時間序列分析的目的:給定一個已被觀測了的時間序列,預測該序列的未來值
ARIMA 模型:如果一個時間序列經差分運算後具有平穩性,則該序列爲差分平穩序列,可以使用 ARIMA 模型進行分析。
時間序列的預處理:
- 平穩性檢驗:
時序圖檢驗:平穩序列的時序圖顯示該序列值始終在一個常數附近隨機波動,而且波動範圍有界;
非平穩序列有明顯的趨勢性或週期性。
自相關圖檢驗:平穩序列具有短期相關性,即只有近期的序列值對現時值的影響比較明顯,間隔越遠的過去值對現時值影響越小。隨着延遲期數k的增加,平穩序列的自相關係數會比較快的衰減趨向於0, 並在0附近隨機波動
非平穩序列的自相關係數衰減的速度比較慢。
單位根檢驗:存在單位根就是非平穩序列。
- 純隨機性檢驗(白噪聲檢驗):由樣本各延遲期數的自相關係數可以計算得到檢驗統計量,然後計算出對應的 p 值。如果 p 值顯著大於顯著性水平,則爲白噪聲序列,可以停止分析。
預處理完成後可以根據處理結果將序列分爲不同類型,不同的序列採取不同的分析方法:
- 純隨機序列(白噪聲序列):各項之間沒有任何相關關係,序列在進行完全無徐的隨機波動,是沒有信息可提取的平穩序列。此時可以終止對該序列的分析。
- 平穩非白噪聲序列:其均值和方差是常數。常用的擬合模型是 ARMA 模型。
- 非平穩序列:均值和方差不穩定,一般將其轉變爲平穩序列。如果一個時間序列經差分運算後具有平穩性,則該序列爲差分平穩序列,可以使用 ARIMA 模型進行分析。
模型識別原則:
模型 | 自相關係數 ACF | 偏自相關係數 PACF |
---|---|---|
AR(p) | 拖尾 | p 階截尾 |
MA(q) | q 階截尾 | 拖尾 |
AEMA(p,q) | p 階截尾 | q 階截尾 |
差分運算:
- p 階差分:相距一期的兩個序列值之間的減法運算稱爲1階差分運算。
- k 步差分:相距k期的兩個序列值之間的減法運算稱爲k步差分運算。
差分運算具有強大的確定性信息提取能力,許多非平穩序列差分後會顯示出平穩序列的性質,這時稱這個非平穩序列爲差分平穩序列。
對差分平穩序列可以使用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)