数学建模系列--预测模型(二)---灰色预测模型

正如前文所述,目前我们学习预测模型的第二类:灰色预测模型。

在控制领域,有一种方法将系统可以笼统的分为三类:
黑箱、白箱、灰箱。

其中黑箱是完全不可观的,因此只能通过大量的输入、输出数据进行建模,找到合理推算后的系统模型。从原理上看,上一期所讲的神经网络模型也在其中,属于通过大量输入输出得到我们的系统辨识。

**白箱:**系统完全可观,可以直接通过过数学模型来应用求解。

**灰箱:**系统部分可观,只能用数学方法将黑色的部分分割出来,通过部分数据推测该不可观部分的数学模型、

但是当下关于灰色控制有了新的思路,当遇到数据较少的情况,无法通过暴力求解黑箱的时候,可以通过部分数据,挖掘其内因。

灰色预测模型:
原文链接:https://blog.csdn.net/qq_39798423/article/details/89283000
灰色系统理论认为,尽管客观表象复杂,但总是有整体功能的,因此必然蕴含某种内在规律。关键在于如何选择适当的方式去挖掘和利用它。因此,灰色序列的生产就是第一步。一切灰色序列都能通过某种生成弱化其随机性,显现其规律性。数据生成的常用方式有累加生成累减生成加权累加生成

生成原处序列:x_0=(x_0(1),x_0(2),…)

1.累加过程:
x_1(1)=x_0(1);
x_1(2)=x_0(1)+x_0(2);

x_1(n)=x_0(1)+…+x_0(n);

2.加权临值生成:
x_1(n)=ax_0(n)+(1-a)x_0(n-1);

实操的步骤:
1.数据检验

使用GM(1,1)建模需要对数据进行检验,首先计算数列的级比,如果所有的级比都落在可容覆盖区间内,则数列x ( 0 )可以建立GM(1,1)模型进行灰色预测。否则就需要对数据做适当的变换处理,如平移等。

2.构建灰色模型
d(k)=x_1(k)-x_1(k-1)=x_0(k)
z(k)=ax_1(k)+(1-a)x_1(k-1)
d(k)+az(k)=b
列矩阵
u=[a;b]
Y=[d(k);d(k-1);…]
B=[-z(k), 1;…]
解Y=Bu,求出a,b(当然a可以设为1/2,便于后期计算)

3.预测
得出白化后的模型:
x(t)=(x_0(1)-b/a)e^-a(t-1)+b/a;
即可测得任意一跳的预测值。

4.检验
灰色模型的精度检验一般有三种方法灰色模型的精度检验一般有三种方法,相对误差大小检验法,关联度检验法和后验差检验法。常用的为后验差检验法。
1.将预测得到的x_1(k)通过累减法得到x_0(k)
2.计算残差
3.将残差平方和与原序列平方和对比
4.S1/S2,查表判定

1 级(好) C<=0.35
2 级(合格) C<=0.5&c>0.35
3 级(勉强) C<=0.65&c>0.5
4 级(不合格) C>0.65
如此,灰色预测结束另外。

python代码:

# 灰色模型预测

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

dir = 'C:/Users/Administrator/Desktop/'

data = pd.read_excel(dir+'test.xls', sheetname='Sheet1')
data = np.array(data['db'])
lens = len(data)  # 数据量

# 数据检验
## 计算级比
lambds = []
for i in range(1, lens):
    lambds.append(data[i-1]/data[i])
## 计算区间
X_min = np.e**(-2/(lens+1))
X_max = np.e**(2/(lens+1))
## 检验
is_ok = True
for lambd in lambds:
    if (lambd < X_min or lambd > X_max):
        is_ok = False
if (is_ok == False):
    print('该数据未通过检验')
else:
    print('该数据通过检验')

# 构建灰色模型GM(1,1)
## 累加数列
data_1 = []
data_1.append(data[0])
for i in range(1, lens):
    data_1.append(data_1[i-1]+data[i])
## 灰导数及临值生成数列
ds = []
zs = []
for i in range(1, lens):
    ds.append(data[i])
    zs.append(-1/2*(data_1[i-1]+data_1[i]))
## 求a、b
B = np.array(zs).reshape(lens-1,1)
one = np.ones(lens-1)
B = np.c_[B, one]  # 加上一列1
Y = np.array(ds).reshape(lens-1,1)
a, b = np.dot(np.dot(np.linalg.inv(np.dot(B.T, B)), B.T), Y)
print('a='+str(a))
print('b='+str(b))

# 预测
def func(k):
    c = b/a
    return (data[0]-c)*(np.e**(-a*k))+c
data_1_hat = []  # 累加预测值
data_0_hat = []  # 原始预测值
data_1_hat.append(func(0))
data_0_hat.append(data_1_hat[0])
for i in range(1, lens+5):  # 多预测5次
    data_1_hat.append(func(i))
    data_0_hat.append(data_1_hat[i]-data_1_hat[i-1])
print('预测值为:')
for i in data_0_hat:
    print(i)

# 模型检验
## 预测结果方差
data_h = np.array(data_0_hat[0:7]).T
sum_h = data_h.sum()
mean_h = sum_h/lens
S1 = np.sum((data_h-mean_h)**2)/lens
## 残差方差
e = data - data_h
sum_e = e.sum()
mean_e = sum_e/lens
S2 = np.sum((e-mean_e)**2)/lens
## 后验差比
C = S2/S1
## 结果
if (C <= 0.35):
    print('1级,效果好')
elif (C <= 0.5 and C >= 0.35):
    print('2级,效果合格')
elif (C <= 0.65 and C >= 0.5):
    print('3级,效果勉强')
else:
    print('4级,效果不合格')

# 画图
plt.figure(figsize=(9, 4), dpi=100)
x1 = np.linspace(1, 7, 7)
x2 = np.linspace(1, 12, 12)
plt.subplot(121)
plt.title('x^0')
plt.plot(x2, data_0_hat, 'r--', marker='*')
plt.scatter(x1, data, marker='^')
plt.subplot(122)
plt.title('x^1')
plt.plot(x2, data_1_hat, 'r--', marker='*')
plt.scatter(x1, data_1, marker='^')
plt.show()
————————————————

你可能感兴趣的:(数学建模系列+算法系列,python,数学建模,算法)