集成時間序列模型提高預測精度

集成時間序列模型提高預測精度!

簡介使用Catboost從(cong) RNN、ARIMA和Prophet模型中提取信號進行預測

集成各種弱學習(xi) 器可以提高預測精度,但是如果我們(men) 的模型已經很強大了,集成學習(xi) 往往也能夠起到錦上添花的作用。流行的機器學習(xi) 庫scikit-learn提供了一個(ge) StackingRegressor,可以用於(yu) 時間序列任務。

但是StackingRegressor有一個(ge) 局限性;它隻接受其他scikit-learn模型類和api。所以像ARIMA這樣在scikit-learn中不可用的模型,或者來自深度神經網絡的模型都無法使用。在這篇文章中,我將展示如何堆疊我們(men) 能見到的模型的預測。

集成時間序列模型提高預測精度

我們(men) 將用到下麵的包:

pip install --upgrade scalecast conda install tensorflow conda install shap conda install -c conda-forge cmdstanpy pip install prophet

數據集

數據集每小時一次,分為(wei) 訓練集(700個(ge) 觀測值)和測試集(48個(ge) 觀測值)。下麵代碼是讀取數據並將其存儲(chu) 在Forecaster對象中:

import pandas as pd import numpy as np from scalecast.Forecaster import Forecaster from scalecast.util import metrics import matplotlib.pyplot as plt import seaborn as sns def read_data(idx = 'H1', cis = True, metrics = ['smape']): info = pd.read_csv( 'M4-info.csv', index_col=0, parse_dates=['StartingDate'], dayfirst=True, ) train = pd.read_csv( f'Hourly-train.csv', index_col=0, ).loc[idx] test = pd.read_csv( f'Hourly-test.csv', index_col=0, ).loc[idx] y = train.values sd = info.loc[idx,'StartingDate'] fcst_horizon = info.loc[idx,'Horizon'] cd = pd.date_range( start = sd, freq = 'H', periods = len(y), ) f = Forecaster( y = y, # observed values current_dates = cd, # current dates future_dates = fcst_horizon, # forecast length test_length = fcst_horizon, # test-set length cis = cis, # whether to evaluate intervals for each model metrics = metrics, # what metrics to evaluate ) return f, test.values f, test_set = read_data() f # display the Forecaster object

結果是這樣的:

集成時間序列模型提高預測精度

模型

在我們(men) 開始構建模型之前,我們(men) 需要從(cong) 中生成最簡單的預測,naive方法就是向前傳(chuan) 播最近24個(ge) 觀測值。

f.set_estimator('naive') f.manual_forecast(seasonal=True)

然後使用ARIMA、LSTM和Prophet作為(wei) 基準。

ARIMA

Autoregressive Integrated Moving Average 是一種流行而簡單的時間序列技術,它利用序列的滯後和誤差以線性方式預測其未來。通過EDA,我們(men) 確定這個(ge) 係列是高度季節性的。所以最終選擇了應用order (5,1,4) x(1,1,1,24)的季節性ARIMA模型。

f.set_estimator('arima') f.manual_forecast( order = (5,1,4), seasonal_order = (1,1,1,24), call_me = 'manual_arima', )

LSTM

如果說ARIMA是時間序列模型中比較簡單的一種,那麽(me) LSTM就是比較先進的方法之一。它是一種具有許多參數的深度學習(xi) 技術,其中包括一種在順序數據中發現長期和短期模式的機製,這在理論上使其成為(wei) 時間序列的理想選擇。這裏使用tensorflow建立這個(ge) 模型

f.set_estimator('rnn') f.manual_forecast( lags = 48, layers_struct=[ ('LSTM',{'units':100,'activation':'tanh'}), ('LSTM',{'units':100,'activation':'tanh'}), ('LSTM',{'units':100,'activation':'tanh'}), ], optimizer = 'Adam', epochs = 15, plot_loss = True, validation_split=0.2, call_me = 'rnn_tanh_activation', ) f.manual_forecast( lags = 48, layers_struct=[ ('LSTM',{'units':100,'activation':'relu'}), ('LSTM',{'units':100,'activation':'relu'}), ('LSTM',{'units':100,'activation':'relu'}), ], optimizer = 'Adam', epochs = 15, plot_loss = True, validation_split=0.2, call_me = 'rnn_relu_activation', )

Prophet

盡管它非常受歡迎,但有人聲稱它的準確性並不令人印象深刻,主要是因為(wei) 它對趨勢的推斷有時候很不切實際,而且它沒有通過自回歸建模來考慮局部模式。但是它也有自己的特點。1,它會(hui) 自動將節日效果應用到模型身上,並且還考慮了幾種類型的季節性。可以以用戶所需的最低需求來完成這一切,所以我喜歡把它用作信號,而不是最終的預測結果。

f.set_estimator('prophet') f.manual_forecast()

比較結果

現在我們(men) 已經為(wei) 每個(ge) 模型生成了預測,讓我們(men) 看看它們(men) 在驗證集上的表現如何,驗證集是我們(men) 訓練集中的最後48個(ge) 觀察結果。

results = f.export(determine_best_by='TestSetSMAPE') ms = results['model_summaries'] ms[ [ 'ModelNickname', 'TestSetLength', 'TestSetSMAPE', 'InSampleSMAPE', ] ]

集成時間序列模型提高預測精度

每個(ge) 模型的表現都優(you) 於(yu) naive方法。ARIMA模型表現最好,百分比誤差為(wei) 4.7%,其次是Prophet模型。讓我們(men) 看看所有的預測與(yu) 驗證集的關(guan) 係:

f.plot(order_by="TestSetSMAPE",ci=True) plt.show()

集成時間序列模型提高預測精度

所有這些模型在這個(ge) 時間序列上的表現都很合理,它們(men) 之間沒有很大的偏差。下麵讓我們(men) 把它們(men) 堆起來!

堆疊模型

每個(ge) 堆疊模型都需要一個(ge) 最終估計器,它將過濾其他模型的各種估計,創建一組新的預測。我們(men) 將把之前結果與(yu) Catboost估計器疊加在一起。Catboost是一個(ge) 強大的程序,希望它能從(cong) 每個(ge) 已經應用的模型中充實出最好的信號。

f.add_signals( f.history.keys(), # add signals from all previously evaluated models ) f.add_ar_terms(48) f.set_estimator('catboost')

上麵的代碼將來自每個(ge) 評估模型的預測添加到Forecaster對象中。它稱這些預測為(wei) “信號”。它們(men) 的處理方式與(yu) 存儲(chu) 在同一對象中的任何其他協變量相同。這裏還添加了最後 48 個(ge) 係列的滯後作為(wei) Catboost 模型可以用來進行預測的附加回歸變量。現在讓我們(men) 調用三種 Catboost 模型:一種使用所有可用信號和滯後,一種僅(jin) 使用信號,一種僅(jin) 使用滯後。

f.manual_forecast( Xvars='all', call_me='catboost_all_reg', verbose = False, ) f.manual_forecast( Xvars=[x for x in f.get_regressor_names() if x.startswith('AR')], call_me = 'catboost_lags_only', verbose = False, ) f.manual_forecast( Xvars=[x for x in f.get_regressor_names() if not x.startswith('AR')], call_me = 'catboost_signals_only', verbose = False, )

下麵可以比較所有模型的結果。我們(men) 將研究兩(liang) 個(ge) 度量:SMAPE和平均絕對比例誤差(MASE)。這是實際M4比賽中使用的兩(liang) 個(ge) 指標。

test_results = pd.DataFrame(index = f.history.keys(),columns = ['smape','mase']) for k, v in f.history.items(): test_results.loc[k,['smape','mase']] = [ metrics.smape(test_set,v['Forecast']), metrics.mase(test_set,v['Forecast'],m=24,obs=f.y), ] test_results.sort_values('smape')

集成時間序列模型提高預測精度

可以看到,通過組合來自不同類型模型的信號生成了兩(liang) 個(ge) 優(you) 於(yu) 其他估計器的估計器:使用所有信號訓練的Catboost模型和隻使用信號的Catboost模型。這兩(liang) 種方法的樣本誤差都在2.8%左右。下麵是對比圖:

fig, ax = plt.subplots(figsize=(12,6)) f.plot( models = ['catboost_all_reg','catboost_signals_only'], ci=True, ax = ax ) sns.lineplot( x = f.future_dates, y = test_set, ax = ax, label = 'held out actuals', color = 'darkblue', alpha = .75, ) plt.show()

集成時間序列模型提高預測精度

哪些信號最重要?

為(wei) 了完善分析,我們(men) 可以使用shapley評分來確定哪些信號是最重要的。Shapley評分被認為(wei) 是確定給定機器學習(xi) 模型中輸入的預測能力的最先進的方法之一。得分越高,意味著輸入在特定模型中越重要。

f.export_feature_importance('catboost_all_reg')

集成時間序列模型提高預測精度

上麵的圖隻顯示了前幾個(ge) 最重要的預測因子,但我們(men) 可以從(cong) 中看出,ARIMA信號是最重要的,其次是序列的第一個(ge) 滯後,然後是Prophet。RNN模型的得分也高於(yu) 許多滯後模型。如果我們(men) 想在未來訓練一個(ge) 更輕量的模型,這可能是一個(ge) 很好的起點。

總結

在這篇文章中,我展示了在時間序列上下文中集成模型的力量,以及如何使用不同的模型在時間序列上獲得更高的精度。這裏我們(men) 使用scalecast包,這個(ge) 包的功能還是很強大的,如果你喜歡,可以去它的主頁看看:https://github.com/mikekeith52/scalecast

本文的數據集是M4的時序競賽:https://github.com/Mcompetitions/M4-methods

使用代碼在這裏:https://scalecast-examples.readthedocs.io/en/latest/misc/stacking/custom_stacking.html

作者:Michael Keith

轉:Deephub Imba

【競賽報名/項目谘詢+微信:mollywei007】

下一篇

2023年多鄰國考試即將調整!

你也可能喜歡

  • 暫無相關文章!

評論已經被關(guan) 閉。

插入圖片
返回頂部