4行关键代码实现灰色模型GM(1, 1)

文章目录

  • 4行关键代码实现灰色模型GM(1, 1)
    • 1、灰色模型GM(1, 1)
    • 2、重新梳理计算步骤(重点)
    • 3、MATLAB代码手把手实现(以下高能)
    • 4、福利完整代码:
    • 5、进一步讨论(核能继续)
    • 6、小结及后记

1、灰色模型GM(1, 1)

先抄书(嫌烦可略过,建议略过):

灰色GM(1, 1)模型:
x(0)(k)+az(1)(k)=bx^{(0)}(k)+az^{(1)}(k)=b x(0)(k)+az(1)(k)=b

其白化方程通常写为:
dx(1)(t)dt+ax(1)(t)=b\frac{dx^{(1)}(t)}{dt}+ax^{(1)}(t)=b dtdx(1)(t)​+ax(1)(t)=b
这里z(1)(k)z^{(1)}(k)z(1)(k) 在邓和刘的书中通常称为紧邻均值序列,有时也称为背景值,它的公式为:
z(1)(k)=12(x(1)(k)+x(1)(k−1))z^{(1)}(k) = \frac{1}{2}\left( x^{(1)}(k) + x^{(1)}(k-1)\right) z(1)(k)=21​(x(1)(k)+x(1)(k−1))
这里 x(1)(k)x^{(1)}(k)x(1)(k) 即是原始数据的累加值,表示为
x(1)(k)=∑j=1kx(0)(j)x^{(1)}(k) = \sum^k_{j=1}x^{(0)}(j) x(1)(k)=j=1∑k​x(0)(j)
参数估计式:
(a^b^)=(BTB)−1BTY\begin{pmatrix} \hat{a}\\\hat{b} \end{pmatrix} =\left(B^TB\right)^{-1}B^TY (a^b^​)=(BTB)−1BTY
其中:
B=(−z(1)(2)1−z(1)(3)1⋮⋮−z(1)(n)1),Y=(x(1)(2)x(1)(3)⋮x(1)(n))B = \begin{pmatrix} -z^{(1)}(2) \quad 1 \\ -z^{(1)}(3) \quad 1 \\ \vdots \quad \vdots\\-z^{(1)}(n) \quad 1 \end{pmatrix} , Y = \begin{pmatrix} x^{(1)}(2) \\ x^{(1)}(3) \\ \vdots \\x^{(1)}(n) \end{pmatrix} B=⎝⎜⎜⎜⎛​−z(1)(2)1−z(1)(3)1⋮⋮−z(1)(n)1​⎠⎟⎟⎟⎞​,Y=⎝⎜⎜⎜⎛​x(1)(2)x(1)(3)⋮x(1)(n)​⎠⎟⎟⎟⎞​
离散响应式(通过求解白化方程得到,取初值为x^(1)(1)=x(1)(1)=x(0)(1)\hat{x}^{(1)}(1)=x^{(1)}(1)=x^{(0)}(1)x^(1)(1)=x(1)(1)=x(0)(1)):
x^(1)(k)=(x(0)(1)−a^b^)e−a^(k−1)+a^b^\hat{x}^{(1)}(k)= \left(x^{(0)}(1) -\frac{\hat{a}}{\hat{b}} \right)e^{-\hat{a}(k-1)}+\frac{\hat{a}}{\hat{b}} x^(1)(k)=(x(0)(1)−b^a^​)e−a^(k−1)+b^a^​
最后计算还原式:
x^(0)(k)=x^(1)(k)−x^(1)(k−1)\hat{x}^{(0)}(k)=\hat{x}^{(1)}(k)-\hat{x}^{(1)}(k-1) x^(0)(k)=x^(1)(k)−x^(1)(k−1)

2、重新梳理计算步骤(重点)

许多人通常在看书的时候就会觉得,一会又是矩阵,一会又是方程,感觉有点麻烦。在实操过程中稍遇到些问题,一想直背后太多知识点就放弃,十分可惜。

下面,我们单纯以实现这个模型的计算为目的,重新梳理其整个建模步骤。

