如何用XGBoost做時間序列預測?

THU資料派發表於2020-09-02

針對分類和迴歸問題,XGBoost是梯度提升演算法的一種高效實現。

它兼顧了速度和效率,且在很多預測模型任務中表現優異,在資料科學比賽中廣受贏家偏愛,如Kaggle。

XGBoost也可以用於時間序列預測,儘管要先把時間序列資料集轉換成適用於有監督學習的形式。它還需要使用一種專門的技術來評估模型,稱為前向推進驗證,因為模型評估使用了k-摺疊交叉,這會產生有正偏差的結果。

在本文中,你將會了解到如何開發應用於時間序列預測的XGBoost模型。

完成本教程後,你將知道:

XGBoost是用於分類和迴歸問題的梯度提升整合方法的一個實現。

透過使用滑動時間視窗表示,時間序列資料集可以適用於有監督學習。

在時間序列預測問題上,如何使用XGBoost模型進行擬合、評估、預測。

讓我們開始吧!如何用XGBoost做時間序列預測?

教程概覽

本教程分為三個部分,分別是:

一、XGBoost整合

二、時間序列資料準備

三、時間序列預測上的XGBoost

一、XGBoost整合

XGBoost是Extreme GradientBoosting的縮寫,是一種高效的隨機梯度提升的實現。

隨機梯度提升演算法(或者叫gradient boosting machines ortree boosting)是一種強大的機器學習技術,在很多有挑戰的機器學習問題上,表現的非常好甚至是最好。

Tree boosting has been shown to give state-of-the-art results onmany standard classification benchmarks.

— XGBoost:A Scalable Tree Boosting System, 2016.

https://arxiv.org/abs/1603.02754

它是一個決策樹演算法的整合,其中新樹可以對模型中已有樹的結果進行修正。我們可以不斷增加決策樹,直到達到滿意的效果。

XGBoost是隨機梯度提升演算法的一種高效實現,它可以透過一系列模型超引數在整個訓練過程中控制模型。

The mostimportant factor behind the success of XGBoost is its scalability in allscenarios. The system runs more than ten times faster than existing popularsolutions on a single machine and scales to billions of examples in distributedor memory-limited settings.

— XGBoost: A Scalable TreeBoosting System, 2016.

https://arxiv.org/abs/1603.02754

XGBoost是為表格式資料集的分類和迴歸問題而設計的,也可以用於時間序列預測。

想獲得更多有關GDBT和XGBoost實現,請看以下教程:

《機器學習中梯度提升演算法的簡要概括》

連結:https://machinelearningmastery.com/gentle-introduction-gradient-boosting-algorithm-machine-learning/

首先,XGBoost需要安裝,你可以用pip安裝,如下:

如何用XGBoost做時間序列預測?

安裝後,可以透過以下程式碼確認是否成功安裝以及安裝的版本:

如何用XGBoost做時間序列預測?

執行以上程式碼,會看到如下的版本號,也有可能版本號更高:

如何用XGBoost做時間序列預測?

雖然XGBoost庫有自己的python介面,你也可以使用scikit-learn API中的XGBRegressor包裝類。 

模型的一個例項可以被例項化並像任何其他scikit-learn類一樣用於模型評估。例如:
如何用XGBoost做時間序列預測?

現在我們已經熟悉了XGBoost,接下來我們看一看如何準備用於監督學習的時間序列資料集。

二、時間序列資料準備

時間資料可以用於監督學習。

給定時間序列資料集的一系列數字,我們可以重新構造資料,使其看起來像一個有監督的學習問題。我們可以使用前一個時間步長的資料作為輸入變數,並使用下一個時間步長作為輸出變數。

讓我們用一個例子來具體學習。設想我們有這樣一組時間序列資料:

如何用XGBoost做時間序列預測?

我們可以把這個時間序列資料集重新構造成一個有監督學習,用前一個時間步長的值來預測下一個時間步的值。
 
