时间序列分析的目的:给定一个已被观测了的时间序列,预测该序列的未来值
ARIMA 模型:如果一个时间序列经差分运算后具有平稳性,则该序列为差分平稳序列,可以使用 ARIMA 模型进行分析。
时间序列的预处理:
时序图检验:平稳序列的时序图显示该序列值始终在一个常数附近随机波动,而且波动范围有界;
非平稳序列有明显的趋势性或周期性。
自相关图检验:平稳序列具有短期相关性,即只有近期的序列值对现时值的影响比较明显,间隔越远的过去值对现时值影响越小。随着延迟期数k的增加,平稳序列的自相关系数会比较快的衰减趋向于0, 并在0附近随机波动
非平稳序列的自相关系数衰减的速度比较慢。
单位根检验:存在单位根就是非平稳序列。
预处理完成后可以根据处理结果将序列分为不同类型,不同的序列采取不同的分析方法:
模型识别原则:
模型 | 自相关系数 ACF | 偏自相关系数 PACF |
---|---|---|
AR(p) | 拖尾 | p 阶截尾 |
MA(q) | q 阶截尾 | 拖尾 |
AEMA(p,q) | p 阶截尾 | q 阶截尾 |
差分运算:
差分运算具有强大的确定性信息提取能力,许多非平稳序列差分后会显示出平稳序列的性质,这时称这个非平稳序列为差分平稳序列。
对差分平稳序列可以使用ARMA模型进行拟合。ARIMA 模型的实质就是差分运算与ARMA模型的组合。
差分平稳时间序列建模步骤:
获得观察值序列——>平稳性检验——(Y)——>白噪声检验——(Y)——>分析结束
平稳性检验——(N)——>差分运算——>平稳性检验------->白噪声检验——(N)——>拟合 ARMA 模型——>白噪声检验------->分析结束
得到平稳非白噪声序列后建模步骤:
平稳非白噪声序列——>计算 ACF、PACF——>ARMA模型识别——>估计模型中未知参数的值——>模型检验——(Y)——>模型优化——(Y)——>预测将来走势
-----模型检验——(N)——>ARMA模型识别——>估计模型中未知参数的值——>模型检验——(Y)——>模型优化——(N)——>ARMA模型识别------
实例:
根据时序图、自相关图、单位根检验,判断平稳性:
import pandas as pd
discfile='../data/arima_data.xls'
forecastnum=5
#读取数据,指定日期列为指标,pandas自动将日期识别为 Datatime 格式
data=pd.read_excel(discfile,index_col=u'日期')
#时序图
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
data.plot()
data.show()
#自相关图
from statsmodels.graphics.tsaplots import plot_acf
plot_acf(data).show()
#平稳性检测——单位根检验
from statsmodels.tsa.stattools import adfuller as ADF
print(u'原始序列的 ADF 检验结果为:',ADF(data[u'销量']))
#返回值依此是:adf、pvalue、usedlag、nobs、critical、values、icbest、regresults、resstore
对非平稳序列进行差分运算:
#差分后的结果
D_data=data.diff().dropna()
D_data.columns=[u'销量差分']
#差分后再次检验
#时序图
D_data.plot()
plt.show()
#自相关图
plot_acf(D_data).show()
from statsmodels.graphics.tsaplots import plot_pacf
#偏自相关图
plot_pacf(D_data).show()
#单位根检验
print(u'差分序列的 ADF 检验结果为:',ADF(D_data[u'销量差分']))
对平稳序列进行白噪声检验:
#白噪声检验
from statsmodels.stats.diagnostic import acorr_ljungbox
print(u'差分序列的白噪声检验结果为:',acorr_ljungbox(D_data,lags=1)) #返回统计量和 p 值
ARIMA 模型拟合:
from statsmodels.tsa.arima_model import ARIMA
data[u'销量']=data[u'销量'].astype(float)
#定阶
pmax = int(len(D_data)/10) #一般阶数不超过 Length/10
qmax = int(len(D_data)/10) #一般阶数不超过 Length/10
bic_matrix=[] #bic 矩阵
for p in range(pmax+1):
tmp=[]
for q in range(qmax+1):
try: #存在部分报错,用 try来跳过报错
tmp.append(ARIMA(data,(p,1,q)).fit().bic)
except:
tmp.append(None)
bix_matrix.append(tmp)
bic_matrix = pd.DataFrame(bic_matrix) #从中可以找出最小值
#先用 stack 展平,然后用 idxmin 找出最小值位置
p,q=bic_matrix.stack().idxmin()
print(u'BIC 最小的 p 值和 q 值为:%s、%s'%(p,q))
#建立 ARIMA(0,1,1)模型
model=ARIMA(data,(p,1,q)).fit()
#给出一份模型报告
model.summary2()
#做为期 5 天的预测,返回预测结果、标准误差、置信区间
model.forecast(5)