一、引言
大家好,今天是第三天,前两篇博文用到的数学建模方法应用的数学知识还比较少,在这一篇章,需要的数学知识变多了,大致需要一些高等数学中导数部分的知识,大家如果忘了的话记得自己去补哈。好言归正传,今天要讲的到底是什么方法呢,就是那个很出名的“灰色预测模型”啦。好了开讲咯!
二、灰色预测模型
2.1概念
2.1.1 灰色系统、白色系统、黑色系统
在讲灰色预测模型的概念时我想先跟大家介绍三种系统。
- 白色系统:指一个系统的内部特征的完全已知的,即系统信息是完全公开的。
- 黑色系统:与白色系统相反,指一个系统的内部信息对外界来说是一无所知的,只能通过它与外界的联系来加以观测研究。
- 灰色系统:介于白色系统和黑色系统之间,即系统内一部分信息是已知的,但另一部分信息是未知的,系统内各因素间有不确定的关系。
一般我们在生活的过程中,大多遇到的系统是灰色系统。因此,我们就需要利用灰色系统内那部分公开的信息,来建模推测出隐藏的信息。这就是灰色预测模型。
2.1.2 灰色预测法
- 灰色预测法是一种预测灰色系统的预测方法。
目前常用的一些预测方法(如回归分析等),需要较大的样本,对于少样本的情况就会造成比较大的误差,使预测目标失效。而灰色预测模型所需的建模信息少、运算方便、建模精度高,因此在各种预测领域都有着广泛的应用,是处理小样本预测问题的有效工具。
- 灰色预测通过鉴别系统因素之间发展趋势的相异程度,即进行关联分析,并对原始数据进行灰色生成来寻找系统变动的规律,生成有较强规律性的数据序列,然后建立相应的微分方程模型,从而预测事物未来发展趋势的状况。
2.2 关联分析
首先什么是关联分析呢,实际上,关联分析时动态过程发展态势的量化比较分析。所谓发展态势比较,也就是系统各时期有关统计数据的集合关系的比较。
举例来讲,某地区2010-2018年的总收入与养鸡和养猪收入资料如下表格。
2010 | 2011 | 2012 | 2013 | 2014 | 2015 | 2016 | 2017 | 2018 | |
总收入(万元) | 16 | 21 | 22 | 21 | 21 | 20 | 20 | 19 | 25 |
养猪(万元) | 12 | 15 | 14 | 16 | 14 | 16 | 13 | 10 | 15 |
养鸡(万元) | 4 | 6 | 8 | 5 | 7 | 4 | 7 | 9 | 10 |
根据上述表格,可以画出曲线图,如下:
由上图易看出,蓝色曲线 (总收入)与橙色曲线(养猪收入)发展趋势比较接近,而与灰色曲线(养鸡收入)相差较大,因此可以判断,该地区对总收入影响较直接的是养猪业, 而不是养鸡业。
很显然,几何形状越接近,关联程度也就越大。但是,对于一些稍微复杂的问题,如果不容易画出图,那就很难通过直观的手法来分析。这时就需要我们的灰色生成方法了。
2.3 灰色生成
原始数据列中的数据,按某种要求作数据处理,这样的一种方法叫做生成。
灰色系统理论认为,尽管客观表表象复制,但必定蕴含某种内在规律的,关键如何去发现这样的一个规律。灰色生成就是为了从灰色序列中去找出内在的规律,从而能判断事物的发展趋势。
常用的灰色生成法有:累加生成、累减生成和加权累加生成。接下来我们就来以此介绍它们。
(1)累加生成(AGO)
假定原始数列为$x^{(0)} = \left (x^{(0)}(1), x^{(0)}(2), \cdot \cdot \cdot ,x^{(0)}(n) \right )$,令
$x^{(1)}(k) = \sum_{i=1}^{k} x^{(0)}(i) \ , \ k = 1, 2,\cdot \cdot \cdot, n$
$x^{(1)} = \left ( x^{1} (1), x^{1} (2), \cdot \cdot \cdot , x^{1} (n) \right )$
则称$x^{(1)}$为数列$x^{(0)}$的1次累加生成数列。若继续推广,有
$x^{(r)}(k) = \sum_{i =1}^{k} x^{(r-1)}(i) \ , \ k = 1, 2,\cdot \cdot \cdot, n, \ r \geq 1$
$x^{(r)}(k)$称为$x^{(0)}(k)$的r次累加生成数列。
(2)累减生成(IAGO)
假定原始数列为$x^{(1)} = \left (x^{(1)}(1), x^{(1)}(2), \cdot \cdot \cdot ,x^{(1)}(n) \right )$,令
$x^{(0)}(k) = x^{(1)}(k) - x^{(1)}(k-1) \ , \ k = 2, 3,\cdot \cdot \cdot, n$
则称$x^{(0)}$为数列$x^{(1)}$的1次累减生成数列。可以看出,通过累加数列得到的新数列,可以通过累减生成还原出原始数列。
(3)加权邻值生成
假定原始数列为$x^{(1)} = \left (x^{(1)}(1), x^{(1)}(2), \cdot \cdot \cdot ,x^{(1)}(n) \right )$,称任意一对相邻元素$x^{(0)}(k-1), x^{(0)}(k)$互为邻值。对于常数$\alpha \in [0, 1]$, 令
$z^{(0)}(k) = \alpha x^{(0)}(k) + (1 - \alpha)x^{(0)} (k-1), \ k = 2, 3, \cdot \cdot \cdot, n$
由此得到的数列称为邻值生成数,权$\alpha$也称为生成系数。特别地,当生成系数$\alpha = 0.5$,则称该数列为均值生成数,也称为等权邻值生成数。
2.4 灰色模型GM(1,1)
灰色模型是利用离散随机数经过生成变为随机性被显著削弱而且较有规律的生成数,建立起的微分方程形式的模型,这样便于对其变化过程进行研究和描述。
G表示grey(灰色),M表示Model(模型);
首先,定义$x^{(1)}$的灰导数为
$d(k) = x^{(0)}(k) = x^{(1)}(k) - x^{(1)}(k-1)$
令$z^{(1)}$为数列$x^{(1)}$的邻值生成数列,即
$z^{(1)}(k) = \alpha x^{(1)}(k) + (1 - \alpha)x^{(1)} (k-1),$
好的。接下来我们要定义最重要的一个方程了,就是GM(1,1)的灰微分方程模型:
$d(k) + a z^{(1)}(k) = b$ 或 $x^{(0)}(k) + a z^{(1)}(k) = b$
其中,$x^{(0)}(k)$称为灰倒数,$a$称为发展系数,$z^{(1)}(k)$称为白化背景纸,b称为灰作用量。
将$k = 2,3,...,n$代入上式,有
$x^{(0)}(2) + a z^{(1)}(2) = b\\ $
$x^{(0)}(3) + a z^{(1)}(3) = b\\ $
$\cdot \cdot \cdot\\ $
$x^{(0)}(n) + a z^{(1)}(n) = b$
引入矩阵向量记号:
$u = \begin{bmatrix} a\\ b\end{bmatrix}$ $ Y = \begin{bmatrix} x^{(0)}(2)\\ x^{(0)}(3)\\ \cdot \cdot \cdot\\ x^{(0)}(2) \end{bmatrix}$ $ B = \begin{bmatrix} -z^{(1)}(2) & 1\\ -z^{(1)}(3) & 1\\ \cdot \cdot \cdot & \cdot \cdot \cdot\\ -z^{(1)}(n) & 1 \end{bmatrix}$
于是GM(1,1)模型可以表示为
$Y = Bu$
那么现在的问题就是求a和b的值,我们可以用一元线性回归,也就是最小二乘法求它们的估计值为
$u = \begin{bmatrix}a\\ b \end{bmatrix} = (B^{T}B)^{-1}B^{T}Y$
2.5 GM(1,1)的白化型
前面我们定义的模型是在离散的情况下,那么针对连续时间$t$,则之前的$X^{(1)}$视为时间$t$函数,于是灰导数$x^{(0)}(k)$变为连续的导数$\frac{dx^{(1)}(t)}{dt}$,白化背景值$z^{(1)}(k)$对应于导数$x^{(1)}(t)$。于是GM(1,1)的灰微分方程对应的白微分方程为:
$\frac{dx^{(1)}(t)}{dt} + ax^{(1)}(t) = b$
三、GM(1,1)灰色预测的步骤
3.1 数据的检验与处理
为了保证GM(1,1)建模方法的可行性,需要对已知数据做必要的检验处理。
设原始数据列为$x^{(0)} = \left (x^{(0)}(1), x^{(0)}(2), \cdot \cdot \cdot ,x^{(0)}(n) \right )$,计算数列的级比
$\lambda(k) = \frac{x^{(0)}(k-1)}{x^{(0)}(k)},\ k = 2, 3, ..., n$
如果所有的级比都落在可容覆盖区间$X = \left(e^{\frac{-2}{n+1}},e^{\frac{2}{n+1}} \right )$内,则数列$x^{(0)}$可以建立GM(1,1)模型且可以进行灰色预测。否则,对数据做适当的变换处理,如平移变换:
$y^{(0)}(k) = x^{(0)}(k) + c, \ k = 1, 2, \cdot \cdot \cdot, n$
取$c$使得数据列的级比都落在可容覆盖内。
3.2 建立GM(1,1)模型
当$x^{(0)} = \left (x^{(0)}(1), x^{(0)}(2), \cdot \cdot \cdot ,x^{(0)}(n) \right )$满足上面的条件后,我们就可以以它为数据列建立GM(1,1)模型,即根据$Y = Bu$求解出$u = \begin{bmatrix} a\\ b\end{bmatrix}$。相应的白化模型为
$\frac{dx^{(1)}(t)}{dt} + ax^{(1)}(t) = b$
这是一个微分方程,可以求解得到:
$x^{(1)}(t) = \left(x^{(0)}(1) - \frac{b}{a} \right )e^{(-a(t-1))}+ \frac{b}{a}$
于是得到
$\hat{x}^{(1)}(k+1) = \left(x^{(0)}(1) - \frac{b}{a} \right )e^{(-ak)}+ \frac{b}{a},\ k = 1, 2, \cdot \cdot \cdot , n-1$
因此得到预测值为:
$\hat{x}^{(0)}(k) = \hat{x}^{(1)}(k) - \hat{x}^{(1)}(k-1) \ , \ k = 2, 3,\cdot \cdot \cdot, n$
3.3 检测预测值
模型选定后,一定要经过检验才能判定其是否合理,只有通过检验的模型才能用来作预测,灰色模型的精度检验一般有三种方法:相对误差大小检验法、关联度检验法和后验差检验法。下面主要介绍相对误差大小检验法和后验差检验法
3.3.1 相对误差大小检验法
$\varepsilon (k) = \frac{x^{(0)}(k) - \hat{x}^{(0)}(k)}{x^{(0)}(k)}, \ k = 1, 2, \cdot \cdot \cdot, n$
如果对所有的$\left | \varepsilon (k) \right | < 0.1$,则认为到达较高的要求;若对所有的$\left | \varepsilon (k) \right | < 0.2$,则认为打到一般要求。
3.3.2 后验差检验法(方差C检验法)
- 原始数列:$x^{(0)} = \left (x^{(0)}(1), x^{(0)}(2), \cdot \cdot \cdot ,x^{(0)}(n) \right )$
- 建模后算出的数列:$\hat{x}^{(0)} = \left (\hat{x}^{(0)}(1), \hat{x}^{(0)}(2), \cdot \cdot \cdot ,\hat{x}^{(0)}(n) \right )$
- 残差序列为$E = \left (e(1), e(2), \cdot \cdot \cdot ,e(n) \right )$
其中,$e(k) = x^{(0)}(k) - \hat{x}^{(0)}(k), \ k = 1, 2, \cdot \cdot \cdot , n$
记原始序列$x^{(0)}$及残差序列$E$的方差分别为$S_{1}^{2}$和$S_{2}^{2}$,则
$S_{1}^{2} = \frac{1}{n}\sum_{k =1}^{n}\left [ x^{(0)}(k) - \overline{x} \right ]^2$
$S_{2}^{2} = \frac{1}{n}\sum_{k =1}^{n}\left [ e(k) - \overline{e} \right ]^2$
其中,$\overline{x} = \frac{1}{n}\sum_{k =1}^{n}x^{(0)}(k)$,$\overline{e} = \frac{1}{n}\sum_{k =1}^{n}e(k)$
则后验差比为:
$C = \frac {S_{2}}{S_{1}}$
指标$C$是后验差检验的重要指标。指标$C$越小越好。为什么这么说呢?这是因为,$C$越小就表明$S_{1}$大而$S_{2}$越小。
那$S_{1}$大表明什么,它表明原始数据方差大,这也就说明原始数据的离散程度大。
那$S_{2}$小又表明什么呢,它表明残方差小,也就是残差的离散程度小。
因此,$C$小就表明尽管原始数据很离散,但模型所得的计算值与实际值之差并不太离散。这样得到的数据可靠性就越强。这样讲是不是就懂啦。。
下面附一张精度检验等级参照表
模型精度等级 | 均方差比值$C$ |
1级(好) | $C\leq 0.35$ |
2级(合格) | $0.35 < C \leq 0.5$ |
3级(勉强) | $0.5 < C \leq 0.65$ |
4级(不合格) | $0.65 < C$ |
四、GM(1,1)模型的Matlab代码
%%构建GM模型计算出a和b %建立符号变量a(发展系数)和b(灰作用量) syms a b; u = [a b]'; %原始数列X0 X0 = input('请输入数据'); n = length(X0); %对原始数列X做累加得到数列X1 X1 = cumsum(X0); %对数列X1做等权邻值生成Z1 for i = 2: n Z1(i) = (X1(i) + X1(i - 1)) / 2; end Z1(1) = []; %去除掉第一个元素 %构造数据矩阵 B = [-Z1; ones(1, n - 1)]'; Y = [X0]'; Y(1, :) = []; %去除掉第一个元素 %利用u = inv(B'*B)*B'*Y来求解 u = inv(B'*B) * B' * Y; a = u(1, :); b = u(2, :); %%预测后续数据 %p是预测后续的数据量,根据情况可更改 p = 3; %构建预测数列F F = []; F(1) = X0(1); for i = 2: (n + p) F(i) = (X0(1) - b/a) * exp(-a*(i-1)) + b/a; end %对数列F累减还原,得到预测出的数据 G = []; G(1) = X0(1); for i = 2: (n + p) G(i) = F(i) - F(i-1); end disp('预测到的数据为: '); G %%模型检验 H = G(1: n); %计算残差序列 E = X0 - H; %法一:相对残差Q检验 %计算相对误差序列 epsilon = abs(E ./ X0); %计算相对误差Q disp('相对残差Q检验: '); Q = mean(epsilon) %法二:方差比C检验 disp('方差比C检验: '); C = std(E, 1) / std(X0, 1) %小误差概率P检验 S1 = std(X0, 1); tmp = find(abs(E - mean(E)) < 0.6745 * S1); disp('小误差概率P检验:'); P = length(tmp) / n %%绘制曲线图(根据不同的题目以下的代码会有所不同,故不贴出来,大家自己动手写吧)