時間序列分析之ARIMA預測

預備知識
時間序列分析原理
時間序列分析之a(chǎn)uto_arima自動調參

一、定義

ARIMA模型(Autoregressive Integrated Moving Average model),差分整合移動平均自回歸模型,又稱整合移動平均自回歸模型,時間序列預測分析方法之一。
ARIMA(p,d,q) = \begin{cases} AR(p), & \text{p階自回歸} \\ MA(q), & \text{q階滑動平均} \\ d,& \text{平穩(wěn)時的差分階數(shù)} \\ \end{cases}

ARIMA(p,d,q)中,
AR是"自回歸",p為自回歸項數(shù);
MA為"滑動平均",q為滑動平均項數(shù),d為使之成為平穩(wěn)序列所做的差分次數(shù)(階數(shù))。

"差分"一詞雖未出現(xiàn)在ARIMA的英文名稱中,卻是關鍵步驟。

1.1 AR模型(自回歸)

描述當前值與歷史值之間的關系,用變量自身的歷史時間數(shù)據(jù)對自身進行預測,數(shù)學模型表達式如下:
y_t = \mu + \sum\limits_{i=1}^{p}r_t y_{t-1} + \epsilon_t

其中是y_t當前值,\mu是常數(shù)項,p是階數(shù),r是自相關系數(shù),?_t是誤差,同時?_t要符合正態(tài)分布
該模型反映了在t時刻的目標值值與前t-1~p個目標值之前存在著一個線性關系

自回歸模型的限制:
自回歸模型是用自身的數(shù)據(jù)來進行預測
必須具有平穩(wěn)性
必須具有自相關性,如果自相關系數(shù)(φ_i)小于0.5,則不宜采用
自回歸只適用于預測與自身前期相關的現(xiàn)象

1.2 MA模型(移動平均)

移動平均模型關注的是自回歸模型中的誤差項的累加,數(shù)學模型表達式如下:
y_t = \mu + \epsilon_t + \sum\limits_{i=1}^{q}\theta_i \epsilon_{t-i}

該模型反映了在t時刻的目標值值與前t-1~p個誤差值之前存在著一個線性關系

移動平均法能有效地消除預測中的隨機波動

1.3 ARMA模型(自回歸移動平均)

ARIMA(p,d,q)模型全稱為差分自回歸移動平均模型(Autoregressive Integrated Moving Average Model,簡記ARIMA)

該模型描述的是自回歸與移動平均的結合,具體數(shù)學模型如下:
y_t = \mu + \sum\limits_{i=1}^{p}r_t y_{t-1} + \epsilon_t + \sum\limits_{i=1}^{q}\theta_i \epsilon_{t-i}

基本原理:將數(shù)據(jù)通過差分轉化為平穩(wěn)數(shù)據(jù),再將因變量僅對它的滯后值以及隨機誤差項的現(xiàn)值和滯后值進行回歸所建立的模型。

1.4 自相關函數(shù)ACF(autocorrelation function)

有序的隨機變量序列與其自身相比較

自相關函數(shù)反映了同一序列在不同時序的取值之間的相關性

ACF(k) = \sum\limits_{t=k+1}^n \frac{(Z_t-\overline Z)(Z_{t-k}-\overline Z)}{\sum\limits_{t=1}^n(Z_t-\overline Z)^2}
取值范圍為[-1,1]

自相關系數(shù)度量的是同一事件在兩個不同時期之間的相關程度,形象的講就是度量自己過
去的行為對自己現(xiàn)在的影響。在這里可以通過自相關系數(shù)(ACF)圖的最大滯后點來大致判斷q 值。

1.5 偏自相關系數(shù)(PACF)(partial autocorrelation function)

PACF(k) = \frac{E(Z_t - E Z_t)(Z_{t-k} - E Z_{t-k})}{\sqrt {E(Z_t - E Z_t)^2\sqrt{E(Z_{t-k} - E Z_{t-k})^2}}} = \frac{cov[(Z_t - \overline Z_t)(Z_{t-k} - \overline Z_{t-k})]}{\sqrt {var(Z_t - \overline Z_t)\sqrt{E(Z_{t-k} - \overline Z_{t-k})}}}

計算某一個要素對另一個要素的影響或相關程度時,把其他要素的影響視為常數(shù),即暫不考慮其他要素的影響,而單獨研究那兩個要素之間的相互關系的密切程度時,稱為偏相關

