時間序列模型梳理

時間序列

在這裏插入圖片描述

時間序列數據

時間序列是按時間順序排列的、隨時間變化且相互關聯的數據序列。html

構成要素

時間序列能夠分爲長期趨勢(trend)、季節變更(seasonal)、循環變更(cycling)和隨機波動(irregular)四個部分。python

  • 長期趨勢( T )現象在較長時期內受某種根本性因素做用而造成的總的變更趨勢
  • 季節變更( S )現象在一年內隨着季節的變化而發生的有規律的週期性變更
  • 循環變更( C )現象以若干年爲週期所呈現出的波浪起伏形態的有規律的變更
  • 不規則變更(I )是一種無規律可循的變更,包括嚴格的隨機變更和不規則的突發性影響很大的變更兩種類型

能夠根據模型輸入變量數將其分爲兩類:算法

第一類:容許單變量輸入的時間序列統計模型【Time series statistical model】
表明算法:Holt-Winters、ARIMA、fbprophet
第二類:容許多變量輸入的時間序列監督模型【Time series supervised learning model】
表明算法:XGBoost、LSTM,convLstm,attention model

第一類時間序列統計模型

ARIMA模型

ARIMA,全稱自迴歸整合移動平均模型,(Autoregressive Integrated Moving Average Model)。api

原理

將非平穩時間序列轉化爲平穩時間序列,而後將因變量僅對它的滯後值以及隨機偏差項的現值和滯後值進行迴歸所創建的模型。數組

須知這是一個你們庭

  • 自迴歸(AR)模型;
  • 移動平均(MA)模型;
  • 自迴歸移動平均(ARMA)模型;
  • 自迴歸整合移動平均模型(ARIMA);
  • 季節性整合自迴歸移動平均模型(SARIMA)模型。

ARIMA要求輸入是平穩的時間序列

平穩性就是要求經由樣本時間序列所獲得的擬合曲線在將來的一段期間內仍能順着現有的形態「慣性」地延續下去。微信

嚴平穩與弱平穩:
  • 嚴平穩:嚴平穩表示的分佈不隨時間的改變而改變;
    如:白噪聲(正態),不管怎麼取,都是指望爲0,方差爲1
  • 弱平穩:指望與相關係數(依賴性)不變;
    將來某時刻的t的值Xt就要依賴於它的過去信息,因此須要依賴性
輸入

單變量,按照時間戳排列好的有序變量ide

輸出

將來一段時間戳序列的有序量。函數

爲啥叫自迴歸

傳統的迴歸模型,都是有自變量X和因變量Y組成的(X,Y)來作模型訓練,可是時間序列是利用自身歷史數據預測將來數據的單變量時間序列模型。用本身歷史數據預測將來就是自迴歸。測試

模型3個超參數

ARIMA(p,d,q)-p,d,q數值越大模型越複雜url

  • p–自迴歸項係數;表明預測模型中採用的時序數據自己的滯後數(lags) ,也稱AR/Auto-Regressive項
  • d–差分系數;表明時序數據須要進行幾階差分化,纔是穩定的,也叫Integrated項。
  • q–移動平均係數;表明預測模型中採用的預測偏差的滯後數(lags),也叫MA/Moving Average項

ARIMA建模過程

核心過程

1:序列白噪聲檢驗:若是序列是純隨機的就不須要在作預測了,都隨機了還預測個毛線啊,有沒有上帝之眼。這一步沒過下面工做就不要作了。。。方法:acorr_ljungbox
2:平穩性檢驗:ARIMA要求輸入的序列是平穩的,因此使用之間要檢查模型的平穩性;方法:ADF檢驗;
3:定階:p,q;方法:圖示法:PACF,ACF;統計量:AIC,BIC統計量。
4:殘差檢驗: 檢驗殘差是不是白噪聲過程。
5:預測: 利用模型預測。



白噪聲檢驗acorr_ljungbox

