目录
- 程序简述
- 程序/数据集下载
- 数据集截图
- 核心代码解析(接口,可直接运行)
- 接口调用、运行效果
- Main.py
程序简述
利用灰色预测GM11模型预测股票收盘价,由于灰色预测模型适合短期预测和小样本,所以程序输入数据为5个,输出为1个,进行动态建模
程序输入:原序列、需要往后预测的个数
程序输出:预测值、模型结构(后验差比、发展系数、灰色作用量)
灰色预测模型 (GM11)即对原始数据作累加生成(或其它方法生成)得到近似的指数规律再进行建模的方法。灰色预测模型对于不同问题采用不同模型,模型主要解决生成序列是有指数变化规律,只能描述单调的变化过程。
程序/数据集下载
点击进入下载地址
数据集截图
图1,上证指数股票数据,共7128行,但出于灰色预测的特性,本文只用了最后30个数据做实验
核心代码解析(接口,可直接运行)
程序输入原序列和需要预测个数后会返回模型结构和预测值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | # -*- coding: utf-8 -*- import matplotlib.pyplot as plt import pandas as pd import numpy as np def GM11(x,n): ''' 灰色预测 x:序列,numpy对象 n:需要往后预测的个数 ''' x1 = x.cumsum()#一次累加 z1 = (x1[:len(x1) - 1] + x1[1:])/2.0#紧邻均值 z1 = z1.reshape((len(z1),1)) B = np.append(-z1,np.ones_like(z1),axis=1) Y = x[1:].reshape((len(x) - 1,1)) #a为发展系数 b为灰色作用量 [[a],[b]] = np.dot(np.dot(np.linalg.inv(np.dot(B.T, B)), B.T), Y)#计算参数 result = (x[0]-b/a)*np.exp(-a*(n-1))-(x[0]-b/a)*np.exp(-a*(n-2)) S1_2 = x.var()#原序列方差 e = list()#残差序列 for index in range(1,x.shape[0]+1): predict = (x[0]-b/a)*np.exp(-a*(index-1))-(x[0]-b/a)*np.exp(-a*(index-2)) e.append(x[index-1]-predict) S2_2 = np.array(e).var()#残差方差 C = S2_2/S1_2#后验差比 if C<=0.35: assess = '后验差比<=0.35,模型精度等级为好' elif C<=0.5: assess = '后验差比<=0.5,模型精度等级为合格' elif C<=0.65: assess = '后验差比<=0.65,模型精度等级为勉强' else: assess = '后验差比>0.65,模型精度等级为不合格' #预测数据 predict = list() for index in range(x.shape[0]+1,x.shape[0]+n+1): predict.append((x[0]-b/a)*np.exp(-a*(index-1))-(x[0]-b/a)*np.exp(-a*(index-2))) predict = np.array(predict) return { 'a':{'value':a,'desc':'发展系数'}, 'b':{'value':b,'desc':'灰色作用量'}, 'predict':{'value':result,'desc':'第%d个预测值'%n}, 'C':{'value':C,'desc':assess}, 'predict':{'value':predict,'desc':'往后预测%d个的序列'%(n)}, } if __name__ == "__main__": data = np.array([1.2,2.2,3.1,4.5,5.6,6.7,7.1,8.2,9.6,10.6,11,12.4,13.5,14.7,15.2]) x = data[0:10]#输入数据 y = data[10:]#需要预测的数据 result = GM11(x,len(y)) predict = result['predict']['value'] predict = np.round(predict,1) print('真实值:',y) print('预测值:',predict) print(result) |
接口调用、运行效果
Main.py
以上证指数为例,进行灰色预测建模,效果勉强,数据集的选择和预测长度很重要
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | # -*- coding: utf-8 -*- from Module.BuildModel import GM11 from sklearn.metrics import mean_absolute_error import pandas as pd import numpy as np import matplotlib.pyplot as plt import os #路径目录 baseDir = os.path.dirname(os.path.abspath(__file__))#当前目录 staticDir = os.path.join(baseDir,'Static')#静态文件目录 resultDir = os.path.join(baseDir,'Result')#结果文件目录 #读取数据 data = pd.read_csv(staticDir+'/000001.csv',encoding='gbk') train = data['收盘价'].values[-15:-10]#训练数据 test = data['收盘价'].values[-10:]#测试数据 #GM11动态建模 yPre = [] for i in range(test.shape[0]): #只预测1个数 result = GM11(train,1) yPre.append(result['predict']['value'][0]) #更新训练集 train = train.tolist()[:-1] train.append(test[i]) train = np.array(train).reshape(-1) #计算MAE MAE = mean_absolute_error(test,yPre) #打印模型 print(result['C']['desc']) print(result['a']['desc'],np.round(result['a']['value'],2)) print(result['b']['desc'],np.round(result['b']['value'],2)) #可视化 #用来正常显示中文标签 plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示负号 plt.rcParams['axes.unicode_minus']=False plt.plot(range(test.shape[0]),yPre,label="预测值") plt.plot(range(test.shape[0]),test,label="观测值") plt.legend() plt.title('GM11预测效果,MAE:%2f'%MAE) plt.savefig(resultDir+'/GM11预测效果.png',dpi=100,bbox_inches='tight') |
图2,程序输出,模型结构
图3,预测值和观测值对比折线图,对于短期预测GM11表现良好