XGBoost是梯度分类和回归问题的有效实现。它快速高效,在各种预测建模任务上表现出色,即使不是最好的,也很受数据科学竞赛获胜者(如Kaggle获胜者)的欢迎。XGBoost也可用于时间序列预测,尽管它需要先将时间序列数据集转换为监督学习问题。它还需要使用一种称为前向验证的专门技术来评估模型,因为使用k折交叉验证评估模型会导致乐观的结果。在本教程中,您将了解如何开发用于时间序列预测的XGBoost模型。完成本教程后,您将了解:1.XGBoost是用于分类和回归的梯度提升集成算法的实现。2.滑动窗口表示可用于将时间序列数据集转换为监督学习。3.如何使用XGBoost模型进行时间序列预测的拟合、评估和预测。教程概述本教程分为三个部分:分别是:1.XGBoost集成2.时间序列数据准备3.XGBoost用于时间序列预测XGBoost集成XGBoost是ExtremeGradientBoosting的缩写,是一种有效的随机梯度提升机器学习算法。完成。随机梯度提升(也称为梯度提升机或树提升)是一种强大的机器学习技术,即使不是最好的,也能在各种具有挑战性的机器学习问题上表现出色。它是决策树算法的集合,其中新树修复了那些已经是模型一部分的树的错误。将添加树木,直到无法对模型进行进一步改进。XGBoost提供了随机梯度提升算法的高效实现,并提供了一组模型超参数,旨在提供对模型训练过程的控制。XGBoost专为表格数据集的分类和回归而设计,尽管它可用于时间序列预测。首先,必须安装XGBoost库。您可以使用pip进行安装,如下所示:sudopipinstallxgboost安装后,您可以通过运行确认它安装成功并且您使用的是现代版本:#xgboostimportxgboostprint("xgboost",xgboost.__version__)运行代码,您应该会看到以下版本号或更高版本。xgboost1.0.1虽然XGBoost库有自己的PythonAPI,但我们可以通过XGBRegressor包装类将XGBoost模型与scikit-learnAPI一起使用。可以像任何其他scikit-learn类一样实例化和使用模型实例来进行模型评估。例如:#definemodelmodel=XGBRegressor()现在我们已经熟悉了XGBoost,让我们看看如何为监督学习准备时间序列数据集。时间序列数据准备时间序列数据可以表述为监督学习。给定时间序列数据集中的数字序列,我们可以将数据重组为看起来像监督学习的问题。我们可以通过使用前一个时间步作为输入变量,使用下一个时间步作为输出变量来做到这一点。让我们用一个例子来具体说明。假设我们有一个时间序列如下:time,measure1,1002,1103,1084,1155,120通过使用上一个时间步的值来预测下一个时间步的值,我们可以重组这个时间序列数据集用于监督学习问题。通过以这种方式重组时间序列数据集,数据将如下所示:X,y?,100100,110110,108108,115115,120120,?请注意,时间列已删除,并且某些数据行不可用于训练模型,例如first和last。这种表示称为滑动窗口,因为输入和预期输出的窗口会随着时间向前移动,从而为监督学习模型创建新的“样本”。有关为时间序列预测准备数据的滑动窗口方法的更多信息。给定所需的输入和输出序列长度,我们可以使用Pandas中的shift()函数自动为时间序列问题创建新帧。这将是一个有用的工具,因为它将允许我们使用机器学习算法探索时间序列问题的不同框架,以查看哪些模型可能会带来更好的性能。下面的函数将时间序列作为具有一列或多列的NumPy数组时间序列,并将其转换为具有指定数量的输入和输出的监督学习问题。#transformatimeseriesdatasetintoasupervisedlearningdatasetdefseries_to_supervised(data,n_in=1,n_out=1,dropnan=True):n_vars=1iftype(data)islistelsedata.shape[1]df=DataFrame(data)cols=list()#inputsequence(t-n,...t-1)foriinrange(n_in,0,-1):cols.append(df.shift(i))#forecastsequence(t,t+1,...t+n)foriinrange(0,n_out):cols.append(df.shift(-i))#putitalltogetheragg=concat(cols,axis=1)#droprowswithNaNvaluesifdropnan:agg.dropna(inplace=True)returnagg.values我们可以使用这个函数为XGBoost准备一个时间序列数据集。准备好数据集后,我们必须谨慎使用它来拟合和评估模型。例如,将模型拟合到未来数据并预测过去是无效的。该模型必须在过去进行训练并预测未来。这意味着不能使用在评估期间随机化数据集的方法,例如k折交叉验证。相反,我们必须使用一种称为前向验证的技术。在前向验证中,首先选择一个切点(例如,除最近12个月以外的所有数据都用于训练,最后12个月用于测试。如果我们有兴趣进行一步预测,比如一个月后,我们可以通过在训练数据集上训练并预测测试数据集的第一步来评估模型,然后我们可以将测试集中的真实观察结果添加到训练数据集中,重新拟合模型,让模型预测测试的第二步数据集中的步骤。对整个测试数据集重复此过程将为整个测试数据集提供一步预测,从中可以计算错误度量以评估模型的技能。下面的函数执行前向验证。它使用时间序列数据集的整个监督学习版本和作为测试集的行数作为参数,然后逐步遍历测试集,调用xgboost_forecast()函数进行单步预测.计算错误度量并返回详细信息以供分析。#walk-forwardvalidationforunivariatedatadefwalk_forward_validation(data,n_test):predictions=list()#splitdatasettrain,test=train_test_split(data,n_test)#seedhistorywithtrainingdatasethistory=[xforxintrain]#stepovereachtime-stepinthetestsetforiluminumrange(len(test)):#splittestandoutyntoi,:-1],test[i,-1]#fitmodelonhistoryandmakeapredictionyhat=xgboost_forecast(history,testX)#storeforecastinlistofpredictionspredictions.append(yhat)#addactualobservationtohistoryforthenextloophistory.append(test[i])#summarizeprogressprint('>预期=%.1f,预测=%.1f'%(testy,yhat))#estimatepredictionerrolerror=mean_absolute_error(test[:,-1],predictions)returnerror,test[:,1],predictions调用train_test_split()函数拆分数据集进行训练集和测试放。我们可以在下面定义这个函数。#splitaunivariatedatasetintotrain/testsetsdeftrain_test_split(data,n_test):returndata[:-n_test,:],data[-n_test:,:]我们可以使用XGBRegressor类进行单步预测。下面的xgboost_forecast()函数通过将训练数据集和测试输入行作为输入、拟合模型并进行一步预测来实现这一点。#fitanxgboostmodelandmakeaonesteppredictiondefxgboost_forecast(train,testX):#transformlistintoarraytrain=asarray(train)#splitintoinputandoutputcolumnstrainX,traintrainy=train[:,:-1],train[:,-1]#fitmodel=XGBRegressor(目标='reg:squared_esterror'=1000)model.fit(trainX,trainy)#makeaone-steppredictionyhat=model.predict([testX])returnyhat[0]现在我们知道了如何准备时间序列数据来预测和评估XGBoost模型,我们可以看看使用真实数据集上的XGBoost。用于时间序列预测的XGBoost在本节中,我们将探讨如何使用XGBoost进行时间序列预测。我们将使用标准的单变量时间序列数据集对该模型进行一步预测。您可以将本节中的代码用作您自己项目的起点,并轻松地对其进行调整以用于多变量输入、多变量预测和多步预测。我们将使用每日女性出生数据集,即三年内的每月出生数据。您可以从此处下载数据集并将其放在当前工作目录中,文件名为“daily-total-female-births.csv”。数据集(每天女性出生总数.csv):https://raw.githubusercontent.com/jbrownlee/Datasets/master/daily-total-female-births.csv描述(每天女性出生总数):https://raw.githubusercontent.com/jbrownlee/Datasets/master/daily-total-female-births.names数据集的前几行如下所示:"Date","Births""1959-01-01",35"1959-01-02",32"1959-01-03",30"1959-01-04",31"1959-01-05",44...首先,让我们加载并绘制数据集。下面列出了完整的示例。#loadandplotthetimeseriesdatasetfrompandasimportread_csvfrommatplotlibimportpyplot#loaddatasetseries=read_csv('daily-total-female-births.csv',header=0,index_col=0)values=series.values#plotdatasetpyplot.plot(values)pyplot.show()运行示例将创建的数据集折线图。我们看不到明显的趋势或季节性。在预测最近12个月的时间段时,持久性模型可以实现约6.7次出生的MAE。这提供了一个性能基准,在此基础上可以认为模型是精通的。接下来,我们可以在对过去12个月的数据执行单步预测时评估数据集上的XGBoost模型。我们将只使用前6个时间步作为模型的输入和默认模型超参数,除非我们将损失更改为“reg:squarederror”(以避免警告消息)并在集成中使用1,000棵树(以避免学习不足)).下面列出了完整的示例。#forecastmonthlybirthswithxgboostfromnumpyimportasarrayfrompandasimportread_csvfrompandasimportDataFramefrompandasimportconcatfromsklearn.metricsimportmean_absolute_errorfromxgboostimportXGBRegressorfrommatplotlibimportpyplot#transformatimeseriesdatasetintoasupervisedlearningdatasetdefseries_to_supervised(data,n_in=1,n_out=1,dropnan=True):n_vars=1iftype(data)islistelsedata.shape[1]df=DataFrame(data)cols=list()#inputsequence(t-n,...t-1)foriinrange(n_in,0,-1):cols.append(df.shift(i))#forecastsequence(t,t+1,...t+n)foriinrange(0,n_out):cols.append(df.shift(-i))#putitalltogetheragg=concat(cols,axis=1)#droprowswithNaNvaluesifdropnan:agg.dropna(inplace=True)returnagg.values#splitaunivariatedatasetintotrain/testsetsdeftrain_test_split(data,n_test):returndata[:-n_test,:],数据[-n_test:,:]#fitanxgboostmodelandmakeaonesteppredictiondefxgboost_forecast(train,testX):#transformlistintoarraytrain=asarray(train)#splitintoinputandoutputcolumnstrainX,traintrainy=train[:,:-1],train[:,-1]#fitmodelmodel=XGBRegressor(objective='reg:squarederror',n_estimators=1000)model.fit(trainX,trainy)#makeaone-steppredictionyhat=model.predict(asarray([testX]))returnyhat[0]#walk-forwardvalidationforunivariatedatadefwalk_forward_validation(data,n_test):predictions=list()#splitdatasettrain,test=train_test_split(data,n_test)#seedhistorywithtrainingdatasethistory=[xforxintrain]#stepovereachtime-stepinthetestsetforiinrange(len(测试)):#splittestrowintoinputandoutputcolumnstestX,testtesty=test[i,:-1],test[i,-1]#fitmodelonhistoryandmakeapredictionyhat=xgboost_forecast(history,testX)#stoforecastinlistofpredictionspredictions.append(yhat)#addactualobservationtohistoryforthenextloophistory.append(test[i])#summarizeprogressprint('>expected=%.1f,predicted=%.1f'%(testy,yhat))#estimatepredictionerrorerror=mean_absolute_error(test[:,-1],predictions)returnerror,test[:,-1],预测#loadthedatasetseries=read_csv('daily-total-female-births.csv',header=0,index_col=0)values=series.values#transformthetimeseriesdataintosupervisedlearningdata=series_to_supervised(values,n_in=6)#evaluatemae,y,yhat=walk_forward_validation(data,12)print('MAE:%.3f'%mae)#plotexpectedvspre??ductedpyplot.plot(y,label='Expected')pyplot.plot(yhat,label='Predicted')pyplot.legend()pyplot.show()运行该示例将报告每一步的预期值在测试集和预测值中,然后报告所有预测值的MAE注意:您的结果可能因算法或评估过程中的随机性或数值精度的差异而有所不同。考虑运行该示例几次并比较平均结果。我们可以看到该模型的性能优于持久化模型,MAE约为5.9,MAE约为6.7>expected=42.0,predicted=44.5>expected=53.0,predicted=42.5>expected=39.0,predicted=40.3>预期=40.0,预测=32.5>预期=38.0,预测=41.1>预期=44.0,预测=45.3>预期=34.0,预测=40.2>预期=37.0,预测=35.0>预期=52.0,预测=32.5>expected=48.0,predicted=41.4>expected=55.0,predicted=46.6>expected=50.0,predicted=47.2MAE:5.957创建一个折线图比较数据集最后12个月的预期值和预测值范围.这给出了模型在测试集上的表现如何的几何解释。图2一旦选择了最终的XGBoost模型配置,就可以完成模型并用于对新数据进行预测。这称为样本外预测,即在训练数据集之外进行预测。这与在模型评估期间进行预测相同:因为我们总是希望使用与我们期望模型用于对新数据进行预测的过程相同的过程来评估模型。下面的示例演示了在所有可用数据上拟合最终XGBoost模型并在数据集末尾进行单步预测的过程。#finalizemodelandmakeapredictionformonthlybirthswithxgboostfromnumpyimportasarrayfrompandasimportread_csvfrompandasimportDataFramefrompandasimportconcatfromxgboostimportXGBRegressor#transformatimeseriesdatasetintoasupervisedlearningdatasetdefseries_to_supervised(data,n_in=1,n_out=1,dropnan=True):n_vars=1iftype(data)islistelsedata.shape[1]df=DataFrame(data)cols=list()#inputsequence(t-n,...t-1)foriinrange(n_in,0,-1):cols.append(df.shift(i))#forecastsequence(t,t+1,...t+n)foriinrange(0,n_out):cols.append(df.shift(-i))#putitalltogetheragg=concat(cols,axis=1)#droprowswithNaNvaluesifdropnan:agg.dropna(inplace=True)returnagg.values#loadthedatasetseries=read_csv('daily-total-female-births.csv',header=0,index_col=0)values=series.values#transformthetimeseriesdataintosupervisedlearningtrain=series_to_supervised(values,n_in=6)#splitintoinputandoutputcolumnstrainX,traintrainy=train[:,:-1],train[:,-1]#fitmodel模型=XGBRegressor(目标='reg:squadererror',n_estimators=1000)model.fit(trainX,trainy)#constructaninputforanewpreductionrow=values[-6:].flatten()#makea一步预测yhat=model.predict(asarray([row]))print('输入:%s,Predicted:%.3f'%(row,yhat[0]))RuntheexampleFitanXGBoostmodeltoallavailabledata使用最近6个月的已知数据准备一个新的输入行并预测下一个月数据集。输入:[343752485550],预测值:42.708