對于一個平穩(wěn)AR(p)模型,求出滯后k自相關系數(shù)p(k)時實際上得到并不是x(t)與x(t-k)之間單純的相關關系x(t)同時還會受到中間k-1個隨機變量x(t-1)、x(t-2)、……、x(t-k+1)的影響,而這k-1個隨機變量又都和x(t-k)具有相關關系,所以自相關系數(shù)p(k)里實際摻雜了其他變量對x(t)與x(t-k)的影響,剔除了中間k-1個隨機變量x(t-1)、x(t-2)、……、x(t-k+1)的干擾之后x(t-k)對x(t)影響的相關程度。ACF還包含了其他變量的影響而偏自相關系數(shù)
PACF是嚴格這兩個變量之間的相關性

1.6 拖尾與截尾

拖尾:始終有非零取值,不會在k大于某個常數(shù)后就恒等于零(或在0附近隨機波動)
截尾:在大于某個常數(shù)k后快速趨于0為k階截尾

拖尾與截尾

1.7 定階

模型 ACF PACF
AR(p) 衰減趨于0(幾何型或振蕩型) p階后截尾
MA (q) q階后截尾 衰減趨于0(幾何型或振蕩型)
ARMA(p,q) q階后衰減趨于0(幾何型或振蕩型) p階后衰減趨于0(幾何型或振蕩型)

截尾:落在置信區(qū)間內(nèi)(95%的點都符合該規(guī)則)

因為AR(自回歸)建立必須具有平穩(wěn)性,所以在建立ARIMA模型也需要平穩(wěn)性,使數(shù)據(jù)平穩(wěn)性的方法可以講數(shù)據(jù)進行差分處理,如一階差分即t與t-1的差值,二階差分為一階差分基礎上再進行一次差分,使數(shù)據(jù)平穩(wěn)后的差分次數(shù)即為我們要定的參數(shù)d。

若PACFp階段后截尾,則截尾的階數(shù)即為模型所確定的參數(shù)p。
若ACFq階段后截尾,則截尾的階數(shù)即為模型所確定的參數(shù)q。

1.8 建模流程

將序列平穩(wěn)(差分法確定d)

p和q階數(shù)確定:ACF與PACF

ARIMA(p,d,q)


在這里插入圖片描述

二、Python建模

2.1 導入相關的包

%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 statsmodels.api as sm
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
from statsmodels.tsa.stattools import adfuller
import numpy as np
style.use('ggplot')    
plt.rcParams['font.sans-serif'] = ['SimHei'] 
plt.rcParams['axes.unicode_minus'] = False  

import statsmodels
statsmodels.__version__
#'0.13.5'

import warnings
warnings.filterwarnings("ignore")

2.2 導入數(shù)據(jù)

我們使用一個股票的樣例數(shù)據(jù)進行分析

stock = pd.read_csv('T10yr.csv', index_col=0, parse_dates=[0])
stock
Date Open High Low Close Volume Adj Close
2000-01-03 6.498 6.603 6.498 6.548 0 6.548
2000-01-04 6.530 6.548 6.485 6.485 0 6.485
2000-01-05 6.521 6.599 6.508 6.599 0 6.599
2000-01-06 6.558 6.585 6.540 6.549 0 6.549
2000-01-07 6.545 6.595 6.504 6.504 0 6.504
... ... ... ... ... ... ...
2016-07-25 1.584 1.584 1.554 1.571 0 1.571
2016-07-26 1.559 1.587 1.549 1.563 0 1.563
2016-07-27 1.570 1.570 1.511 1.515 0 1.515
2016-07-28 1.525 1.535 1.493 1.511 0 1.511
2016-07-29 1.525 1.530 1.458 1.458 0 1.458

4167 rows × 6 columns

#數(shù)據(jù)選取
stock_week = stock['Close'].resample('W-MON').mean()
stock_train = stock_week['2000':'2015']

Date
2000-01-03    6.54800
2000-01-10    6.53900
2000-01-17    6.66300
2000-01-24    6.73720
2000-01-31    6.67280
               ...   
2015-11-30    2.22950
2015-12-07    2.23260
2015-12-14    2.20980
2015-12-21    2.23780
2015-12-28    2.24275
Freq: W-MON, Name: Close, Length: 835, dtype: float64

2.3 數(shù)據(jù)查看

stock_train.plot(figsize=(12,6))
plt.legend(bbox_to_anchor=(1.25, 0.5))
plt.title("Stock Close")
sns.despine()
在這里插入圖片描述

從數(shù)據(jù)走勢上我們大概可以看出,是有下降的趨勢的,我們用單位根來檢驗一下,為了方便我們寫一個函數(shù)直接輸出相關的數(shù)據(jù)和圖

