一文详解Python灰色预测模型实现示例
作者:fanstuck 发布时间:2023-05-11 01:45:21
前言
博主参与过大大小小十次数学建模比赛,也获得了不少建模奖项。对于一些小批量样本数据去做预测或者是评估其规律性的话,比较适合的模型一般都是选择灰色预测模型。该模型解释性强而且易于理解,建模手段也比较简单。在一些不确定是否存在相关标量或者是存在位置特征的时候,用灰色预测模型尤为明显,牵扯太多变量时候可以以量曾量减的方式显现其变化规律,是建模比较好用的算法和思路。但是首先我们要明白该模型的使用场景以及优缺点才能更好的解释建模的效果。故为接下来的美赛,我将把一些常用建模的模型和代码补上。
一、模型理论
灰色预测模型是通过少量的、不完全的信息,建立数学模型做出预测的一种预测方法。是基于客观事物的过去和现在的发展规律,借助于科学的方法对未来的发展趋势和状况进行描述和分析,并形成科学的假设和判断。
我们称信息完全未确定的系统为黑色系统,称信息完全确定的系统为白色系统,灰色系统就是这介于这之间,一部分信息是已知的,另一部分信息是未知的,系统内各因素间有不确定的关系。
不知道大家知不知道白盒测试和黑盒测试,我们可以这样通俗的理解,黑色系统就好比一个黑色的盒子你看不到里面装着几个小球,从里面拿出几个小球或者是章鱼都是未知数。而白色系统就像是透明的盒子,你能很清楚的看到里面是什么你想要拿什么出来拿多少个。而这个灰色系统介于他们之间,盒子是灰色的,只能模糊的看到一些小球,看不到几个或者是有除了小球以外的其他东西。
灰色预测通过鉴别系统因素之间发展趋势的相异程度,即进行关联分析,并对原始数据进行生成处理来寻找系统变动的规律,生成有较强规律性的数据序列,然后建立相应的微分方程模型,从而预测事物未来发展趋势的状况。其用等时距观测到的反映预测对象特征的一系列数量值构造灰色预测模型,预测未来某一时刻的特征量,或达到某一特征量的时间。
特点
用灰色数学处理不确定量,使之量化。
充分利用已知信息寻求系统的运动规律。
灰色系统理论能处理贫信息系统。
二、模型场景
1.预测种类
灰色时间序列预测;即用观察到的反映预测对象特征的时间序列来构造灰色预测模型,预测未来某一时刻的特征量,或达到某一特征量的时间。
畸变预测;即通过灰色模型预测异常值出现的时刻,预测异常值什么时候出现在特定时区内。
系统预测;通过对系统行为特征指标建立一组相互关联的灰色预测模型,预测系统中众多变量间的相互协调关系的变化。
拓扑预测;将原始数据作曲线,在曲线上按定值寻找该定值发生的所有时点,并以该定值为框架构成时点序列,然后建立模型预测该定值所发生的时点。
2.适用条件
灰色预测模型可针对数量非常少(比如仅4个),数据完整性和可靠性较低的数据序列进行有效预测,其利用微分方程来充分挖掘数据的本质,建模所需信息少,精度较高,运算简便,易于检验,也不用考虑分布规律或变化趋势等。但灰色预测模型一般只适用于短期预测,只适合指数增长的预测,比如人口数量,航班数量,用水量预测,工业产值预测等。
三、建模流程
总体建模流程可以参考:
1.级比校验
trong>数据累加和微分方程构造
3.系数求解
数据向量Y:
4.残差检验与级比偏差检验
四、Python实例实现
我们通过得到的周数拥堵车辆数据进行测试:
import numpy as np
import pandas as pd
from decimal import *
import matplotlib.pyplot as plt
def Grade_ratio_test(X0):
lambds = [X0[i - 1] / X0[i] for i in range(1, len(X0))]
X_min = np.e ** (-2 / (len(X0) + 1))
X_max = np.e ** (2 / (len(X0) + 1))
for lambd in lambds:
if lambd < X_min or lambd > X_max:
print('该数据未通过级比检验')
return False
print('该数据通过级比检验')
return True
def model_train(X0_train):
#AGO生成序列X1
X1 = X0_train.cumsum()
Z= (np.array([-0.5 * (X1[k - 1] + X1[k]) for k in range(1, len(X1))])).reshape(len(X1) - 1, 1)
# 数据矩阵A、B
A = (X0_train[1:]).reshape(len(Z), 1)
B = np.hstack((Z, np.ones(len(Z)).reshape(len(Z), 1)))
# 求灰参数
a, u = np.linalg.inv(np.matmul(B.T, B)).dot(B.T).dot(A)
u = Decimal(u[0])
a = Decimal(a[0])
print("灰参数a:", a, ",灰参数u:", u)
return u,a
def model_predict(u,a,k,X0):
predict_function =lambda k: (Decimal(X0[0]) - u / a) * np.exp(-a * k) + u / a
X1_hat = [float(predict_function(k)) for k in range(k)]
X0_hat = np.diff(X1_hat)
X0_hat = np.hstack((X1_hat[0], X0_hat))
return X0_hat
'''
根据后验差比及小误差概率判断预测结果
:param X0_hat: 预测结果
:return:
'''
def result_evaluate(X0_hat,X0):
S1 = np.std(X0, ddof=1) # 原始数据样本标准差
S2 = np.std(X0 - X0_hat, ddof=1) # 残差数据样本标准差
C = S2 / S1 # 后验差比
Pe = np.mean(X0 - X0_hat)
temp = np.abs((X0 - X0_hat - Pe)) < 0.6745 * S1
p = np.count_nonzero(temp) / len(X0) # 计算小误差概率
print("原数据样本标准差:", S1)
print("残差样本标准差:", S2)
print("后验差比:", C)
print("小误差概率p:", p)
if __name__ == '__main__':
plt.rcParams['font.sans-serif'] = ['SimHei'] # 步骤一(替换sans-serif字体)
plt.rcParams['axes.unicode_minus'] = False # 步骤二(解决坐标轴负数的负号显示问题)
# 原始数据X
data = pd.read_excel('./siwei_day_traffic.xlsx')
X=data[data['week_day']=='周五'].jam_num[:5].astype(float).values
print(X)
# 训练集
X_train = X[:int(len(X) * 0.7)]
# 测试集
X_test = X[int(len(X) * 0.7):]
Grade_ratio_test(X_train) # 判断模型可行性
a,u=model_train(X_train) # 训练
Y_pred = model_predict(a,u,len(X),X) # 预测
Y_train_pred = Y_pred[:len(X_train)]
Y_test_pred = Y_pred[len(X_train):]
score_test = result_evaluate(Y_test_pred, X_test) # 评估
# 可视化
plt.grid()
plt.plot(np.arange(len(X_train)), X_train, '->')
plt.plot(np.arange(len(X_train)), Y_train_pred, '-o')
plt.legend(['负荷实际值', '灰色预测模型预测值'])
plt.title('训练集')
plt.show()
plt.grid()
plt.plot(np.arange(len(X_test)), X_test, '->')
plt.plot(np.arange(len(X_test)), Y_test_pred, '-o')
plt.legend(['负荷实际值', '灰色预测模型预测值'])
plt.title('测试集')
plt.show()
来源:https://juejin.cn/post/7195014110411980859
猜你喜欢
- 总结了一下自己工作中使用到的注释书写规范,没有什么技术含量,只是用于统一制作方式,方便维护。包含了“区域注释”、“单行注释”、“注释层级”和
- 1、正则表达式包括两部分①定义正则表达式的规则;②正则表达式的模式(i/g/m);2、声明正则表达式① 字面量声明: var reg = /
- 今天看了篇关于Web Form Design的成功案例,虽然讲的事情很简单,但总结了一些方法,翻译过来做个原始积累吧,以后写东西举例子时也好
- 我刚进入5gsns的时候,我真不知道怎么玩,我是通过白鸦的博客过去的,之前也没有怎么去玩过这类的网站。对于sns网站还算是陌生,不过还好网站
- 我将图形编辑程序分为两类:一类(是)绘图程序,利用这种程序可以一个像素一个像素(地)绘制图像;另外一类(是)制图程序,这种程序提供了一组对象
- 将有安全问题的SQL过程删除.比较全面.一切为了安全!删除了调用shell,注册表,COM组件的破坏权限MS SQL SERVER2000使
- PHP观察者模式(Observer Pattern)观察者模式是一种行为设计模式,它定义了一种订阅机制,让一个或多个对象(观察者)自动被通知
- 阅读上一篇:W3C优质网页小贴士(三)明智地选择 URI没有什么比走到你最喜欢的商店门口,却发现店门紧闭,而且没有看见店面搬迁告示这种事情还
- 继Go 1.18支持泛型后,Go 将在下个版本中支持pdqsort排序算法再次引起了开发者们的热切讨论。目前,Go仓库的最新commit中提
- 本文实例为大家分享了Python曲线拟合的最小二乘法,供大家参考,具体内容如下模块导入import numpy as npimport ga
- 在 MySQL 中,数据库和表对应于那些目录下的目录和文件。因而,操作系统的敏感性决定数据库和表命名的大小写敏感。这就意味着数据库和表名在
- 完全备份的SH文件:exp_comp.shrq=` date +"%m%d" `su - oracle -c "
- 1.抽象类抽象类机制中总是要定义一个公共的基类,而将特定的细节留给继承者来实现。通过抽象概念,可以在开发项目中创建扩展性很好的架构。任何一个
- 呵呵,这几天沉溺于灌水,发现转贴的时候真的是很不方便,文字、图形、颜色、连接,如果都转过来真的是满费劲的,于是就写了一个小东西,简陋的很,不
- 在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时候怎么办呢?不用担心, mysql已经为我们提供了这样一个功
- 可试试下面这个方法,但要保证在FORM中使用的Input Name都和数据库中使用的是一样的:upfiles.asp<% &
- 如何获知用户的IP?<% Dim ValidLog ' 日志变量 Valid
- 前言python中进行面向对象编程,当在子类的实例中调用父类的属性时,由于子类的__init__方法重写了父类的__init__方法,如果在
- 以下介绍用数据库实现简单计数器,功能实现统计网站每日访问,每周访问及总访问量的统计,使用js调用下面存为count.asp<%&nbs
- 自己前端开发中常用到的一些技巧及问题解决方法,会常更新,希望对前端路上的朋友有帮助。1、文章标题列表中日期居右显示的方法(提供了两种方法,使