在XGBoost中通过Early Stop避免过拟合( 二 )


使用学习曲线来评估模型
我们可以提取出模型在测试数据集上的表现并绘制成图案,从而更好地洞察到在整个训练过程中学习曲线是如何变化的 。
在调用模型时我们提供了一个数组,数组的每一项是一个X和y的配对 。在测试集之外,我们同时将训练集也作为输入,从而观察在训练过程中模型在训练集和测试集上各自的表现 。
例如:
eval_set = [(X_train, y_train), (X_test, y_test)]model.fit(X_train, y_train, eval_metric="error", eval_set=eval_set, verbose=True)
模型在各个数据集上的表现可以在训练结束后通过model.()函数获取,这个函数返回一个dict包含了评估数据集的代码和对应的分数列表,例如:
results = model.evals_result()print(results)
这将输出如下的结果:
{'validation_0': {'error': [0.259843, 0.26378, 0.26378, ...]},'validation_1': {'error': [0.22179, 0.202335, 0.196498, ...]}}
“”和“”代表了在调用fit()函数时传给参数的数组中数据集的顺序 。
一个特定的结果,比如第一个数据集上的分类错误率,可以通过如下方法获取:
results['validation_0']['error']
另外我们可以指定更多的评价指标,从而同时获取多种评价指标的变化情况 。
接着我们可以使用收集到的数据绘制曲线,从而更直观地了解在整个训练过程中模型在训练集和测试集上的表现究竟如何 。
下面是一段完整的代码,展示了如何将收集到的数据绘制成学习曲线:
# plot learning curvefrom numpy import loadtxtfrom xgboost import XGBClassifierfrom sklearn.model_selection import train_test_splitfrom sklearn.metrics import accuracy_scorefrom matplotlib import pyplot# load datadataset = loadtxt('pima-indians-diabetes.csv', delimiter=",")# split data into X and yX = dataset[:,0:8]Y = dataset[:,8]# split data into train and test setsX_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.33, random_state=7)# fit model no training datamodel = XGBClassifier()eval_set = [(X_train, y_train), (X_test, y_test)]model.fit(X_train, y_train, eval_metric=["error", "logloss"], eval_set=eval_set, verbose=True)# make predictions for test datay_pred = model.predict(X_test)predictions = [round(value) for value in y_pred]# evaluate predictionsaccuracy = accuracy_score(y_test, predictions)print("Accuracy: %.2f%%" % (accuracy * 100.0))# retrieve performance metricsresults = model.evals_result()epochs = len(results['validation_0']['error'])x_axis = range(0, epochs)# plot log lossfig, ax = pyplot.subplots()ax.plot(x_axis, results['validation_0']['logloss'], label='Train')ax.plot(x_axis, results['validation_1']['logloss'], label='Test')ax.legend()pyplot.ylabel('Log Loss')pyplot.title('XGBoost Log Loss')pyplot.show()# plot classification errorfig, ax = pyplot.subplots()ax.plot(x_axis, results['validation_0']['error'], label='Train')ax.plot(x_axis, results['validation_1']['error'], label='Test')ax.legend()pyplot.ylabel('Classification Error')pyplot.title('XGBoost Classification Error')pyplot.show()
运行这段代码将会在每一次训练迭代中输出模型在训练集和测试集上的分类错误率 。我们可以通过设置=False来关闭输出 。
我们绘制了两张图,第一张图表示的是模型在每一轮迭代中在两个数据集上的对数损失:
第二张图表示分类错误率:
从第一张图来看,似乎有机会可以进行Early Stop,大约在20到40轮迭代时比较合适 。