def test_stationarity(timeseries):
    
    #滑動均值和方差
    rolmean = timeseries.rolling(1).mean()
    rolstd = timeseries.rolling(1).std()

    #繪制滑動統(tǒng)計量
    plt.figure(figsize=(24, 8))   
    orig = plt.plot(timeseries, color='blue',label='data')
    
    plt.legend(loc='best')
    plt.title('數(shù)據(jù)展示')
    plt.show(block=False)
    
    #adf檢驗
    print('Results of Dickey-Fuller Test:')
    dftest = adfuller(timeseries, autolag='AIC')
    dfoutput = pd.Series(dftest[0:4], index=['Test Statistic','p-value','#Lags Used',
                                             'Number of Observations Used'])
    for key,value in dftest[4].items():
        dfoutput['Critical Value (%s)'%key] = value
    print(dfoutput)
test_stationarity(stock_train)
在這里插入圖片描述

Results of Dickey-Fuller Test:
Test Statistic -2.196095
p-value 0.207666

Lags Used 1.000000

Number of Observations Used 833.000000
Critical Value (1%) -3.438225
Critical Value (5%) -2.865016
Critical Value (10%) -2.568621
dtype: float64

P值為0.207666> 0.05,所以數(shù)據(jù)存在單位根

2.4 差分

根據(jù)上面說的,當存在單位根,即數(shù)據(jù)不平穩(wěn)時需要進行差分處理。

stock_diff = stock_train.diff()
stock_diff = stock_diff.dropna()
test_stationarity(stock_diff)

直接套用上面定義的函數(shù)進行查看


在這里插入圖片描述

Results of Dickey-Fuller Test:
Test Statistic -23.506019
p-value 0.000000

Lags Used 0.000000

Number of Observations Used 833.000000
Critical Value (1%) -3.438225
Critical Value (5%) -2.865016
Critical Value (10%) -2.568621
dtype: float64

p-value=0.000000 ,明顯是小于0.05的,所以可以拒絕存在單位根,序列已經(jīng)平穩(wěn)

2.5 ACF和PACF

acf = plot_acf(stock_diff, lags=20)
plt.title("ACF")
acf.show()

pacf = plot_pacf(stock_diff, lags=20)
plt.title("PACF")
pacf.show()
在這里插入圖片描述

在這里插入圖片描述

我們根據(jù)ACF和PACF的圖大概可以判定p =2 ,q = 2

2.6 自動訓練定階

根據(jù)之前auto_arima介紹

from pmdarima import auto_arima

stepwise_fit = auto_arima(stock_train, 
                          start_p = 1, 
                          start_q = 1,
                          max_p = 3, 
                          max_q = 3, 
                          m = 52,
                          start_P = 0, 
                          seasonal = True,
                          d = None, 
                          D = 1, 
                          trace = True,
                          error_action ='ignore',   # we don't want to know if an order does not work
                          suppress_warnings = True,  # we don't want convergence warnings
                          stepwise = True,
                         n_jobs = -1)           # set to stepwise
  
# To print the summary
stepwise_fit.summary()

Best model: ARIMA(2,0,1)(2,1,0)[52] intercept
Total fit time: 2262.306 seconds

2.7 預測

m = 52

#Model Estimation

# Fit the model
arima2 = sm.tsa.SARIMAX(stock_train, order=(2,0,1), seasonal_order=(2,1,0,m))
model_results = arima2.fit()

#殘差分析 正態(tài)分布 QQ圖線性
model_results.plot_diagnostics(figsize=(15, 12));
在這里插入圖片描述
pred = model_results.predict(start=0,end=1000)
print (pred)

plt.figure(figsize=(24, 8))   
orig = plt.plot(stock_train, color='blue',label='Original')
predict = plt.plot(pred[m+1:], color='red',label='Predict')
plt.legend(loc='best')
plt.title('Original&Predict')
plt.show(block=False)
在這里插入圖片描述

2.8 殘差分布

ERROR_RATE=(stock_train-pred[m+1:])/stock_train
plt.figure(figsize=(12,4))   
plt.scatter(ERROR_RATE.index,ERROR_RATE,color='r')
plt.grid(True)
plt.figure(figsize=(12, 4))
plt.hist(ERROR_RATE, bins=20)
plt.grid(True)
plt.show()
在這里插入圖片描述
# Load specific evaluation tools
from sklearn.metrics import mean_squared_error
from statsmodels.tools.eval_measures import rmse
  
# Calculate root mean squared error
print(rmse(stock_train, pred[:m]))
  
# Calculate mean squared error
print(mean_squared_error(stock_train, pred[:m]))

1.5157632571102173
2.297538251605375

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容