白噪聲檢驗也稱爲純隨機性檢驗, 當數據是純隨機數據時,再對數據進行分析就沒有任何意義了, 因此拿到數據後最好對數據進行一個純隨機性檢驗。
原假設:數據是隨機的;給定顯著性水平a:

  • 若是 p <= a, 則在顯著性水平a 下拒絕H0;

  • 若是p > a,則在顯著性水平a下接受H0

  • a一般是0.0五、0.01等。

python方法
from statsmodels.stats.diagnostic import acorr_ljungbox

acorr_ljungbox(b.salesVolume, lags = [6, 12],boxpierce=True)
  • lags爲延遲期數,若是爲整數,則是包含在內的延遲期數,若是是一個列表或數組,那麼全部時滯都包含在列表中最大的時滯中

  • boxpierce爲True時表示除開返回LB統計量還會返回Box和Pierce的Q統計量

返回值:

  • lbvalue:測試的統計量

  • pvalue:基於卡方分佈的p統計量

  • bpvalue:((optionsal), float or array) 基於 Box-Pierce 的檢驗的p統計量

  • bppvalue:((optional), float or array) 基於卡方分佈下的Box-Pierce檢驗的p統計量

平穩性檢驗-ADF檢驗

白噪聲檢驗經過,說明序列時非隨機的,能夠嘗試用來作預測;
ADF檢驗的原假設是存在單位根。注意,ADF值通常是負的,也有正的,可是它只有小於1%水平下的才能認爲是及其顯著的拒絕原假設 。

python 的ADF檢驗方法adfuller的返回值
  • Test statistic:表明檢驗統計量
  • p-value:表明p值檢驗的機率
  • Lags used:使用的滯後k,autolag=AIC時會自動選擇滯後
  • Number of Observations Used:樣本數量
  • Critical Value(5%) : 顯著性水平爲5%的臨界值。
    (1) 假設是存在單位根,即不平穩;
    (2) 顯著性水平,1%:嚴格拒絕原假設;5%:拒絕原假設,10%類推。
    (3) 看P值和顯著性水平a的大小,p值越小,小於顯著性水平的話,就拒絕原假設,認爲序列是平穩的;大於的話,不能拒絕,認爲是不平穩的
    (4) 看檢驗統計量和臨界值,檢驗統計量小於臨界值的話,就拒絕原假設,認爲序列是平穩的;大於的話,不能拒絕,認爲是不平穩的



P值和T統計量的關係

P值是t統計量對應的機率值,因此t和p二者是等效的,看p就夠了。
P值要求小於給定的顯著性水平,通常是0.0五、0.01等,p越接近於0越好;
這三個水平值內部本身設定的,它表示拒絕原假設的不一樣程度。

通常在原序列條件下,若是存在非平穩狀態,按如下步驟進行:
一階差分是否具備單位根,就是比較一屆差分的ADF檢驗值與5%臨界值的大小,不然再看二階差分的。
若是二階都不單整,就要從新處理一下數據了
ADF檢驗


3個超參數選擇方法

圖示法-PACF、ACF

python繪製的效果圖:
在這裏插入圖片描述
選擇p,q的原則:
在這裏插入圖片描述
截尾:落在置信區間內(95%的點都符合該規則)



p階自迴歸過程的公式定義:

在這裏插入圖片描述
PACF,偏自相關函數(決定p值),剔除了中間k-1個隨機變量x(t-1)、x(t-2)、……、x(t-k+1)的干擾以後x(t-k)對x(t)影響的相關程度。

q階自迴歸過程的公式定義

在這裏插入圖片描述
ACF,自相關函數(決定q值)反映了同一序列在不一樣時序取值之間的相關性。x(t)同時還會受到中間k-1個隨機變量x(t-1)、x(t-2)、……、x(t-k+1)的影響;而這k-1個隨機變量又都和x(t-k)具備相關關係,因此自相關係數p(k)裏實際摻雜了其餘變量對x(t)與x(t-k)的影響。
在這裏插入圖片描述
取值在-1到1之間。


AIC和BIC統計量

