數據挖掘——時間序列算法之ARIMA模型
關於時間序列的其他模型,請參考本人的以下博文:
1、平滑法
2、趨勢擬合法
3、組合模型
4、AR模型
5、MA模型
6、ARMA模型
7、ARIMA模型
8、ARCH模型
9、GARCH模型及其衍生模型
前言
前面幾篇對平穩序列進行分析,然而實際上大多數時間序列都是非平穩的。對非平穩時間序列的分析方法可以分爲確定性因素分解的時序分析和隨機時序分析兩個大類。
- 確定性因素分解的方法把所有序列的變化都歸結爲4個因素:長期趨勢、季節變動、循環變動和隨機波動。其中長期趨勢和季節變動的規律性信息通常比較容易提取,而由隨機因素導致的波動則非常難確定和分析,對隨機信息浪費驗證,會導致模型擬合精度差。
- 隨機時序分析法的發展就是爲了彌補確定性因素分解方法的不足。根據時間序列的不同特點,隨機時序分析可以建立的模型有ARIMA模型、殘差自迴歸模型、季節模型、異方差模型。
差分定義
相距d期的兩個序列值之間的減法運算稱爲d階差分運算。(定義這個是爲了後面用)
ARIMA模型
ARIMA模型(Autoregressive Integrated Moving Average model),差分整合移動平均自迴歸模型,又稱整合移動平均自迴歸模型(移動也可稱作滑動),是時間序列預測分析方法之一
許多非平穩序列差分後會顯示出平穩序列的性質,這時非平穩序列爲差分平穩序列。對差分平穩序列就可以使用ARMA模型進行擬合了。
ARIMA的數學表達:
很明顯哈,ARIMA的實質就是差分運算與ARMA模型的結合。其中,是AR模型的參數,是MA模型的參數。
關於ARIMA的計算方法,這裏有一篇比較好的博客,我這裏就臭不要臉的在他的上面截圖了:
上面的例子可以很好的幫助理解ARIMA模型。
差分平穩時間序列建模步驟:
實踐
先查看數據長什麼樣
import pandas as pd
data = pd.read_excel( './data/arima_data.xls', index_col = u'日期')
data
1、檢驗序列的平穩性
1)畫個趨勢圖,檢驗序列的平穩性
#時序圖
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用來正常顯示中文標籤
plt.rcParams['axes.unicode_minus'] = False #用來正常顯示負號
data.plot()
plt.show()
從原始數據的趨勢圖中很明顯的看出,該序列具有單調遞增趨勢,可以判斷爲是非平穩數據。
2)再看下原始數據的自相關圖
#自相關圖
from statsmodels.graphics.tsaplots import plot_acf
plot_acf(data).show()
上面的自相關圖顯示自相關係數長期大於0,說明序列間具有很強的長期相關性。
3)再來看原始數據的單位根檢驗
#平穩性檢測
from statsmodels.tsa.stattools import adfuller as ADF
print(u'原始序列的ADF檢驗結果爲:', ADF(data[u'銷量']))
#返回值依次爲adf、pvalue、usedlag、nobs、critical values、icbest、regresults、resstore
結果如下:
整理成表格:
ADF | cValue | p值 |
---|---|---|
1.8138 | 1%:-3.7112;5%:-2.9812;10%:-2.6301 | 0.9984 |
結論:上表中表明,單位根檢驗統計量對應的p值顯著大於0.05,最終將該序列判斷爲非平穩序列,並且非平穩數據一定不是白噪聲數據。
2、進行一階差分後,進行平穩性和白噪聲檢驗
1)對一階差分後的序列再次做平穩性判斷
#差分後的結果
D_data = data.diff().dropna()
D_data.columns = [u'銷量差分']
D_data.plot() #時序圖
plt.show()
2)自相關圖
plot_acf(D_data).show() #自相關圖
3)單位根檢驗
print(u'差分序列的ADF檢驗結果爲:', ADF(D_data[u'銷量差分'])) #平穩性檢測
ADF | cValue | p值 |
---|---|---|
-3.1561 | 1%:-3.6327;5%:-2.9485;10%:-2.6130 | 0.0227 |
結果顯示:
- 一階差分後的序列的時序圖在均值附近比較平穩的波動
- 自相關圖有很強的短期相關性
- 單位根檢驗p值小於0.05
結論:一階差分之後的序列是平穩序列。
上面已經證明了一階差分後的序列是平穩序列了,那麼就需要對該平穩的一節差分做白噪聲檢驗:
#白噪聲檢驗
from statsmodels.stats.diagnostic import acorr_ljungbox
print(u'差分序列的白噪聲檢驗結果爲:', acorr_ljungbox(D_data, lags=1)) #返回統計量和p值
stat | p值 |
---|---|
11.304 | 0.007724 |
結論:輸出的p值小於0.05,所以一階差分之後的序列是平穩非白噪聲序列。
3、對一階差分之後的平穩非白噪聲序列擬合ARMA模型
下面進行模型定階,也就是確定ARMA的p和q。
這裏有兩種方法可以確定出p和q,即人爲識別的方法和相對最優模型識別。
1)人爲識別方法
使用該方法確定p和q時,一定要知道AR模型和MA模型的性質,這在我的博文裏面有說,詳見本文開始部分處的鏈接。
回顧下一階差分後的自相關圖:
可見一階差分後的自相關圖顯示出了1階截尾 (記爲結論1)
再看一階差分後的偏自相關圖:
from statsmodels.graphics.tsaplots import plot_pacf
plot_pacf(D_data).show() #偏自相關圖
可見一階差分後的偏自相關圖顯示出了拖尾性 (記爲結論2)
(關於截尾和拖尾,看此篇文章,或者簡要的看下下面的圖)
綜合結論1和結論2 ,可以考慮用MA(1)模型擬合1階差分後的序列,即對袁術序列建立ARIMA(0,1,1)模型。
2)相對最優模型識別
使用該方法必須瞭解BIC和AIC的含義,可以看此篇文章:ARIMA模型原理及實現,這塊截一段主要介紹:
計算ARMR(p,q)。當p和q均小於等於3的所有組合的BIC信息量,取其中BIC信息量達到最小的模型階數。
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)
bic_matrix.append(tmp)
bic_matrix = pd.DataFrame(bic_matrix) #從中可以找出最小值
bic_matrix
可以看到在p=0,q=1的時候BIC是最小的,爲422.51…。用下面的代碼找出
p,q = bic_matrix.stack().idxmin() #先用stack展平,然後用idxmin找出最小值位置。
print(u'BIC最小的p值和q值爲:%s、%s' %(p,q))
4、使用ARIMA預測
上面已經得到了p=0,q=1,那麼就應用ARIMA(0,1,1)對原始數據即某餐廳的顯瘦數據作爲爲期5天的預測。
model = ARIMA(data, (p,1,q)).fit() #建立ARIMA(0, 1, 1)模型
model.summary2() #給出一份模型報告
model.forecast(5) #作爲期5天的預測,返回預測結果、標準誤差、置信區間。
預測結果如下:
需要注意:利用模型向前預測的時期越長,預測誤差將會越大,這是時間預測的典型特點。