数据准备:假设我们有原始数据
[x(0)(1),x(0)(2),…,x(0)(n),…,x(0)(n+p)]\left[ x^{(0)}(1),x^{(0)}(2),\dots,x^{(0)}(n),\dots,x^{(0)}(n+p)\right] [x(0)(1),x(0)(2),…,x(0)(n),…,x(0)(n+p)]
第一步:计算其累加值:
x(1)(k)=∑j=1kx(0)(j)x^{(1)}(k) = \sum_{j=1}^{k}x^{(0)}(j) x(1)(k)=j=1∑k​x(0)(j)
第二步: 再算背景值:
z(1)(k)=12(x(1)(k)+x(1)(k−1))z^{(1)}(k) = \frac{1}{2}\left( x^{(1)}(k) + x^{(1)}(k-1)\right) z(1)(k)=21​(x(1)(k)+x(1)(k−1))
第三步:构造矩阵BBB (在具体实操中,我们并不需要专门构造矩阵YYY):
B=(−z(1)(2)1−z(1)(3)1⋮⋮−z(1)(n)1)B = \begin{pmatrix} -z^{(1)}(2) & 1 \\ -z^{(1)}(3) &1 \\ \vdots & \vdots \\-z^{(1)}(n) &1 \end{pmatrix} B=⎝⎜⎜⎜⎛​−z(1)(2)−z(1)(3)⋮−z(1)(n)​11⋮1​⎠⎟⎟⎟⎞​
第四步:算 矩阵的转置、 乘积、求逆再算矩阵乘向量(后面马上就来具体实操,并不难):
(a^b^)=(BTB)−1BTY\begin{pmatrix} \hat{a}\\\hat{b} \end{pmatrix} =\left(B^TB\right)^{-1}B^TY (a^b^​)=(BTB)−1BTY
第五步:算时间响应式和还原值(取 k=1,2,…,n,…,n+pk=1,2,\dots,n,\dots,n+pk=1,2,…,n,…,n+p):
x^(1)(k)=(x(0)(1)−a^b^)e−a^(k−1)+a^b^\hat{x}^{(1)}(k)= \left(x^{(0)}(1) -\frac{\hat{a}}{\hat{b}} \right)e^{-\hat{a}(k-1)}+\frac{\hat{a}}{\hat{b}} x^(1)(k)=(x(0)(1)−b^a^​)e−a^(k−1)+b^a^​

x^(0)(k)=x^(1)(k)−x^(1)(k−1)\hat{x}^{(0)}(k)=\hat{x}^{(1)}(k)-\hat{x}^{(1)}(k-1) x^(0)(k)=x^(1)(k)−x^(1)(k−1)

3、MATLAB代码手把手实现(以下高能)

在上一节里我们将模型的主要步骤分成了5个步骤,实际上真正的计算过程就是按这个顺序逐步执行的。接下来,我们就来一步步写出各步的代码。

在以下内容中,你将看到熟悉MATLAB编程特性的情况下,实现这一模型是何其简单。

数据准备:

x0 = exp(0.1*[1:10])' + rand(10,1);

注: 这里是生成了一组10*1的矩阵,以指数函数为真实值,加入0到1之间的噪声。这里我们采用列向量方便后面计算。

另外,我们设n=8,p=2n=8,p=2n=8,p=2

n = 8;
p = 2;

第一步:计算其累加值:

x1 = cumsum(x0);

注: cumsum()是MATLAB内置函数,直接求出某一组列向量的累加值,返回一个和原数据同样的矩阵。那么也就是说,这段代码直接实现了累加的所有计算,不需要任何循环

第二步: 计算背景值:

z1 = 0.5 * ( x1(1:n-1) + x1(2:n) );

注: 如果上述操作是小高能,那么这一步就是高能操作。即是利用MATLAB中对矩阵元素的取出方式,简单实现了背景值的计算。同样,不需要任何循环

第三步: 构造矩阵:

B = [ -z1 ones(n-1,1)];
Y = x0(2:n);

注:如果上面是高能,那么这里就算是小超高能。利用MATLAB分块矩阵的记法,轻松实现两个矩阵的构造,一句循环都不需要,同时代码简洁易懂。

第四步:计算矩阵乘积、求逆、、、、(不想打了,直接看代码):

val_a_b = pinv(B)*Y;
a = val_a_b(1);
b = val_a_b(2);

注: 不明真相的群众需要补充一些知识,即广义逆矩阵(也称为伪逆矩阵)。见百科:

https://zh.wikipedia.org/wiki/%E5%B9%BF%E4%B9%89%E9%80%86%E9%98%B5zh.wikipedia.org

这里: 函数pinv()即是矩阵广义逆的函数,当矩阵行大于列时,这个函数计算出的值即是:
(BTB)−1BT\left(B^TB\right)^{-1}B^T (BTB)−1BT
所以我们所看到的这一大坨矩阵计算,一个函数就可以搞定。

第五步: 计算响应式和还原式

这里你以为我要用循环了?(图样图桑破!)看代码:

k = [1:10]';
hat_x1 = ( x0(1) - b/a ) * exp(-a*k) + b/a;
hat_x0 = [ x0(1);hat_x1(2:end)-hat_x1(1:end-1) ];

注:这里属于核能

这段代码有几个技巧需要说明:

