自回归模型(AutoRegression Model)可以用来预测时间序列将来的值,该模型假定前后值之间的关系是线性的。在使用该模型时,通常要假定一个随机变量的值依赖于它前面的值。我们要做的是拟合数据,为数据找到适当的参数。自回归模型的数学公式如下:
x
t
x_t
xt?=c+
∑
i
=
1
p
a
i
?
x
k
\sum_{i=1}^{p}a_i*x_k
∑i=1p?ai??xk?+
g
t
g_t
gt? (k=t-i) 上述公式中,c为常量,最后一项为随机分量,又称为白噪声。 在进行回归分析时,如果在样本拟合程度非常好的情况下引入新的数据点,可能会出现拟合表现立刻变差的情况。我们可以通过交叉验证,或者使用没有过拟合问题的算法来解决这个问题。 下面通过scipy.optimize.least()函数来搭建一个模型,我们用太阳黑子的数据来训练该模型。代码如下:
'''Xu Yong Kang'''
from scipy.optimize import leastsq
import statsmodels.api as sm
import matplotlib.pyplot as plt
import numpy as np
def model(p,x1,x10):
p1,p10=p
return p1*x1+p10*x10
def error(p,data,x1,x10):
return data-model(p,x1,x10)
def fit(data):
p0=[0.5,0.5]
params=leastsq(error,p0,args=(data[10:],data[9:-1],data[:-10]))
return params
data_loader=sm.datasets.sunspots.load_pandas()
sunspots=data_loader.data['SUNACTIVITY'].values
cutoff=0.9*len(sunspots)
params=fit(sunspots[:int(cutoff)])
print('Params',params)
print(params[0].shape)
print(params[1])
pred=params[0][0]*sunspots[int(cutoff-1):-1]+params[0][1]*sunspots[int(cutoff-10):-10]
actual=sunspots[int(cutoff):]
print('Root mean square error',np.sqrt(np.mean((actual-pred)**2)))
print('Mean absolute error',np.mean(np.abs(actual-pred)))
print('Mean absolute percentage error',100*np.mean(np.abs(actual-pred)/actual))
print('Cofficient of determination',1-((actual-pred)**2).sum()/((actual-actual.mean())**2).sum())
year_range=data_loader.data['YEAR'].values[int(cutoff):]
plt.plot(year_range,actual,'x',label='Actual Sunspots',color='red')
plt.plot(year_range,pred,'o',label='Prediction',color='blue')
plt.grid(True)
plt.xlabel('Year')
plt.ylabel('Activity')
plt.legend()
plt.show()
我们可以从训练结果中得到参数
Params (array([0.67172672, 0.33626295]), 2)
通过这些可以得到预测值 从图中我们可以发现,许多预测几乎是成功的,但也有一些效果很差。 注: 在pred的计算上存在一个关于numpy广播的问题
|