簡介:
ARIMA模型:(英語:Autoregressive Integrated Moving Average model),差分整合移動平均自回歸模型,又稱整合移動平均自回歸模型(移動也可稱作滑動),是時間序列預測分析方法之一。AR是“自回歸”,p為自回歸項數;MA為“滑動平均”,q為滑動平均項數,d為使之成為平穩序列所做的差分次數(階數)。
由於畢業論文要涉及到時間序列的數據(商品的銷量)進行建模與分析,主要是對時間序列的數據進行預測,在對數據進行簡單的散點圖觀察時,發現數據具有季節性,也就是說:數據波動呈現着周期性,並且前面的數據會對后面的數據產生影響,這也符合商品的銷量隨時間波動的影響。於是選擇了ARIMA模型,那為什么不選擇AR模型、MA模型、ARMA模型???
於是,通過這篇博客,你將學到:
(1)通過SPSS操作ARIMA模型
(2)運用python進行白噪聲數據判斷
(3)為什么差分,怎么定階
PS:在博客結尾,會附錄上Python進行ARIMA模型求解的代碼。
為什么會使用SPSS?
由於真香定理,在SPSS里有ARIMA、AR、MA模型的各種操作;還包括異常值處理,差分,白噪聲數據判斷,以及定階。 一種很方便又不用編程還可以避免改代碼是不是很爽…
ARIMA模型的步驟
好啦,使用ARIMA模型的原因:
在過去的數據對今天的數據具有一定的影響,如果過去的數據沒有對如今的數據有影響時,不適合運用ARIMA模型進行時間序列的預測。
使用ARIMA進行建模的步驟:
簡單來說,運用ARIMA模型進行建模時,主要的步驟可以分成以下三步:
(1)獲取原始數據,進行數據預處理。(缺失值填補、異常值替換)
(2)對預處理后的數據進行平穩性判斷。如果不是平穩的數據,則要對數據進行差分運算。
(3)將平穩的數據進行白噪聲檢驗;如果不是白噪聲數據,則說明數據之間仍然有關聯,需要進行ARIMA(p,d,q)重新定階:p、q。
(4)當最后檢驗的數據是白噪聲數據,模型結束。
接下來,就是用SPSS與Python進行實操。
1 原始數據預處理
首先數據來源是:2019年華中賽數學建模B題的數據。通過對一部分數據進行篩選后得到了可以運用模型建立的數據。如下圖所示:
當然我們在拿到新的數據后,需要對數據進行缺失值填補,以及異常值判斷。這里不再展示預處理的相關操作。下面有對應的操作鏈接:
缺失值填補:https://jingyan.baidu.com/article/d8072ac456536bec95cefdb6.html
異常值處理:https://wenku.baidu.com/view/bd0289ca6d85ec3a87c24028915f804d2b1687aa.html?fr=search
2 平穩性檢驗
在獲取了預處理后的數據后,我們就可以進行下一步平穩性檢驗;簡單來說,平穩性也就是時間序列的數據是不是在某一數據上下波動,轉化成數學術語就是:均值和反差不會隨着時間變化而變化。於是可以使用SPSS畫出數據的散點圖,然后通過散點圖的圖像顯示來判斷是否是平穩性數據,如果不是平穩的數據就需要進行差分。
觀察圖像可以看出,原始數據是有很弱的季節性,但是數據是非平穩的。從2018年12月份,商品號SS73210銷量就明顯下降,而不是在某一確定值上下波動。於是,對數據使用一階差分。
為什么差分? 處理非平穩的數據,消除其相關性使其變成平穩性數據。
差分后的數據為:
同時,在我們獲取了相應的平穩的數據后,要進行白噪聲檢驗。
下面是獲取差分后的數據值,然后與運用Python進行運算。
最終,獲取一階差分后的數據:SS73210_1
3 白噪聲檢驗
獲取了差分后的數據SS73210_1后,運用Python進行白噪聲檢驗,要進行白噪聲檢驗的目的:檢驗圍繞某一條線上下波動的時間序列數據是不是隨機上下波動的。
(白噪聲數據:隨機數據,Sig>0.05,則是白噪聲序列,則歷史的數據不能對未來進行預測和推斷,及殘差的ACF在置信區間內,可以認為等於0,過去的數據影響到今日的數據的這部分數據,這份信息已經被這個模型給提取出來了。)
接下來就是運用Python進行對序列的白噪聲判斷:
'''
1.實現一階差分的白噪聲數據的判斷
'''
import pandas as pd
from statsmodels.stats.diagnostic import acorr_ljungbox as lb
path = 'D:/Python/Python_learning/HBUT/預處理/ARIMA.xlsx'
df1 = pd.read_excel(path)
p_value = lb(df1, lags= 1)
print('白噪聲檢驗p值:', p_value)
檢驗結果:
白噪聲檢驗p值: (array([28.53145736]), array([9.21884666e-08])
結果分析:原假設為數據是白噪聲的數據,由於模型檢驗的p值為9.21884666e-08小於0.05,為小概率事件,認為原假設成立不是白噪聲數據。所以需要運用ARIMA模型進行重新定階。
4 重新定階
ARIMA模型的定階有兩個參數p,q,一般可以通過具體的自相關,偏相關圖的截尾來確定階數,這里使用SPSS的操作進行自己定階,然后通過顯著性sig參數來判斷模型定階后的參數是夠可靠。
1:這里有SPSS自動的操作:“專家建模器”
2 :也可以通過方法 “ARIMA模型” 進行自定義參數p,d,q的階數。
我這里選擇的模型的參數p,d,q都為1,也就是進行一階差分,p(自回歸項數)與q(滑動平均項數)都為1。
下面是使用了上面的模型后的模型結果:
從圖像可以看出運用了ARIMA模型(1,1,1)后,顯著性為0.135是大於0.05,認為此模型的數據為白噪聲的數據,也就是說,過去的數據影響到今日的數據的這部分數據,這份信息已經被這個模型給提取出來了。
再通過殘差ACF與殘差PACF也是用來看相關性,如果大部分的數據是處於兩條線之間的,說明之間的數據是弱相關,幾乎沒有什么相關性,影響程度的信息已經被提取了。
PS:編寫Python,進行參數定階
'''
#相對最優模型(p,q)
data_ = data_.astype(float) #銷量轉為float類型
#定階
pmax = int(len(D_data)/30) #一般階數不超過length/10
qmax = int(len(D_data)/30) #一般階數不超過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) #從中可以找出最小值
p, q = bic_matrix.stack().idxmin() #先用stack展平,然后用idxmin找出最小值位置。
print(u'BIC最小的p值和q值為:%s、%s' %(p, q))
'''
5 預測
在選好了參數后,我們需要運用模型進行后來5天的銷量進行預測。
這里運用Python進行預測:
# 選取好p,q后進行ARIMA預測
model = ARIMA(data_, (p,1,q) ).fit() # 建立ARIMA(1, 1, 1)模型
model.summary2() # 給出一份模型報告
r = model.forecast(5) # 做出未來五天的預測結果
pro_r = r[0]
預測結果:
做出未來五天的預測結果:
[ 9.49325086 9.25931922 10.35808756 8.96617407 9.23941594]
我這里也加上了完整的ARIMA算法的Python的代碼:
# -*- coding: utf-8 -*-
# @Time : 2020/4/3 22:50
'''
1.運用模型:ARIMA
'''
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns #seaborn畫出的圖更好看,且代碼更簡單,缺點是可塑性差
from statsmodels.graphics.tsaplots import plot_acf #自相關圖
from statsmodels.tsa.stattools import adfuller as ADF #平穩性檢測
from statsmodels.graphics.tsaplots import plot_pacf #偏自相關圖
from statsmodels.stats.diagnostic import acorr_ljungbox #白噪聲檢驗
from statsmodels.tsa.arima_model import ARIMA #引入ARIMA模型
#seaborn 是建立在matplotlib之上的
#文件的導入,和data的選取。
inputfile = 'D:/Python/Python_learning/HBUT/model_3/test_four.xlsx'
data = pd.read_excel(inputfile ,sheet_name= 'Sheet2', index_col = '日期')
print(data.head())
print(data[-5:])鄭州好的婦科醫院 http://www.zzkedayy.com/
data_1 = data['SS81346']; data_2 = data['SS81004']
data_3 = data['SS73210']; data_4 = data['SS81516']; data_5 = data['SS81376']
data_ = data_5
#seaborn設置背景
sns.set(color_codes=True)
plt.rcParams['font.sans-serif'] = ['SimHei'] #用來正常顯示中文標簽
plt.rcParams['axes.unicode_minus'] = False #用來正常顯示負號
plt.rcParams['figure.figsize'] = (8, 5) #設置輸出圖片大小
#自相關圖
#自相關圖顯示自相關系數長期大於零,說明時間序列有很強的相關性
f = plt.figure(facecolor='white')
ax1 = f.add_subplot(1, 1, 1)
data_drop = data_.dropna() #將數據data dropna()
plot_acf(data_drop, lags=31, ax=ax1)
#平穩性檢查
print(u'原始序列的ADF檢驗結果為:')
print(ADF(data_)) #通過導入的ADF模塊返回銷量的平穩性檢查
#單位根統計量對應的p的值顯著大於0.05,最終判斷該序列是非平穩序列
#1階差分后的時序圖
f = plt.figure(facecolor='white')
ax2 = f.add_subplot(1, 1, 1)
D_data = data_.diff().dropna() #1階差分,丟棄na值
D_data.plot(ax = ax2)
print(u'一階差分序列的ADF檢驗結果為:')
print(ADF(D_data))
#輸出p值遠小於0.05,所以1階差分之后是平穩非白噪聲序列
#繪制一階差分前后的圖像
f = plt.figure(facecolor='white')
ax3 = f.add_subplot(2, 1, 1)
plot_acf(D_data, lags=31, ax=ax3) #自相關
ax4 = f.add_subplot(2, 1, 2)
plot_pacf(D_data, lags=31, ax=ax4) #偏相關
p = 1
q = 1
#選取好p,q后進行ARIMA預測
model = ARIMA(data_, (p,1,q) ).fit() #建立ARIMA(1, 1, 1)模型
model.summary2() #給出一份模型報告
r = model.forecast(5) #做出未來五天的預測結果
pro_r = r[0]
print('做出未來五天的預測結果:')
print(pro_r)
#添加預測值到圖像上
pre_data = pd.Series(pro_r, index=['2019/03/13', '2019/03/14', '2019/03/15', '2019/03/16', '2019/03/17'], name='SS81346')
pre_data.index.name = '日期'
#繪圖
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.plot(data_, 'k', label='one')
ax.plot(pre_data,'r', label='two')
ax.set_title('商品: SS81376')
ax.set_xlabel('日期')
ax.set_ylabel('銷量')
ax.set_xticks(['2018/09/01', '2018/10/01', '2018/11/01',
'2018/12/01', '2019/01/01', '2019/02/01', '2019/02/28', '2019/03/18'])
plt.show()
得出圖像
從圖像可以看出,黑色部分的數據是原有的數據,紅色的數據為銷量預測的數據,可以看出預測的后5天的數據具有很好的效果,也能夠很好的反映模型的預測能力。