[Data Science]時間序列分析初探(2)

Young Chen
宅男雜誌
Published in
6 min readDec 22, 2018

前言

前一篇對資料有初步的理解,畫了折線圖觀察乘客量的變化,接下來會使用不同的預測模型對資料做預測,並且比較誤差。

資料建模與分析

Naive Method(天真預測法)

簡單來說,就是拿前一期的數值當作下一期的預測值。閱讀時我想不通這方法為何可以說嘴,後來想通了:如果考慮很多因素的方法也沒有比這個幾乎亂猜不用思考的方法好,那值得嗎?有種當作比較基準,看誰做了一堆還是褲子沒穿的比較基準。

dd = np.asarray(train.Count)
y_hat = test.copy()
y_hat['naive'] = dd[len(dd)-1]
plt.figure(figsize=(12,8))
plt.plot(train.index, train['Count'], label='Train')
plt.plot(test.index, test['Count'], label='Test')
plt.plot(y_hat.index, y_hat['naive'], label='Naive Forecast')
plt.legend(loc='best')
plt.title("Naive Forecast")
plt.show()
Navie Forecast

Naive Method誤差評估

參考文章中誤差評估用RMSE當指標,下面利用sklearn模組中計算來衡量誤差:

from sklearn.metrics import mean_squared_error
from math import sqrt
rms = sqrt(mean_squared_error(test.Count, y_hat.naive))
#rms = 43.91640614391676

最後該指標會當作衡量好壞的方法,如之前說明,天真預測法其中一個重要的意義是當作基準線,如果沒有比這個方法好,似乎再高深的演算法都不太需要考慮。

移動平均法(Moving Average)

移動平均法是利用前n期的平均數值當作下一期的預測值,方法很直覺。Ft=(At-1+At-2+At-3+…+At-n)/n,其中:

  • Ft — 對下一期的預測值;
  • n — 移動平均的時期個數;
  • At-1 — 前期實際值;
  • At-2, At-3和At-n分別表示前兩期、前三期直至前n期的實際值

加大n值平滑效果好,但是副作用會是不夠敏感。n的大小決定反應的敏感程度,常見生活中的範例就是股票的MA線,5MA, 30MA…觀察線圖的話也就會發現反應股價波動程度會明顯的因為天數而有顯著差異。以下是範例程式碼:

#this is sample program from articley_hat_avg = test.copy()
y_hat_avg['moving_avg_forecast'] = train['Count'].rolling(60).mean().iloc[-1]
plt.figure(figsize=(16,8))
plt.plot(train['Count'], label='Train')
plt.plot(test['Count'], label='Test')
plt.plot(y_hat_avg['moving_avg_forecast'], label='Moving Average Forecast')
plt.legend(loc='best')
plt.show()

這裡要分享一下我覺得非常奇怪的地方。移動平均應該是要隨時間有移動的,程式碼似乎只有把rolling mean 最後一個點的數值記錄下來並且直接繪圖,因此是一條平穩直線,這不太合理。經過一番研究,我的理解是:由於公式定義是需要上n期的實際值推算n+1期的預測值,而當預測到了n+2期,前面的數據其中一個點已經是預測值(非實際值),因此變成這樣描述預測2013–11月的所有資料。有此可知,其實模型對於後面數期是沒有辦法滾動推算的。

Moving Average誤差評估

rms = sqrt(mean_squared_error(test.Count, y_hat_avg.moving_avg_forecast))
print(rms)
#rms = 44.242070132183656

效果居然比天真預測法還差…

指數平滑法(Exponential Smoothing

概念是時間序列的態勢具有穩定性或規則性,所以時間序列可被合理地順勢推延;最近的過去態勢,在某種程度上會持續到最近的未來,所以將較大的權數放在最近的資料。更多細節可以參考這裡,更生動的例子可以參考這裡。實際計算時僅需要兩個數值與常數就能夠預測下一期數值,因此對於資料不夠完整的情境帶來方便。

from statsmodels.tsa.api import ExponentialSmoothing, SimpleExpSmoothing, Holt
y_hat_avg = test.copy()
fit2 = SimpleExpSmoothing(np.asarray(train['Count']))
.fit(smoothing_level=0.6, optimized=False)
y_hat_avg['SES'] = fit2.forecast(len(test))
plt.figure(figsize=(16,8))
plt.plot(train['Count'], label='Train')
plt.plot(test['Count'], label='Test')
plt.plot(y_hat_avg['SES'], label='SES')
plt.legend(loc='best')
plt.show()

有相關的統計模組可以直接利用,使用的模式大約是用training set 配適後,再用模型預測數值。其中smoothing level 參數應為公式中alpha值。如移動平均法,由於假設的關係沒辦法連續遞移預測,所以一樣的很怪看起來一條直線。

rms = sqrt(mean_squared_error(test.Count, y_hat_avg.SES))
print(rms)
#rms = 43.357625225228155

誤差方面也只比移動平均好那麼一點點。接下來要介紹的大概都是很難用好理解方式說明的模型,只能盡力理解跟了解應該配置什麼參數,留待第三篇。

--

--

Young Chen
宅男雜誌

曾經是全端工程師,目前在資料科學團隊中主要負責雲端架構相關工作,透過自學正在資料科學領域相關知識耕耘中。mail: chiyoung0307@gmail.com