(1) 在计算响应式的时候,我们预先知道需要算出 k=1,2,...,10k = 1, 2,...,10k=1,2,...,10 的值,通常的思路是写一个FOR循环让kkk取遍1到10. 不过MATLAB提供了十

分灵活的矩阵计算方式。用第二行代码算出的值直接就是响应式所有值构成的列向量,因此,不需要循环

(2) 在计算还原式的时候,采用了2个技巧。第1个仍然是分块矩阵的运用,这一点不用多说。第2个技巧是MATLAB对下标的操作。这里 hat_x1(2:end) 指的是这一向量中第2个到最后一个元素,同理hat_x1(1:end-1)即是第1到倒数第二个元素。这两组相减,刚好每个元素的值就是x^(0)(k)=x^(1)(k)−x^(1)(k−1)\hat{x}^{(0)}(k)=\hat{x}^{(1)}(k)-\hat{x}^{(1)}(k-1)x^(0)(k)=x^(1)(k)−x^(1)(k−1) ,所以这里,我们仍然不需要任何循环

4、福利完整代码:

x0 = exp(0.1*[1:10])' + rand(10,1);
n = 8;
p = 2;
x1 = cumsum(x0);
z1 = 0.5 * ( x1(1:n-1) + x1(2:n) );
B = [ -z1 ones(n-1,1)];
Y = x0(2:n);
val_a_b = pinv(B)*Y;
a = val_a_b(1);
b = val_a_b(2);
k = [1:10]';
hat_x1 = ( x0(1) - b/a ) * exp(-a*k) + b/a;
hat_x0 = [ x0(1);hat_x1(2:end)-hat_x1(1:end-1) ];

至于模型的评估,计算误差这些问题,自己简单写一写即可。

提示:仍然全部使用MATLAB自带函数,如mean(),abs() 以及向量的表达式。

5、进一步讨论(核能继续)

上述代码其实仍有简化的空间,有几个地方其实是完全没必要的。

(1)矩阵B和Y并没有必要显式构造出来,同时背景值也只用来做了一下矩阵构造,所以,这三行可以不要。

(2)上述三行代码只是用来算参数,因此把这三行合并到这一行来即可。

即:

z1 = 0.5 * ( x1(1:n-1) + x1(2:n) );
B = [ -z1 ones(n-1,1)];
Y = x0(2:n);
val_a_b = pinv(B)*Y;

缩减到一行:

val_a_b = pinv([ -0.5 * ( x1(1:n-1) + x1(2:n) ) ones(n-1,1)] )*x0(2:n);

(3)单独用变量a,b,k来存储一些值,只是为了让代码更好懂,其实可以全删了。直接用val_a_b(1), val_a_b(2) 分别代替a,b; 后面的k直接写成[1:n+p]'即可,这里就不拆了。

直接上最终简洁版:

