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]] = 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)
print(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([17681.37,18309.06,18927.07,19457.05,19914.97])
x = data[0:5]
y = data[0:]
result = GM11(x,len(y))
predict = result['predict']['value']
predict = np.round(predict,1)
print('真实值:',y)
print('预测值:',predict)
print(result)
import numpy as np
import matplotlib.pyplot as plt
x1 = np.array([2013,2014,2015,2016,2017])
y1 = np.array([17681.37,18309.06,18927.07,19457.05,19914.97])
x2 = np.array([2014,2015,2016,2017,2018,2019,2020])
y2 = np.array([18357.72,18876.57,19410.09,19958.69,20522.79, 21102.83, 21699.27])
plt.plot(x1,y1,'r*-',label='true value')
plt.plot(x2,y2,'b+-',label='predicted value')
plt.xlabel('year')
plt.ylabel('value')
plt.legend()
plt.plot()
plt.show()
输出结果
真实值的预测值以及对未来五年的预测
得到的预测图