时间序列预测实战 ARIMA模型(Python)
ARIMA模型的实战(一元)
首先数据分析类问题采用Jupyter来编写比较方便,所以该文中的代码都是用于Jupyter中的。
ARIMA模型的简单说明:
ARIMA模型全名为差分整合移动平均自回归模型,可以分为三部分:AR,I,MA(自回归,差分,移动平滑),显然他是一个组合模型。
- p阶AR模型AR(p)表示为:
其中c是常数,ψ1,…,ψp是回归参数,ϵ(t)是对时间序列的不确定因素(noise)建模的变量。 公式表明,如果模型x(t-T)中包含前一时期的样本,则AR模型可以处理季节性。
2.q阶的MA模型MA(q)表示为:
其中,μ是x(t)的期望,θ1,…,θq是模型的参数,而ϵ(t)是对不确定因素进行建模的变量。 如公式所示,MA模型具有灵活性,因为它们基于不确定变量的先前值来估计时间序列的当前值。
3.阶数为p和q的ARMA模型ARMA(p,q)表示为:
ARMA模型由于其灵活性和精度而被广泛使用, p和q的选择通常基于PACF和ACF。
————————————————————————————————————————————————————————————————
接下来就是代码部分:由于是用的Jupyter所以分个个cell来贴。
%matplotlib inline
import pandas as pd
import pandas_datareader
import datetime
import matplotlib.pylab as plt
import seaborn as sns
from matplotlib.pylab import style
import matplotlib.pyplot as plt
import statsmodels.api as sm
from statsmodels.graphics.tsaplots import plot_acf,plot_pacf
from statsmodels.tsa.arima_model import ARIMA
from statsmodels.tsa.arima_model import ARMA
from statsmodels.stats.stattools import durbin_watson
from statsmodels.graphics.api import qqplot
style.use('ggplot')
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
这就是导入的一些包,或者数据库,如果报错的话,请自行pip下载,百度一下还是比较简单的。
————————————————————————————————
birthsFile = 'births.csv'
births = pd.read_csv(birthsFile, index_col=0, parse_dates=[0])
births.head(10)
这是读取文件部分,应该也不需要多解释了,我的数据集是1959年美国某某州每天出生女婴个数。
代码中运用了一个head()函数,所以应该会输出一个这样的:
——————————————————————————————————————————————
births.plot(figsize=(12,8))
plt.legend(bbox_to_anchor=(1.25, 0.5))
plt.title("Births")
sns.despine()
读取数据运行结果:
———————————————————————————————————————————
——————————————
births_diff = births.diff()
births_diff = births_diff.dropna()
plt.figure()
plt.plot(births_diff)
plt.title('一阶差分')
plt.show()
做一个一阶差分,做差分是为了让数据更加平稳,因为是时间序列,所以好比是今天与昨天做了一个差分。
运行结果:
如果数据还是不平稳可以再做一次差分(二阶差分),一般而言一阶差分就够了。
births_diff2 = births_diff.diff()
births_diff2 = births_diff2.dropna()
plt.figure()
plt.plot(births_diff2)
plt.title('二阶差分')
plt.show()
这是二阶差分的代码。
————————————————————————————————————————————————————————————
acf = plot_acf(births_diff, lags=20)
plt.title("ACF")
acf.show()
ACF(自相关系数)图:
pacf = plot_pacf(births_diff, lags=20)
plt.title("PACF")
pacf.show()
PACF(偏自相关系数图):
偏自相关的这个阶数有点不对劲,但是不管他=。=
ACF对应的就是q阶
PACF对应的就是p阶
AIC = sm.tsa.arma_order_select_ic(births,max_ar=7,max_ma=1,ic='aic')['aic_min_order']
BIC = sm.tsa.arma_order_select_ic(births,max_ar=7,max_ma=1,ic='bic')['bic_min_order']
print('the AIC is{},\nthe BIC is{}'.format(AIC,BIC))
这个代码意思是:利用AIC:赤池信息准则(Akaike Information Criterion,AIC)或者
BIC:贝叶斯信息准则(Bayesian Information Criterion,BIC)进行p,q的选择。
由输出可知(2,1)(1,1)都是可以的。
————————————————————————————————————————————————————————
model = ARIMA(births, order=(2, 1, 1),freq='D')
代码中的order=(2,1,1)也就是ARIMA模型的参数(p,d,q)。
p,q就是阶数,d就是差分的次数。
result = model.fit()
pred = result.predict('1959/12/01', '1960/01/31',dynamic=True, typ='levels')
print (pred)
(‘1959/12/01’,‘1960/01/31’)就是我预测的时间段。
plt.figure(figsize=(6, 6))
plt.xticks(rotation=45)
plt.plot(pred)
plt.plot(births)
运行结果就是:
红线就是预测的结果,这个数据集有点不明显,大家可以用其他的数据集,比如一个有上升趋势的数据集,hhh。
——————————————————————————————————————————————————————————————
然后进行模型的检验
resid = result.resid
plt.figure(figsize=(12,8))
#qq图检验残差是否满足正态分布
qqplot(resid,line='q',fit=True)
#利用D-W检验,检验残差的自相关性
print('D-W检验值为{}'.format(durbin_watson(resid.values)))
运行结果为:
D-W值越接近2,模型越好。
由运行结果也可以知道:由QQ图可以知道该数据集的残差满足正态分布。
——————————————————————————————————————————————
对于有季节性的数据集建议使用SARIMA模型,有季节性的数据对这个模型并不适用。
本文地址:https://blog.csdn.net/Dylanqin/article/details/109645487
上一篇: 线性回归
下一篇: Python中常用的os操作汇总