x0 = exp(0.1*[1:10])' + rand(10,1);
n = 8;
p = 2;
x1 = cumsum(x0);
val_a_b = pinv([ -0.5 * ( x1(1:n-1) + x1(2:n) ) ones(n-1,1)] )*x0(2:n);
hat_x1 = ( x0(1) - val_a_b(2)/val_a_b(1) ) * exp(-val_a_b(1)*[1:n+p]') + val_a_b(2)/val_a_b(1);
hat_x0 = [ x0(1);hat_x1(2:end)-hat_x1(1:end-1) ];

仔细看看,前3行是必要的数据准备和参数设置。真正的计算过程4行代码即可

6、小结及后记

读完本文,如果认真读的话,可能你花得不止10分钟。

读完本文,相信你已经能学会灰色模型的实现,换上你自己的数据试一试,或许会有更多发现。

通过本文,相信你已经能体会到一些MATLAB编程的乐趣,尤其是亲自动手实现过这个模型或者类似模型的朋友。

更多关于灰色预测模型的最新成果,可以参考以下链接:

https://www.researchgate.net/profile/Sifeng_Liuwww.researchgate.netBo Zeng | Chongqing Technology and Business University, Chongqingwww.researchgate.net

https://www.researchgate.net/profile/Xin_Ma58

更多代码也可在MATHWORKS社区中找到:

ng | Chongqing Technology and Business University, Chongqingwww.researchgate.net[外链图片转存中…(img-8ZbaeKRB-1583045245538)]](https://link.zhihu.com/?target=https%3A//www.researchgate.net/profile/Bo_Zeng15)

更多代码也可在MATHWORKS社区中找到:

The kernel-based grey system model - File Exchange - MATLAB Centralww2.mathworks.cn

4行关键代码实现灰色模型GM(1, 1)相关推荐

  1. R语言用灰色模型 GM (1,1)、神经网络预测房价数据和可视化

    全文链接:http://tecdat.cn/?p=31938 以苏州商品房房价为研究对象,帮助客户建立了灰色预测模型 GM (1,1). BP神经网络房价预测模型,利用R语言分别实现了 GM (1,1 ...

  2. 知然算法【2】灰色模型GM(1,1)

    知然算法[2]灰色模型GM(1,1) 0.算法适用 适用于短期预测: 样本条数大于4即可建模: 不适用于较大震荡性数据: 1.符号说明 原始数据序列: x 0 ( k ) , k = 1 , 2 ,

  3. 9灰色预测- 灰色模型GM(1,N)

    灰色预测- 灰色模型GM(1,N)    上篇博客说到了 G M ( 1 , 1 ) GM(1,1) GM(1,1),即只有单个变量,且模型是1阶的,此次我们来说说 G M ( 1 , N ) GM( ...

  4. 灰色模型 java代码_灰色模型的简单Java实现

    前几天在以前的遗留代码中发现一个问题,就是我生成的一个数据的走势曲线的预测值(用于灰色时间序列预测)总是和老代码里的不一致,具体来说就是:遗留代码里面的预测值的斜率总是为零,相比之下我生成的就比较合理 ...

  5. 19行关键代码,带你轻松入门PaddlePaddle单机训练

    刚接触深度学习框架的同学可能会说 新入手一个框架是不是会很难? NO,NO,NO   PaddlePaddle的宗旨就是"easy to use!" PaddlePaddle是百度 ...

  6. python灰色模型代码_python 实现 灰色预测 GM(1,1)模型 灰色系统 预测 灰色预测公式推导...

    来源公式推导连接 关键词:灰色预测 python 实现 灰色预测 GM(1,1)模型 灰色系统 预测 灰色预测公式推导 一.前言 本文的目的是用Python和类对灰色预测进行封装 二.原理简述 1.灰 ...

  7. 用python建立gm(1、1)模型_灰色预测模型GM(1,1)的全面讲解及python实现

    1. 灰色预测的概念 (1)灰色系统.白色系统和黑色系统 白色系统是指一个系统的内部特征是完全已知的,既系统信息是完全充分的. 黑色系统是一个系统的内部信息对外界来说是一无所知的,只能通过它与外界的联 ...

  8. python灰色预测_python 实现 灰色预测 GM(1,1)模型 灰色系统 预测 灰色预测公式推导...

    关键词:灰色预测 python 实现 灰色预测 GM(1,1)模型 灰色系统 预测 灰色预测公式推导 一.前言 本文的目的是用Python和类对灰色预测进行封装 二.原理简述 1.灰色预测概述 灰色预 ...

  9. 时间序列预测之二:灰色模型

    目录 1.简介 (1)常见系统分类 (2)灰色预测法 2. 灰色生成数列 (1)累加生成(AGO) (2)累减生成(IAGO)​ (3)加权邻值生成​ 3. 灰色模型GM(1,1) 4. 检验预测值 ...

最新文章

  1. Linux真随机数的生成
  2. 服务器弱口令修改,Tomcat服务器弱口令漏洞攻击实验
  3. redis学习(四) 登录和cookie缓存
  4. 数据结构 - 队列(图解+源码)
  5. C++PrimerPlus学习——第六章编程练习
  6. jsencrypt加密结果false(网罗答案) - 分析篇
  7. 微软API工作笔记001---API大全查询
  8. 网页编辑器粘贴word格式的处理
  9. 计算机网络(北京理工大学出版社)课后习题答案
  10. python生成随机imei
  11. snort安装使用教程
  12. Python学习笔记—— 面向对象5.异常
  13. 澳洲国立与渥太华计算机科学,山东小伙斩获渥太华电子工程专业及多伦多计算机科学专业录取!...
  14. Selenium基于Python web自动化测试框架 —— PO模型
  15. Wex5 popOver组件的使用
  16. Unity_Shader中级篇_10_Unity Shader入门精要
  17. OpenWrt 编译及batman-adv组件选择(for Netgear WNDR3800)
  18. “圆”来如此——关于圆周率 π 的36 个有趣事实
  19. 编程小白入门在线求助呜呜呜
  20. 痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU启动那些事(4)- Flashloader初体验(blhost)...

热门文章

  1. java领域对象_java的几种对象(po,dto,dao等)
  2. ssh实现基于密钥方式登录系统
  3. 常用数据库语句(更新)
  4. 设计模式:享元(FlyWeight)模式
  5. Xcode7 项目转 Xcode6 时 出现问题
  6. C++ 容器 LIST VECTOR erase
  7. SQL2008 附加数据库提示 5120错误
  8. android7.1增加一个开机自启动的bin应用遇到的权限问题
  9. Android 5.0 SEAndroid下如何获得对一个内核节点的访问权限
  10. Firefox 66 将自带自动屏蔽声音功能