ARIMA模型的定阶原理与建模分析
- 前言
- 一:AR ( p ) (p) (p)模型的定阶原理
- 二:MA ( q ) (q) (q)模型的定阶原理
- 三:ARMA模型
- 四:实际建模运用
- 五:建模结果比较分析
- 六:总结
前言
ARIMA模型是很经典的自回归模型,这篇文章将全面的讲述ARIMA的建模步骤。从定阶原理解释到实际数据代码编写模型来进行回归预测。基于理论推导和代码编写一气呵成!
岁月如云,匪我思存,写作不易,望路过的朋友们点赞收藏加关注哈,在此表示感谢!
一:AR模型的定阶原理
AR模型是一个线性模型,p阶自回归模型的一般表达式为:
其中 是一个白噪声序列,既然AR模型被建立,此AR模型是满足弱平稳条件的,则存在 和自相关系数,以及。
- 首先我们先建立AR(2)模型
那么我们对上式 (*) 左右两边各减去 得:
又由弱平稳性质,
即
那么把此结果带入
式两边乘以 :
对 式两边再除以方差 之后得 ,这里的 为自相关系数。
则可得 ,同理 (2) 式两边同时乘以
可得 。
同理我们推广 式两边乘以
可得
从 的表达式我们容易发现尽管 ,但
- 接着我们拓展至AR模型
在平稳的前提下,我们容易得
将 两边减去均值 可得:
那么对 左右两边同乘以 并除以方差
根据这些关系式,模仿AR(2)的递推关系式可得:
因此符合的平稳序列模型,其自相关系数在
二:MA模型的定阶原理
模型被称为移动平均模型,一个 阶的移动平均模型可以用数学式表达为:
那么满足的性质有
;
- 首先我们还是建立模型
如
则
对于 ,两边同时被
又
那么最终 。
如果我们相同的方法求解 ,那么
- 接着我们建立模型
同理对于模型,我们经过相同的运算可得最终表达式
那么当 时同理可得
所以,通过上述推导我们有理由相信:模型的自相关系数 阶截尾。所谓 阶截尾意思是在 阶以后模型的自相关系数立马截止,
以上就是通过理论解释了AR§模型和MA(q)模型的拖尾和截尾的底层逻辑。
三:ARMA模型
- 参数估计过程
当把模型和模型相结合时,我们得到模型如下:
相较于前两个模型,此模型是更具有普遍性。首先我们通过一些定阶模型确定 ,当阶数确定后,可以根据最小二乘最大似然估计或者梯度下降法更新所有方程系数。根据模型的表达式一直迭代下去即可完成“无穷的”预测。但是作为长期预测,理论上是可行的,实际确实长期预测所受的干扰因素太多了,除非你的预测数据是周期性、趋势性或者季节性的,那长期还是有点实际意义,否则任何回归模型,还是作为短期预测才有更大的实际意义。
- 建模过程
1:序列判断
(a):判断我们需要建立的模型数据是否为平稳序列,若非平稳序列我们要对其进行变换处理(一般用差分方法即可)至平稳序列,
(b):接着再判断平稳序列时候为白噪声序列,若为白噪声序列则建模结束(白噪声序列无法构成ARMA模型),否则进行下一步。
2:模型估计与建立
(a):判断 和 的值。当我们建立好自回归模型时,为了得到最优的模型结构,我们需要定下 和 值。这里的定阶一是可以通过自相关系数和偏自相关系数大致决定。由上面的理论分析,我们知道)将出现 阶拖尾,将出现
(b):如果序列的和不是很明确的话,我们可以用其他模型来定阶。其中就包括AIC和BIC信息准备判别。AIC是一种用于模型选择的指标,同时考虑模型的拟合程度以及简单性,BIC是对AIC的改进,一般来说较小的AIC或者BIC表示在保持模型简单的同时,能够更好的对时间序列进行拟合。
3:模型诊断
即对模型残差进行验证,确保其为服从正态分布的白噪声序列,当模型的残差为白噪声时,说明我们已经将序列的信息充分提取到模型中,建模彻底结束。
在上一篇文章我们对于ARMA模型
四:实际建模运用
我们接下来基于实际销量数据开始建立时序模型,首先观察下销量数据可视化结果,由曲线图发现销量的变化明显具有上涨的趋势性,符合自回归移动平均模型的建模直观要求。
图1
from statsmodels.graphics.tsaplots import plot_acf,plot_pacf
from statsmodels.tsa.stattools import adfuller as ADF
from statsmodels.stats.diagnostic import acorr_ljungbox
from statsmodels.tsa.arima_model import ARIMA
import statsmodels.api as sm
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
yv = np.array([2800,2811,2832,2850,2880,2910,2960,3023,3039,3056,3138,3150,3198,3100,3029,2950,2989,3012,3050,3142,3252,3342,3365,3385,3340,3410,3443,3428,3554,3615,3646,3614,3574,3635,3738,3764,3788,3820,3840,3875,3900,3942,4000,4021,4055])
yv_serie = pd.Series(yv[:-10])##样本外数据
def testwhitenoise(data):
m = 10# 检验10个自相关系数
acf,q,p = sm.tsa.acf(data,nlags=m,qstat=True)
out = np.c_[range(1,m+1),acf[1:],q,p]
output = pd.DataFrame(out,columns=['lag','自相关系数','统计量Q值','p_values'])
output = output.set_index('lag')# 设置第一列索引名称,可省略重复索引列1
print(output)
def teststeady(data,count=0):
res_ADF = ADF(data)
print('ADF检验结果为:', res_ADF)
Pv = res_ADF[1]
if Pv > 0.05:
print('\033[1;31mP值:%s,原始序列不平稳,要进行差分!\033[0m' % round(Pv,5))
count = count + 1
print('\033[1;32m进行了%s阶差分后的结果如下\033[0m' % count)
data = data.diff(1).dropna()
teststeady(data,count)
else:
print('\033[1;34mP值:%s,原始序列平稳,继续建模\033[0m'% round(Pv,5))
testwhitenoise(yv_serie)
teststeady(yv_serie)
图2
图2就是平稳性和自相关性(白噪声)检验的结果,我们发现当进行一阶差分后序列平稳,按照建模步骤我们接下来开始定阶。
def confirm_p_q(data):
fig = plt.figure(figsize=(8,6))
testwhitenoise(data)
train = teststeady(data)
ax1 = fig.add_subplot(211)
fig = sm.graphics.tsa.plot_pacf(train, lags=10, ax=ax1)
ax2 = fig.add_subplot(212)
fig = sm.graphics.tsa.plot_acf(train, lags=10, ax=ax2)
plt.show() ###可视化定阶
pmax = int(len(data) / 10)
qmax = int(len(data) / 10)
AIC = sm.tsa.arma_order_select_ic(train,max_ar=pmax,max_ma=qmax,ic='aic')['aic_min_order']
BIC = sm.tsa.arma_order_select_ic(train,max_ar=pmax,max_ma=qmax,ic='bic')['bic_min_order']
HQIC = sm.tsa.arma_order_select_ic(train,max_ar=pmax,max_ma=qmax,ic='hqic')['hqic_min_order']
print('AIC:',AIC)
print('BIC:',BIC)
print('HQIC:',HQIC)
return AIC
pq = confirm_p_q(yv_serie)##返回p,q值
图3
图4
由上面图4自相关函数图可知,定阶在 阶比较合理,再由相应的信息准则,我们最终定阶
这里的定阶结果都是理论给的结果,实际中的定阶还是要根据模型表现不断调整,一般阶数越高越复杂,拟合效果越强,但过拟合概率也越高,所以要不断尝试不断调整。
接着我们正式开始预测
def prediction(data):
tempmodel = ARMA(teststeady(data),pq).fit(disp=-1)
print(tempmodel.summary())
#num = 10
#predictoutside1 = tempmodel.forecast(num)[0]#预测样本外的
predictoutside2 = tempmodel.predict(len(tempmodel.predict()),len(tempmodel.predict()) + 9,dynamic=True)##也是样本外预测,预测结果一致
predictinside = tempmodel.predict()##样本内预测
init_value = yv[0]
fig = plt.figure(figsize=(8, 6))
predictinside = predictinside.cumsum()##差分还原
pretrueinside = init_value + predictinside
startprevalue = list(pretrueinside)[-1]
predictoutside2 = predictoutside2.cumsum()##差分还原
pretrueoutside = startprevalue + predictoutside2
##作图
plt.plot(yv,label='原始值')
plt.plot([init_value] + list(pretrueinside),label='样本内预测值')
X = [i for i in range(len(yv)-11,len(yv))]
plt.plot(X,[startprevalue] + list(pretrueoutside), label='样本外预测值')
allpredata = [init_value] + list(pretrueinside) + list(pretrueoutside)
plt.legend()
plt.show()
return tempmodel,allpredata
preres = prediction(yv_serie)
最后我们对模型进行评价
def evaluate_model(model,apd):
delta = model.fittedvalues - tsres
score = 1 - delta.var() / tsres.var()
print('R^2:', score)
allmse = mean_squared_error(apd,yv)##所有预测值跟所有原始值的MSE
print('ALLMSE:',allmse)
###残差白噪声检验
testwhitenoise(delta)
evaluate_model(preres[0],preres[1])
五:建模结果比较分析
- 当我们选择阶数
图5:p,q=(1,1)
图6
注:这里涉及两个评价指标,一个是拟合优度 值,公式如下: , 是方差意思, 越接近1,说明拟合越好。 另一个是均方误差,公式如下: ,
从残差检验是白噪声序列后,我们完整的建模算正式结束!
当我们选择阶数
图7:p,q=(2,2)
图8
由图5和图6比较,直观上感觉图6总体拟合效果更好,再观察理论评价指标,也是 表现的更好,所以具体定阶时,我们不妨多个指标一起观察。
六:总结
- 此篇文章涉及的内容很多,有详细的理论推导解释AR§拖尾和MA(q)截尾的缘故,并最终一步一步建立ARMA模型来解决实际问题,
- 在上一篇文章我们也谈到ARMA对趋势性,周期性和季节性数据做短期预测是非常有效的,这篇文章主要是对趋势性数据做预测,周期性和季节性当然也是同理而得,
- 对于阶数 。