透過這種方式重新組織時間序列資料集,資料將如下所示:

如何用XGBoost做時間序列預測?

注意!我們去掉了時間列,並且有幾行資料不能用於訓練,如第一行和最後一行。

這種表示稱為滑動視窗,因為輸入和期望輸出的視窗隨著時間向前移動,為有監督學習模型建立新的“樣本”。

有關準備時間序列預測資料的滑動視窗方法的更多資訊,請參閱教程:

《Time Series Forecasting as Supervised Learning》

連結:https://machinelearningmastery.com/time-series-forecasting-supervised-learning/

可以用pandas庫的shift()方法,按照給定的輸入輸出的長度,把時間序列資料轉換為新框架。

這將是一個有用的工具,因為它可以讓我們用機器學習演算法來探索時間序列問題的不同框架,看看哪種方法可能會產生更好的模型。

 下面的函式將時間序列作為具有一列或多列的NumPy陣列時間序列,並將其轉換為具有指定數量的輸入和輸出的監督學習問題。

如何用XGBoost做時間序列預測?我們可以使用此函式為XGBoost準備一個時間序列資料集。             

有關此功能逐步開發的更多資訊,請參閱教程:

《如何在Python中將時間序列轉化為監督學習問題》

連結:https://machinelearningmastery.com/convert-time-series-supervised-learning-problem-python/

資料集準備好之後,我們需要關注如何使用它來擬合和評估一個模型。

比如用未來資料預測歷史資料的模型是無效的。模型必須根據歷史資料預測未來。

這意味著模型評估階段,類似k折交叉檢驗這種資料集隨機拆分的方法並不適用。相反我們必須使用一種稱為向前推進驗證的技術。

在前向驗證中,首先透過選擇一個拆分點將資料分為訓練集和測試集,比如除去最後12個月的資料用於訓練,最後12個月的資料用於測試。

如果對一步預測感興趣,例如一個月,那麼我們可以透過在訓練資料集上訓練並預測測試資料集中的第一個步長來評估模型。然後,我們可以將來自測試集的真實觀測值新增到訓練資料集中,重新調整模型,然後讓模型預測測試資料集中的第二個步長。

在整個測試集上重複這個過程,可以得到一步長的預測,並且可以計算錯誤率來評估這個模型的表現。

有關前向驗證的更多資訊,請參考教程:

《How To Backtest Machine Learning Models for Time Series Forecasting》

連結:https://machinelearningmastery.com/backtest-machine-learning-models-time-series-forecasting/)

下邊這個函式執行前向驗證。 

引數是整個時間序列資料集和用於測試集的行數。 

然後它遍歷測試集,呼叫xgboost_forecast()函式做一步長的預測。計算錯誤度量並返回詳細資訊以供分析。

如何用XGBoost做時間序列預測?

train_test_split()函式是用來把資料集劃分為訓練集和測試集的。可以如下定義這個方法:

如何用XGBoost做時間序列預測?

可以用XGBRegressor類來做一步預測。xgboost_forecast()方法實現的是,以訓練集、測試集的輸入作為函式的輸入,擬合模型,然後做一步長預測。
如何用XGBoost做時間序列預測?

現在我們已經知道如何準備用於預測的時間序列資料集,以及評估XGBoost模型,接下來我們可以在實際的資料集上使用XGBoost。

三、XGBoost用於時間序列預測

在本節中,我們將探討如何使用XGBoost進行時間序列預測。        

我們將使用一個標準的單變數時間序列資料集,目的是使用該模型進行一步預測。 

你可以使用本節的程式碼來開始自己專案,它可以輕易的轉化應用於多變數輸入、多變數預測、多步長預測。 

以下連結可以用於下載資料集,在本地工作目錄以“daily-total-female-births.csv“的檔名匯入。

Dataset (daily-total-female-births.csv)

連結:https://raw.githubusercontent.com/jbrownlee/Datasets/master/daily-total-female-births.csv