AIC和BIC選擇更簡單的模型,因此統計量的值越小越好。
AIC:赤池信息準則(AkaikeInformation Criterion,AIC)
在這裏插入圖片描述
BIC:貝葉斯信息準則(Bayesian Information Criterion,BIC)
在這裏插入圖片描述
k爲模型參數個數,n爲樣本數量,L爲似然函數;




咱們經常使用的是AIC準則,AIC鼓勵數據擬合的優良性可是儘可能避免出現過分擬合(Overfitting)的狀況。因此優先考慮的模型應是AIC值最小的那一個模型。
爲了控制計算量,咱們限制AR最大階不超過5,MA最大階不超過5。 可是這樣帶來的壞處是可能爲局部最優。
timeseries是待輸入的時間序列,是pandas.Series類型,max_ar、max_ma是p、q值的最大備選值。
order.bic_min_order返回以BIC準則肯定的階數,是一個tuple類型。


殘差檢驗

爲何要作殘差檢驗

  • 殘差(Residual)在檢查預測模型是否徹底捕捉數據中的信息時頗有用。一個好的預測方法的殘差有如下特色:
    (1)Residual之間是無相關性的:
    若是Residual之間是有相關性的,那麼殘差中還有信息能夠用到預測中。
    (2)Residual的均值爲0:
    若是Residual均值非0,那麼預測存在誤差(bias)。



不知足上述兩條的預測模型均可以改進來提高效果。固然,並非意味着知足這兩條的模型不能夠改進。

ARIMA的優缺點

  • 優勢: 模型十分簡單,只須要內生變量而不須要藉助其餘外生變量。

  • 缺點:
    1.要求時序數據是穩定的(stationary),或者是經過差分化(differencing)後是穩定的。
    2.本質上只能捕捉線性關係,而不能捕捉非線性關係。
    注意,採用ARIMA模型預測時序數據,必須是穩定的,若是不穩定的數據,是沒法捕捉到規律的。好比股票數據用ARIMA沒法預測的緣由就是股票數據是非穩定的,經常受政策和新聞的影響而波動。


來個代碼實戰

import sys
import os
 
import pandas as pd
import numpy as np
 
# TSA from Statsmodels
import statsmodels.api as sm
import statsmodels.formula.api as smf
import statsmodels.tsa.api as smt
 
# Display and Plotting
import matplotlib.pylab as plt
import seaborn as sns
filename_ts = 'data/sentiment.csv'
ts_df = pd.read_csv(filename_ts, index_col=0, parse_dates=[0])
 
n_sample = ts_df.shape[0]
print(ts_df.shape)
print(ts_df.head())
# Create a training sample and testing sample before analyzing the series
 
n_train=int(0.95*n_sample)+1
n_forecast=n_sample-n_train
#ts_df
ts_train = ts_df.iloc[:n_train]['value']
ts_test = ts_df.iloc[n_train:]['value']
print(ts_train.shape)
print(ts_test.shape)
print("Training Series:", "\n", ts_train.tail(), "\n")
print("Testing Series:", "\n", ts_test.head())

def tsplot(y, lags=None, title='', figsize=(14, 8)):
    
    fig = plt.figure(figsize=figsize)
    layout = (2, 2)
    ts_ax   = plt.subplot2grid(layout, (0, 0))
    hist_ax = plt.subplot2grid(layout, (0, 1))
    acf_ax  = plt.subplot2grid(layout, (1, 0))
    pacf_ax = plt.subplot2grid(layout, (1, 1))
    
    y.plot(ax=ts_ax) # 折線圖
    ts_ax.set_title(title)
    y.plot(ax=hist_ax, kind='hist', bins=25) #直方圖
    hist_ax.set_title('Histogram')
    smt.graphics.plot_acf(y, lags=lags, ax=acf_ax) # ACF自相關係數
    smt.graphics.plot_pacf(y, lags=lags, ax=pacf_ax) # 偏自相關係數
    [ax.set_xlim(0) for ax in [acf_ax, pacf_ax]]
    sns.despine()
    fig.tight_layout()
    return ts_ax, acf_ax, pacf_ax
 
