本文所要介紹的主要是時間序列預測模型 Theta(以下通稱「Theta」為該模型的方法論本身),以及 Python 程式語言的統計分析工具 statsmodels 當中所呈現的 ThetaModel (以下通稱「ThetaModel」為 statsmodels 當中實作 Theta 模型的程式物件)。模型的名稱 Theta 指的就是希臘字母 θ。由於相關內容繁多,筆者將分成兩篇文章來介紹 Theta。
# Why Theta?
時間序列的預測模型百百款,為什麼要專門挑 Theta 來介紹?起初,我是由於工作的因素,要找個能夠用於需求預測建模的基礎方法,才因此意外認識了這個模型。而當我在網路上尋找的相關參考資料,幾乎找不到中文(無論繁體或簡體)的參考資源。但由於該模型的理論設計有很好的可解釋性、運算流程簡單快速,所以才決定,自己來寫一篇關於 Theta 模型的中文介紹文章。
# ThetaModel 的特色?
粗暴地來說,ThetaModel 其實就是用一條近似於原始資料配適出來的簡單線性迴歸直線、以及一條水平直線,劃定預測值可能的發生範圍(可以用兩條線之夾角的概念來理解),而ThetaModel 的預測值則是根據使用者給定的權重參數 theta,來決定預測結果的發散方向。實際上,ThetaModel 當然不是只有表面上看起來這麼簡單而已。statsmodels 採用了以下三篇 Theta 的論文來構成其 ThetaModel,並以下方截圖所示的公式,來產生其預測值。
- Assimakopoulos, V., & Nikolopoulos, K. (2000). The theta model: a decomposition approach to forecasting. International Journal of Forecasting, 16(4), 521-530.
- Hyndman, R. J., & Billah, B. (2001). Unmasking the Theta method. International Journal of Forecasting, 19(2), 287-290.
- Fioruci, J. A., Pellegrini, T. R., Louzada, F., & Petropoulos, F. (2015). The optimized theta method. arXiv preprint arXiv:1503.03529.
上述提到的那條「近似於原始資料配適出來的簡單線性迴歸直線」,就是以第一篇論文所提出來的原始 Theta 模型,在震盪係數為 0 的時候,以所配適出來的趨勢線。(「震盪係數」這個詞是筆者在這篇文章當中,為了方便讀者理解而採用的詞彙,原始論文當中是用 theta 這個單字來代表原始資料的震盪倍數,其代表的意涵是 curvatures,意思是「曲率」)。
而另一條水平線,則是參照第二篇論文的構想,以一條水平線作為第一篇論文的原始模型的緩衝,以避免在中長期的預測應用時,只單獨使用第一篇論文的原始模型的情況下,其預測結果可能會過度向上或向下發散的情況。而實際上,這條水平線在 ThetaModel 的預測值的構成成份當中,是做為一個截距項的存在。根據第二篇論文的描述,那條水平線是由簡單指數平滑法,以全段歷史資料的時間範圍作為平滑區間,下去產生出來的簡單指數平滑預測結果。
在 statsmodels 當中,簡單指數平滑項的水平線,這一段也是由他們自家的 ExponentialSmoothing 模型物件來實作的。而 ThetaModel 當中以 theta 參數決定其預測值發散方向的作法,則是參照第三篇論文,以不同的 theta 值來決定所要採用的震盪幅度權重,藉以調節歷史資料當中的震盪幅度對於未來預測結果的影響程度。透過上述的方法組合,便能夠產生出一個穩健且可解釋性高的預測結果。
# 圖解 ThetaModel
上述的所提到的概念,可以搭配下方的兩張圖來理解。上圖跟下圖使用的都是同一條需求序列資料,且都預設沒有任何的季節週期項,而差別在於,兩張圖用來作為 input data 的時間區段不同。黑色的垂直需線則做為模型 input data 與 output data 的分界線。我們可以觀察到,隨著 input data 的長度與走勢不同,模型配適後所產生出來的紫色水平線(SES)的截距高度、以及淺灰色趨勢線(Trend)的斜率也會有所不同。而黃色線段所代表的簡單線性迴歸直線(OLS),其與灰色趨勢線具有一樣的斜率,差異在其初始的截距不同。這也是為什麼要強調,ThetaModel 所採用的趨勢線,雖然跟看起來與簡單線性迴歸直線很像,但還是不一樣的點。
而我們也可以觀察到四條不同 theta 參數所帶出來的預測結果(Future 線),隨著 theta 數字越大(圖片當中的紅色 Future 線的 L = 9,999,999),其預測結果與模型配適之後的灰色趨勢線基本上會趨近於一致;而當 theta = 0 的時候,根據前述的截圖公式,預測結果就會等於那條紫色的簡單指數平滑水平線。其中,theta 必須 >= 0。而需特別留意的是,當我們在配適模型的時候,並不需要去設定 theta 參數。theta 參數是只有在模型配適好之後,決定我們要如何調配淺灰色趨勢線以及紫色水平線的採用權重,在最終預測結果當中的分配比例使用的。也就是說,圖片當中的四條 Future 線,都是根據同一個配適好的ThetaModel 所產生出來的淺灰色趨勢線以及紫色水平線,依照不同的 theta 參數混合出來的結果。
此外,要特別提到的是,ThetaModel 並沒有專門用於產生歷史模擬值的函數。現有的 forecast 函數所產生出來的是在給定的theta 參數下的預測值(theta);forecast_components 函數所產生出來的是構成 forecast 預測結果的趨勢項與指數平滑項的數值成份。同理,forecast_components 函數所呼叫出來的趨勢項與指數平滑項的數值,一樣是只針對未來期數的部份。而下圖當中的 input data 的那個時間區段之所以還看到趨勢項與指數平滑項的數值,是筆者依照上方截圖的公式,從第一期的未來值開始推算回去的。而水平的指數平滑項,則是方便讀者理解對照,才在 input data 的時間區段當中也填上去的。
# ThetaModel 的參數調整
既然 theta 這項參數的功能,都只是用於模型配適好之後的預測結果權重調配,那難道在模型配適之前,沒有任何參數可以由使用者來調整的嗎?當然還是有的。根據 ThetaModel 官方頁面說明,其配適與預測流程如下:
- Test for seasonality
- Deseasonalize if seasonality detected
- Estimate α by fitting a SES model to the data and b0 by OLS.
- Forecast the series
- Reseasonalize if the data was deseasonalized.
根據上述步驟,在估計趨勢項以及指數平滑項之前,模型就會先根據資料以及使用者的設定,會先對原始資料進行 ACF 檢定 ,確認當中是否包含週期項的特徵。如果有,則會先使用 classical time series decomposition 方法,將週期項從原始資料當中剔除之後,才進行趨勢項的運算。並在產生預測值的那個步驟,將先前拆離出來的週期項成份給掛回去。除此之外,也有對應的參數能夠設定週期項的類型(總共有 {auto, additive, multiplicative} 三種);以及週期的長度。這部份的模型設計其實與 ThetaModel 所參考的 2000 的基礎論文當中相呼應。
而除了週期項拆解的相關參數。在 ThetaModel 的 fit 函數當中有一個名為 use_mle 的二元參數,意思為是否使用「最大概似估計法」(Maximum Likelihood Estimation,MLE)去估計上述配適流程的 α 與 b0 參數,預設值為 False。而該參數需要否設定為 True,筆者建議,可根據歷史資料的樣貌、實際業務情境、與模型預測成效來判定。而這裡就不詳述以上參數的設定細節,有興趣的讀者自行參考 ThetaModel 官方的 source code 頁面。
關於 ThetaModel 的簡單介紹就到這裡為止。下篇文章,筆者將為各位進一步介紹 Theta 的理論本身,以及另一項基於 Python 的 Theta 模型實作工具。
文章開頭的圖片來源:https://www.statsmodels.org/dev/examples/notebooks/generated/theta-model.html