Description (daily-total-female-births.names)

連結:https://raw.githubusercontent.com/jbrownlee/Datasets/master/daily-total-female-births.names

資料集的前幾行如下所示:

如何用XGBoost做時間序列預測?

首先匯入資料,繪製資料集。完整的示例如下:

如何用XGBoost做時間序列預測?

執行這段示例可以得到這個資料集的折線圖。可以發現沒有明顯的趨勢和季節性。

如何用XGBoost做時間序列預測?

在預測後12個月的嬰兒出生數的問題上,持續性模型實現了6.7的平均絕對誤差(MAE)。提供了一個模型有效的基準。 

接下來我們評估XGBoost模型在這個資料集上的表現,並對最後12個月的資料做一步長的預測。

我們僅使用前三個時間步長作為模型輸入,以及預設的模型超引數,但是把loss改成了‘reg:squarederror‘(以避免警告訊息)並在集合中使用1000棵樹(以避免欠擬合)。

完整的示例如下:

# forecast monthlybirths with xgboost

from numpy importasarray

from pandas importread_csv

from pandas importDataFrame

from pandas importconcat

from sklearn.metricsimport mean_absolute_error

from xgboost importXGBRegressor

from matplotlib importpyplot

# transform a timeseries dataset into a supervised learning dataset

defseries_to_supervised(data, n_in=1, n_out=1, dropnan=True):

       n_vars = 1 if type(data) is list elsedata.shape[1]

       df = DataFrame(data)

       cols = list()

       # input sequence (t-n, ... t-1)

       for i in range(n_in, 0, -1):

              cols.append(df.shift(i))

       # forecast sequence (t, t+1, ... t+n)

       for i in range(0, n_out):

              cols.append(df.shift(-i))

       # put it all together

       agg = concat(cols, axis=1)

       # drop rows with NaN values

       if dropnan:

              agg.dropna(inplace=True)

       return agg.values

 

# split a univariatedataset into train/test sets

deftrain_test_split(data, n_test):

       return data[:-n_test, :], data[-n_test:,:]

 

# fit an xgboost modeland make a one step prediction

def xgboost_forecast(train,testX):

       # transform list into array

       train = asarray(train)

       # split into input and output columns

       trainX, trainy = train[:, :-1], train[:,-1]

       # fit model

       model =XGBRegressor(objective='reg:squarederror', n_estimators=1000)

       model.fit(trainX, trainy)

       # make a one-step prediction

       yhat = model.predict(asarray([testX]))

       return yhat[0]

 

# walk-forwardvalidation for univariate data

defwalk_forward_validation(data, n_test):

       predictions = list()

       # split dataset

       train, test = train_test_split(data,n_test)

       # seed history with training dataset

       history = [x for x in train]

       # step over each time-step in the testset

       for i in range(len(test)):

              # split test row into input andoutput columns

              testX, testy = test[i, :-1],test[i, -1]

              # fit model on history and make aprediction

              yhat = xgboost_forecast(history,testX)

              # store forecast in list ofpredictions

              predictions.append(yhat)

              # add actual observation tohistory for the next loop

              history.append(test[i])

              # summarize progress

              print('>expected=%.1f,predicted=%.1f' % (testy, yhat))

       # estimate prediction error

       error = mean_absolute_error(test[:, 1],predictions)

       return error, test[:, 1], predictions

 

# load the dataset

series =read_csv('daily-total-female-births.csv', header=0, index_col=0)

values = series.values

# transform the timeseries data into supervised learning

data =series_to_supervised(values, n_in=3)

# evaluate

mae, y, yhat =walk_forward_validation(data, 12)

print('MAE: %.3f' %mae)

# plot expected vspreducted

pyplot.plot(y,label='Expected')

pyplot.plot(yhat,label='Predicted')

pyplot.legend()

pyplot.show()

執行這個示例將報告測試集中每個時間的預期值和預測值,然後報告所有預測值的MAE。             