tsplot(ts_train, title='A Given Training Series', lags=20);
 
# Fit the model
arima200 = sm.tsa.SARIMAX(ts_train, order=(2,0,0)) # ARIMA季節性模型,至於p,d,q須要按照下面的方法選擇
model_results = arima200.fit()

# 此處運用BIC(貝葉斯信息準則)進行模型參數選擇
# 另外還能夠利用AIC(赤池信息準則),視具體狀況而定
import itertools
 
p_min = 0
d_min = 0
q_min = 0
p_max = 4
d_max = 0
q_max = 4
# Initialize a DataFrame to store the results
results_bic = pd.DataFrame(index=['AR{}'.format(i) for i in range(p_min,p_max+1)],
                           columns=['MA{}'.format(i) for i in range(q_min,q_max+1)])
 
for p,d,q in itertools.product(range(p_min,p_max+1),
                               range(d_min,d_max+1),
                               range(q_min,q_max+1)):
    if p==0 and d==0 and q==0:
        results_bic.loc['AR{}'.format(p), 'MA{}'.format(q)] = np.nan
        continue
    
    try:
        model = sm.tsa.SARIMAX(ts_train, order=(p, d, q),
                               #enforce_stationarity=False,
                               #enforce_invertibility=False,
                              )
        results = model.fit() 此處的result包含了不少信息,具體若是用到須要本身去查詢
# http://www.statsmodels.org/stable/tsa.html
        # print("results.bic",results.bic)
        # print("results.aic",results.aic)
        
        results_bic.loc['AR{}'.format(p), 'MA{}'.format(q)] = results.bic
    except:
        continue
results_bic = results_bic[results_bic.columns].astype(float)

fig, ax = plt.subplots(figsize=(10, 8))
ax = sns.heatmap(results_bic,
                 mask=results_bic.isnull(),
                 ax=ax,
                 annot=True,
                 fmt='.2f',
                 );
ax.set_title('BIC');
//annot
//annotate的縮寫,annot默認爲False,當annot爲True時,在heatmap中每一個方格寫入數據
//annot_kws,當annot爲True時,可設置各個參數,包括大小,顏色,加粗,斜體字等
# annot_kws={'size':9,'weight':'bold', 'color':'blue'}
#具體查看:https://blog.csdn.net/m0_38103546/article/details/79935671
# Alternative model selection method, limited to only searching AR and MA parameters
 
train_results = sm.tsa.arma_order_select_ic(ts_train, ic=['aic', 'bic'], trend='nc', max_ar=4, max_ma=4)
 
print('AIC', train_results.aic_min_order)
print('BIC', train_results.bic_min_order)

#殘差分析 正態分佈 QQ圖線性
 
model_results.plot_diagnostics(figsize=(16, 12));

過程當中的顯示

  • PACF,ACF
    在這裏插入圖片描述

  • AIC,BIC熱度圖
    在這裏插入圖片描述
    AIC和BIC統計量值越小越好,熱度圖呈黑色的。

  • 殘差檢驗圖
    在這裏插入圖片描述
    QQ圖是線性的說明殘差白噪聲檢驗經過了。
    開始預測


model = ARIMA(stock_train, order=(1, 1, 1),freq='W-MON')
result = model.fit()
pred = result.predict('20140609', '20160701',dynamic=True, typ='levels')
# 此處注意,2014060必須能在訓練集數據中可以找到,後邊的20160701則不用
print (pred)
plt.figure(figsize=(6, 6))
plt.xticks(rotation=45)
plt.plot(pred)
plt.plot(stock_train)

在這裏插入圖片描述

參考資料

時間序列金融偏
fbprophet
時間序列ARIMA小栗子
ARIMA的p,d,q定階方法


須要數據集的朋友能夠關注個人微信公衆號:[Python技術博文]–私信留言我便可。

相關文章
相關標籤/搜索