灰色预测模型
灰色预测模型
介绍
灰色预测模型(Gray Forecast Model)是通过少量的、不完全的信息,建立数学模型并做出预测的一种预测方法。是处理小样本(4个就可以)预测问题的有效工具,而对于小样本预测问题回归和神经网络的效果都不太理想。
灰色系统理论认为,尽管客观表象复杂,但总是有整体功能的,因此必然蕴含某种内在规律。关键在于如何选择适当的方式去挖掘和利用它。灰色系统时通过对原始数据的整理来寻求其变化规律的,这是一种就数据寻求数据的现实规律的途径,也就是灰色序列的生产。一切灰色序列都能通过某种生成弱化其随机性,显现其规律性。数据生成的常用方式有累加生成、累减生成和加权累加生成。常用的是累加生成。
建模
原始数据为\(x^0 = (x^0(1),x^0(2),\dots \dots,x^0(n))\) ### 累加生成
\[ x^1(n) = x^0(1) + x^0(2) + \dots \dots + x^0(n) \]
加权临值生成
\[ z^1(n) = \alpha x^1(n) + (1-\alpha)x^1(n-1) \]
由此得到的数列称为邻值生成数,权\(\alpha\)也称为生成系数。 特别地,当生成系数\(\alpha=0.5\)时,则称该数列为均值生成数,也称为等权邻值生成数。
灰色模型GM(1,1)
GM代表grey model(灰色模型),GM(1,1)是一阶微分方程模型。
1.数据检验
数据要先进行准指数规律检验,看看能不能进行灰色预测建模,检验不通过的数据无法进行建模。 首先计算级比
\[ \lambda(k) = \frac{x^0(k-1)}{x^0(k)}, k = 2,3,\dots,n \]
如果所有的级比都落在可容覆盖区间 \(X=(e^{\frac{-2}{n+1}}, e^{\frac{2}{n+1}})\)内,则数列\(x^{(0)}\)可以建立GM(1,1)模型进行灰色预测。否则就需要对数据做适当的变换处理,如平移等。
2.构建灰色模型
定义灰微分方程:
\[ x^0(k) = -az^1(k) + b \]
其中-a为发展系数,b为灰作用度。 可以近似的看成线性回归方程\(y = kx+b\),从而求出a和b 先矩阵化。
\[ u = (a,b)^T , Y = \begin{bmatrix} x^0(2)\\\\ x^0(3)\\\\ \vdots \\\\ x^0(n) \end{bmatrix}, B = \begin{bmatrix} -z^1(2) & 1 \\\\ -z^1(3) & 1 \\\\ \vdots & \vdots \\\\ -z^1(n) & 1 \end{bmatrix} \]
用最小二乘法的到u的估计值即a,b的估计值
\[ \hat{u} = (B^TB)^{-1}B^TY \]
即正规方程。具体的推导看下图
3.预测
相应的白化模型为
\[ \frac{dx^1(t)}{dt} = -\hat{a}x^1(t) + \hat{b} \]
通过高数中学的微分方程的求解可以得到
\[ \hat{x}^1(t) = \left(x^0(1) - \frac{\hat{b}}{\hat{a}} \right)e^{-\hat{a}(t-1)} + \frac{\hat{b}}{\hat{a}} \]
由\(x^0\)与\(x^1\)的关系可以得到
\[ \hat{x}^0(m+1) = (1-e^{\hat{a}})\left(x^0(1)-\frac{\hat{b}}{\hat{a}} \right)e^{-\hat{a}m},其中m=1,2,\dots,n-1 \]
这样就可以进行预测。
4.检验
(1)残差检验 相对残差:\(\epsilon_r(k)=\frac{\mid x^0(k) - \hat{x}^0(k) \mid}{x^0(k)}\) 平均相对残差:\(\bar{\epsilon_r} = \frac{1}{n-1}\sum_{k=2}^n \mid \epsilon_r(k) \mid\) \(\bar{\epsilon_r}\)越小,说明拟合效果越好。
(2)后验差检验法 计算残差\(e(k) = x^0(k) - \hat{x}^0(k)\) 计算原始序列\(x^0\)的方差和残差e的方差
\[ S_1 = \frac{1}{n} \sum_{k=1}^n(x^0(k) - \bar{x})^2 \\\\ S_2 = \frac{1}{n} \sum_{k=1}^n(e(k)-\bar{e})^2 \]
观察后验差比 \(C = \frac{S_2}{S_1}\) 然后通过查表观察效果。
代码
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from itertools import accumulate
= np.array([71.1, 72.4, 72.4, 72.1, 71.4, 72, 71.6])
data = len(data)
lens
# 数据检验
## 计算级比
= []
lambds for i in range(1, lens):
-1]/data[i])
lambds.append(data[i## 计算区间
= np.e**(-2/(lens+1))
X_min = np.e**(2/(lens+1))
X_max ## 检验
= True
is_ok for lambd in lambds:
if (lambd < X_min or lambd > X_max):
= False
is_ok if (is_ok == False):
print('该数据未通过检验')
else:
print('该数据通过检验')
# 构建灰色模型GM(1,1)
## 累加数列
= list(accumulate(data))
data_1 ## 灰导数及临值生成数列
= []
ds = []
zs for i in range(1, lens):
ds.append(data[i])-1/2*(data_1[i-1]+data_1[i]))
zs.append(## 求a、b
= np.array(zs).reshape(lens-1,1)
B = np.ones(lens-1)
one = np.c_[B, one] # 加上一列1
B = np.array(ds).reshape(lens-1,1)
Y = np.dot(np.dot(np.linalg.inv(np.dot(B.T, B)), B.T), Y) # 正规方程
a, b print('a='+str(a))
print('b='+str(b))
# 预测
def func(k):
= b/a
c return (data[0]-c)*(np.e**(-a*k))+c
= [] # 累加预测值
data_1_hat = [] # 原始预测值
data_0_hat 0))
data_1_hat.append(func(0])
data_0_hat.append(data_1_hat[for i in range(1, lens+5): # 多预测5次
data_1_hat.append(func(i))-data_1_hat[i-1])
data_0_hat.append(data_1_hat[i]print('预测值为:')
for i in data_0_hat:
print(i)
# 模型检验
## 预测结果方差
= np.array(data_0_hat[0:7]).T
data_h = data_h.sum()
sum_h = sum_h/lens
mean_h = np.sum((data_h-mean_h)**2)/lens
S1 ## 残差方差
= data - data_h
e = e.sum()
sum_e = sum_e/lens
mean_e = np.sum((e-mean_e)**2)/lens
S2 ## 后验差比
= S2/S1
C ## 结果
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级,效果不合格')
# 画图
=(9, 4), dpi=100)
plt.figure(figsize= np.linspace(1, 7, 7)
x1 = np.linspace(1, 12, 12)
x2 121)
plt.subplot('x^0')
plt.title('r--', marker='*')
plt.plot(x2, data_0_hat, ='^')
plt.scatter(x1, data, marker122)
plt.subplot('x^1')
plt.title('r--', marker='*')
plt.plot(x2, data_1_hat, ='^')
plt.scatter(x1, data_1, marker plt.show()