針對分類和迴歸問題,XGBoost是梯度提升演算法的一種高效實現。
它兼顧了速度和效率,且在很多預測模型任務中表現優異,在資料科學比賽中廣受贏家偏愛,如Kaggle。
XGBoost也可以用於時間序列預測,儘管要先把時間序列資料集轉換成適用於有監督學習的形式。它還需要使用一種專門的技術來評估模型,稱為前向推進驗證,因為模型評估使用了k-摺疊交叉,這會產生有正偏差的結果。
在本文中,你將會了解到如何開發應用於時間序列預測的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庫有自己的python介面,你也可以使用scikit-learn API中的XGBRegressor包裝類。
模型的一個例項可以被例項化並像任何其他scikit-learn類一樣用於模型評估。例如:
現在我們已經熟悉了XGBoost,接下來我們看一看如何準備用於監督學習的時間序列資料集。
二、時間序列資料準備
時間資料可以用於監督學習。
給定時間序列資料集的一系列數字,我們可以重新構造資料,使其看起來像一個有監督的學習問題。我們可以使用前一個時間步長的資料作為輸入變數,並使用下一個時間步長作為輸出變數。
注意!我們去掉了時間列,並且有幾行資料不能用於訓練,如第一行和最後一行。
這種表示稱為滑動視窗,因為輸入和期望輸出的視窗隨著時間向前移動,為有監督學習模型建立新的“樣本”。
有關準備時間序列預測資料的滑動視窗方法的更多資訊,請參閱教程:
《Time Series Forecasting as Supervised Learning》
連結:https://machinelearningmastery.com/time-series-forecasting-supervised-learning/
可以用pandas庫的shift()方法,按照給定的輸入輸出的長度,把時間序列資料轉換為新框架。
這將是一個有用的工具,因為它可以讓我們用機器學習演算法來探索時間序列問題的不同框架,看看哪種方法可能會產生更好的模型。
下面的函式將時間序列作為具有一列或多列的NumPy陣列時間序列,並將其轉換為具有指定數量的輸入和輸出的監督學習問題。
我們可以使用此函式為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模型,接下來我們可以在實際的資料集上使用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模型在這個資料集上的表現,並對最後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模型引數,就可以確定一個模型並用於對新資料進行預測。
這稱為樣本外預測,例如訓練集之外的預測。這與在評估模型期間進行預測是相同的:因為在評估選擇哪個模型和用這個模型在新資料上做預測的流程是一樣的。
下面的示例演示如何在所有可用資料上擬合最終的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從業者。保持學習。