一些時間序列處理工具包的簡單比較(待續)

  • 2021 年 6 月 1 日
  • AI

時間序列的Python工具很多,但是好用的不多,因為論文需要,調研了幾乎全部的star比較高,維護相對積極的python library,這裡給出一些簡單的總結:

需求:

1』單序列單變數(序列值本身)建模;

2 單序列多變數建模(包括序列值本身,以及其他的一些時變或者時不變變數);

3 多序列單變數建模和多序列多變數建模

多序列指數據中包含了多個獨立的序列,例如不同店鋪的不同商品都存在一個自身的時間序列數據,這也是最常見的問題形式。

關於單序列的問題,單序列問題本身的數據量往往不大,尤其是電商,即使單序列的長度很長,一般來說也就取最近一段時間的數據來進行建模,因為序列數據本身的趨勢、周期、固有值也是發生變化的,例如固有值會隨著通貨膨脹,經濟周期等因素從而發生變化(我大一那會兒門口的山東煎餅兩塊錢一個,現在最便宜的都要五塊錢了),趨勢(比如股票指數,很明顯其上升、下降和平穩變化的趨勢差異是很大的),周期(520,618,11.11各種新的節日會帶來非常明顯的新周期),因此往往單序列建模不會取太過久遠的數據,除非數據是秒,分鐘級別的,如果按照3~5年來取數據(這也是我所處理過的時序問題里最常見的取法了,在kaggle上的序列比賽里甚至給定的數據集都沒有超過5年以上的),天級別(常見的數據的序列值的level),個人淺見,在一些常規的供應鏈,電商場景下,比較少有低於天級別的歷史數據存儲,高頻交易有可能存儲分鐘甚至秒級別的數據,但是這個就在討論之外了。

所以即使按照五年來測算,單序列也就5*365=1825條數據,更不用說很多商品壓根就取不到這麼長的銷量數據,一些冷門商品的銷量數據可能也就上百條,這種情況下進行機器學習或者深度學習建模的難度是很大的,樣本量實在太少了,舉個極端的例子,假設我們的序列數據是這樣的:

[1,2,3,4…..1824,1825],即使通過滑窗的方式來構建樣本,用能夠產生最多樣本的滑窗方式來構造,用過去一天預測未來一天,則樣本構造為:

[1,2]

[2,3]

[3,4]

[1824,1825]

也就1824條的數據,這點樣本我在線下測試過兩個數據集,一個是web traffic中某個網頁的流量數據,數據量接近900條,一個是kaggle的m5的比賽里某個商鋪的某個sku的序列數據,為了避免趨勢性的影響,使用的單序列基本上沒有趨勢性,進行單序列建模,測試了經濟學模型,xgboost和簡單的lstm,可以說xgb和nn的略差,放一部分結果:

這是lightgbm的預測結果,mape=1.9868239292946304

這是holtwinters的預測結果,mape=0.24162530054457074

ets,mape=0.3486683255515128

arima,mape=0.8770316409264396

tbats mape=0.47721204186604005

Prophet mape=0.30538213361067473

複合策略,對趨勢,周期分兩個模型建模,疊加最近一個周期的簡單平均,mape=0.2744438240584007

lightgbm ,mape接近2了。。(機器學習演算法這裡採用了迭代預測的方式,直接預測和混合預測的方法複雜度太高了,基本上實際應用上不會去考慮,這裡預測的是為了63天的數據,如果使用直接預測或者混合預測的方法則意味著要構建63個lightgbm模型,這種高計算複雜度基本上是不會考慮應用的)

使用線性回歸去除趨勢之後的lightgbm:

mape=0.42634482052747374

單序列的預測面臨的主要問題是小樣本問題,其實通過複雜的特徵工程構造是有可能提高機器學習或者nn模型的預測結果的,但是個人認為這樣做意義不大,nn不用說了,高參數空間,少量數據可能連收斂都不夠,而gbdt模型相對來說穩定性好一些,但是面對趨勢是沒有什麼好的解決方法的,必須通過一些簡單趨勢模型來結合lgb一起預測,並且如果周期性很明顯則最好也補充一個周期策略模型來一起預測,最後,使用nn來處理單序列預測的問題,我基本上放棄這個方向了。。。希望有人能來打我臉。


言歸正傳,下面總結一下調研的幾款感覺不錯的工具:

1、darts,darts的周期性檢測工具比較方便,核心思想是通過自相關以及顯著性檢驗來得到可靠的周期性檢驗結果,因為隨著周期長度的增加,進行自相關係數計算的數據會越來越少,樣本越小則相關係數計算的結果越不可靠,因此要引入顯著性檢驗來檢驗相關係數計算結果的可靠性,初次之外,darts的經濟學模型功能基本上sktime里有更好更統一的實現,darts的nn功能很雞肋,感覺沒有太大必要使用,darts目前只能支援單序列的問題,無法處理多序列問題,和skearn,xgb,lgb這些工具的統一性也很差;

2、sktime,個人感覺最好用的時間序列工具包,支援原生的pandas和numpy數據,和sklearn api的結合非常緊密,可以看作是sklearn在時間序列問題上的擴展,基本上除了nn之外,經濟學模型和機器學習模型的全流程建模的設計都有,很方便地進行實驗,並且其經濟學模型功能和darts基本是一致的(常用的經濟學模型也就那幾個了。。);

3、nn部分,pytorch-forecasting,pytorch-forecasting設計的timeseriesdataset可以說是非常非常的便利了,針對多序列和單序列的數據轉換,向量預測和seq2seq式迭代預測的數據構建都極其方便,並且內置了各種group 標準化,log變換等功能,因為torch和numpy本身的緊密度很高,將data loader得到的tensor直接轉化為numpy就可以很方便的將構建完的數據集用於gbdt這類模型的建模了,比較推薦。

pytorch-forecasting除了timeseriesdataset和數據的一些預處理的功能之外,其它的功能就不推薦了,模型部分維護的並不好,不同的時間序列模型介面不統一,用起來非常混亂,實際上通過timeseriesdataset的方式構建標準的適合nn的數據形式之後,模型部分可以自己用torch lightning來寫;

4、gluonts,大一統,目前還在看介紹,演算法的種類基本上是整個git上最全的了,你了解的和你不了解的模型基本都實現了,並且也有和pandas,numpy結合緊密的時間序列數據格式,api相對統一的多,文檔也比較豐富,美中不足的就是對於mxnet支援較好,對於torch也有支援(但是不知道支援到什麼程度,目前看文檔是可以支援模型構建,但是loss的計算等等不知道能不能也支援)。

所以最後的選型就是sktime和pytorch-forecasting的timeseriesdataset以及gluonts了。

pytorch-forecasting可以比較方便的測試新模型,數據處理完畢,只要把相應的模型的輸入輸出搞清楚直接forward就可以了,gluonts暫時研究的不深入,後續看完了再更新一下吧。