引言:灰色预测模型是通过少量的信息、不完全的信息,建立数学模型并做出预测的一种预测方法,相比于其他预测模型,如回归分析,需要的数据信息少,运算方便,建模精度高,在各种领域都有着广泛的应用,是处理小样本预测问题的有效工具
举个栗子,现在有一组数据序列:
那么问题来了,你能对之后未知的数据进行一个预测吗?
带着你的疑问,我们一起进入灰色系统。推导过程可能有点枯燥乏味,但希望大家能看到最后。不想看推导过程的,文末也会附上代码,可直接修改使用。
首先,我们先对数据进行一个累加求和的操作:
可得到一个全新的序列:
设满足一阶微分方程:(其中a是常数,u是发展灰数)
当时,
,此时微分方程的解为:
(把t替换成了k+1)
对于这个结果,很明显,利用最小二乘法求出a和u就可以对未知的数据进行预测了。由于处理的数据是一维离散数据,可以用差分表示微分,因此可以列出一组方程:
用矩阵的形式可以写成:
由于涉及到累加列
的两个时刻的值,因此,
取前后两个时刻的平均值代替更为合理
最终的矩阵形式可以写成:
为了方便求解,可以把U写成:
至此,模型算是求解完毕,但还剩下一个比较重要的工作,那就是最后的结果检验!
精度检验:
(1)残差检验:
残差:
相对残差:
(2)后验差检验:
的均值:
的方差:
残差的均值:
残差的方差:
后验差比值:,小概率误差:
(3)预测精度等级参照表:
预测精度等级 | P | C |
好 | ![]() | ![]() |
合格 | ![]() | ![]() |
勉强 | ![]() | ![]() |
不合格 | ![]() | ![]() |
接下来是算法的实现(此处使用MATLAB实现),预测第6个和第7个数:
%灰色预测模型
clear all
clc
%数据累加
y1 = input('请输入数据:');%y1为原始数据
n = length(y1);
y2 = ones(n,1);%y2用来放置累加数据
y2(1) = y1(1);
%累加操作
for i = 2:n
y2(i) = y2(i-1) + y1(i);
end
%建立矩阵B
B = ones(n-1,2);
for i = 1:n-1
B(i,1) = -(y2(i) + y2(i+1))/2;
B(i,2) = 1;
end
%求逆矩阵
BT = B';
%建立矩阵y
for i = 1:n-1
y(i) = y1(i+1);
end
y = y';
%求解U矩阵
U = inv(BT*B)*BT*y;
a = U(1);
u = U(2);
%利用求解出来的微分方程,预测未知数据
t_test = input('输入预测的个数:');
k = 1:t_test+n;
y3(k+1) = (y2(1)-u/a).*exp(-a.*k)+u/a;%根据微分方程预测出来的累加拟合数据
y3(1)=y1(1);
for i = n+t_test:-1:2
y4(i) = y3(i) - y3(i-1);
end
x1 = 1:n;
xs = 1:n+t_test;
ys = [y1(1) y4(2:n+t_test)];
plot(x1,y1,'^r',xs,ys,'*-b')
legend('原始数据','预测数据')
%检验
det = 0;
for i = 2:n
det = det + abs(ys(i)-y1(i));
end
det = det / (n + 1);
X = mean(y1);%原始数据的均值
for i = 1:n
E(i) = y1(i) - ys(i);%残差
end
%计算原始数据的残差
temp1 = 0;
for i = 1:n
temp1 = temp1 + (y1(i) - X)^2;
end
S1 = sqrt(temp1/n);
%计算残差的方差
temp2 = 0;
for i = 1:n
temp2 = temp2 + E(i) - mean(E);
end
S2 = sqrt(temp2/(n-1));
C = S2 / S1
disp(['百分绝对误差为:',num2str(det),'%']);
disp(['预测值为:',num2str(ys(n+1:n+t_test))]);
%%----------------------------以下是输出结果
请输入数据:[1 3 8 10 15]
输入预测的个数:2
C =
1.3160e-09
百分绝对误差为:0.47793%
预测值为:22.7307 34.2451
从图中可以看到的,预测的数据还是比较好的:
灰色系统对于小数据样本预测有非常好的效果,本文推导的是一阶一元灰色模型,希望以上内容对你能有所帮助,感想观看!