上篇文章簡單提到了應該用平穩時間序列作預測,本文將介紹具體概念和緣由。python
平穩序列有三個基本標準:git
一、序列的均值(mean)不該該是時間的函數(意思是不該該隨時間變化),而應該是一個常數。下面的左圖知足這個條件,而右圖的均值受時間的變化影響。
github
二、序列的方差(variance)不該該是時間的函數。這種特性稱爲homoscedasticity(同方差性)。下圖描繪了平穩序列和非平穩序列,注意右圖分佈的不一樣變化範圍。
dom
三、t時間段的序列和前一個時間段的序列的協方差(協方差,衡量的是兩個變量在一段時間內同向變化的程度)應該只和時間間隔有關,而與時間t無關,在時間序列中,由於是同一個變量在不一樣時間段的值序列,因此這裏的協方差稱爲自協方差。右圖隨着時間的增長,有一段變得愈來愈緊密了。因此右圖的序列的協方差不是常數。
函數
帶有趨勢和季節性成分的時間序列都是非平穩的,下圖給出了更多的區分平穩性的例子:
測試
大多數的統計預測方法都是以平穩時間序列爲假設前提來設計的。
好比,對於時間序列自迴歸預測來講,咱們的假設是變量的歷史和現狀呈現出的基本特性,在將來階段的一個長時期裏會維持不變,而這裏的基本特性通常就是用上面提到的均值、方差、自協方差來表示。
更具體的說,自迴歸預測模型本質是'利用序列的滯後階數(lags)做爲自變量'的線性迴歸模型,好比lags=2表示使用變量的t-1和t-2時刻的值做爲自變量來預測t時刻的值。那麼經過在歷史序列上訓練模型後,獲得的這個線性迴歸模型的各自變量的係數就表明了各滯後時刻的值與下一時刻值的相關性,若是時間序列接近平穩,這些相關性在將來一段時間內都不會有大的變化,那麼預測將來就成爲了可能。
因此,相對非平穩序列的預測,平穩序列的預測更簡單和可靠。設計
對於非平穩時間序列的預測,咱們須要先將其轉換爲平穩時間序列,方法包括:code
- 差分(一階或n階)
- 取log
- 開根號
- 時間序列分解
- 綜合使用上面的方法
通常來講,作個一階差分,就能夠獲得接近平穩的時間序列了,若是方差隨時間變化較大,那麼先取log再作一階差分就能夠了。blog
好比有一個序列:[1,5,2,12,20]
一階差分,獲得:[5-1, 2-5, 12-2, 20-12] = [4, -3, 10, 8]
二階差分(即在一階差分以後,再作一次差分),獲得:[-3-4, -10-3, 8-10] = [-7, -13, -2]ip
對於判斷時間序列是否平穩,能夠經過肉眼觀測時間序列圖,就相似上面提到的平穩性的3個基本標準,或者
將時間序列分紅多個連續的部分,計算各部分的均值、方差和自相關性(或協方差),若是結果相差很大,那麼序列就不平穩。可是這些方法都不能量化平穩性,也就是用一個數值來表示出時間序列的平穩性。爲此,咱們可使用‘Unit Root Tests’即單位根檢驗,該方法的思想是若是時間序列有單位根,則就是非平穩的。
如下是經常使用的兩個基於單位根檢驗思想的實現:
- Augmented Dickey Fuller test (ADF Test)
零假設爲序列有單位根,是非平穩的,P-Value若是小於顯著級別(0.05),則能夠拒絕零假設。- Kwiatkowski-Phillips-Schmidt-Shin – KPSS test (trend stationary)
與ADF正好相反,零假設爲序列是平穩的。另外,在python中,能夠經過指定regression='ct'參數來讓kps把「肯定性趨勢(deterministic trend)」的序列認爲是平穩的。所謂肯定性趨勢的序列就是斜率始終保持不變的序列,好比下面這樣的:
下面是對應的python代碼:
from statsmodels.tsa.stattools import adfuller, kpss df = pd.read_csv('https://raw.githubusercontent.com/selva86/datasets/master/a10.csv', parse_dates=['date']) # ADF Test result = adfuller(df.value.values, autolag='AIC') print(f'ADF Statistic: {result[0]}') print(f'p-value: {result[1]}') for key, value in result[4].items(): print('Critial Values:') print(f' {key}, {value}') # KPSS Test result = kpss(df.value.values, regression='c') print('\nKPSS Statistic: %f' % result[0]) print('p-value: %f' % result[1]) for key, value in result[3].items(): print('Critial Values:') print(f' {key}, {value}')
輸出:
ADF Statistic: 3.14518568930674 p-value: 1.0 Critial Values: 1%, -3.465620397124192 Critial Values: 5%, -2.8770397560752436 Critial Values: 10%, -2.5750324547306476 KPSS Statistic: 1.313675 p-value: 0.010000 Critial Values: 10%, 0.347 Critial Values: 5%, 0.463 Critial Values: 2.5%, 0.574 Critial Values: 1%, 0.739
白噪聲的遵循均值爲0的隨機分佈,沒有絲毫的模式可言。用python製造一個白噪聲序列,並可視化以下:
randvals = np.random.randn(1000) pd.Series(randvals).plot(title='Random White Noise', color='k')
- 減去最佳擬合線
- 減去均值線,或者移動平均線
- 減去/除以 利用時間序列分解出的趨勢序列
- 季節性窗口內的移動平均法,平滑季節性
- 季節性差分,就是用當前值減去一個季節窗口以前對應的時刻的值
- 減去/除以 利用時間序列分解出的季節性序列
- 經過肉眼看圖
- 經過自相關函數判斷
from pandas.plotting import autocorrelation_plot df = pd.read_csv('https://raw.githubusercontent.com/selva86/datasets/master/a10.csv') # Draw Plot plt.rcParams.update({'figure.figsize':(9,5), 'figure.dpi':120}) autocorrelation_plot(df.value.tolist())
- 經過時間序列分解出的季節性序列來計算,其思想是越沒有季節性,那麼Rt的方差和Rt+St的方差越應該區別不大,反之,這個方差的比值越應該小於1,公式以下:
Fs越接近0,越沒有季節性,越接近1,季節性越強。
ok,本篇就這麼多內容啦~,感謝閱讀O(∩_∩)O。