我們可以看到,該模型比6.7MAE的永續性模型表現得更好,實現了大約5.3個出生嬰兒的MAE。

你可以做的更好嗎?

可以嘗試不同的XGBoost超引數,以及不同的時間步長的輸入,看看是否能夠得到更好的模型,歡迎在評論區中分享結果。如何用XGBoost做時間序列預測?

下圖繪製了用於比較最後12個月的預測值和實際值的折線圖,該圖提供了一個測試集上模型表現情況的視覺化展示。

如何用XGBoost做時間序列預測?

一旦選擇了最終的XGBoost模型引數,就可以確定一個模型並用於對新資料進行預測。    

這稱為樣本外預測,例如訓練集之外的預測。這與在評估模型期間進行預測是相同的:因為在評估選擇哪個模型和用這個模型在新資料上做預測的流程是一樣的。

下面的示例演示如何在所有可用資料上擬合最終的XGBoost模型,並在資料集末尾之外進行一步預測。

# finalize model andmake a prediction for monthly births with xgboost

from numpy importasarray

from pandas importread_csv

from pandas importDataFrame

from pandas importconcat

from xgboost importXGBRegressor

 

# transform a timeseries dataset into a supervised learning dataset

defseries_to_supervised(data, n_in=1, n_out=1, dropnan=True):

       n_vars = 1 if type(data) is list elsedata.shape[1]

       df = DataFrame(data)

       cols = list()

       # input sequence (t-n, ... t-1)

       for i in range(n_in, 0, -1):

              cols.append(df.shift(i))

       # forecast sequence (t, t+1, ... t+n)

       for i in range(0, n_out):

              cols.append(df.shift(-i))

       # put it all together

       agg = concat(cols, axis=1)

       # drop rows with NaN values

       if dropnan:

              agg.dropna(inplace=True)

       return agg.values

 

# load the dataset

series =read_csv('daily-total-female-births.csv', header=0, index_col=0)

values = series.values

# transform the timeseries data into supervised learning

train =series_to_supervised(values, n_in=3)

# split into input andoutput columns

trainX, trainy =train[:, :-1], train[:, -1]

# fit model

model =XGBRegressor(objective='reg:squarederror', n_estimators=1000)

model.fit(trainX,trainy)

# construct an inputfor a new preduction

row = values[-3:].flatten()

# make a one-stepprediction

yhat =model.predict(asarray([row]))

print('Input: %s,Predicted: %.3f' % (row, yhat[0]))

執行該程式碼,基於所有可用資料構建XGBoost模型。  

使用最後三個月的已知資料作為新的輸入行,並預測資料集結束後的下一個月。

進一步閱讀

如果您想深入瞭解,本節將提供有關該主題的更多資源。             

相關教程

機器學習中梯度提升演算法的簡要介紹

https://machinelearningmastery.com/gentle-introduction-gradient-boosting-algorithm-machine-learning/

時間序列預測轉化為監督學習問題

https://machinelearningmastery.com/time-series-forecasting-supervised-learning/

如何用Python 將時間序列問題轉化為有監督學習問題

https://machinelearningmastery.com/convert-time-series-supervised-learning-problem-python/

How To Backtest Machine Learning Models for Time Series     Forecasting

https://machinelearningmastery.com/backtest-machine-learning-models-time-series-forecasting/

總結 

在本教程中,您瞭解瞭如何為時間序列預測開發XGBoost模型。

具體來說,你學到了: 

XGBoost是用於分類和迴歸的梯度boosting整合演算法的實現

時間序列資料集可以透過滑動視窗表示轉化為有監督學習。             

如何使用XGBoost模型擬合、評估和預測時間序列預測。

原文標題:

How to Use XGBoost for Time Series Forecasting

原文連結:

https://machinelearningmastery.com/xgboost-for-time-series-forecasting

譯者簡介

王威力,養老醫療行業BI從業者。保持學習。


相關文章