我正在使用评估集在 Python 中使用 xgboost 实现提前停止。让我感到困惑的是,在训练期间报告为最佳的评估指标比我在用于评估目的的集合上使用相同模型进行预测时得到的评估指标要好得多。为了说明这一点,我使用了一个带有玩具数据集的可重现示例。在这种情况下,差异不是很大,但仍然很显着。然而,就我实际使用的数据集而言,差距要大得多。代码如下:import xgboost as xgbimport seaborn as snsdef xgb_mape(preds, dtrain): labels = dtrain.get_label() return('mape', np.mean(np.abs((labels - preds) / (labels+1))))mpg = sns.load_dataset('mpg')mpg = mpg.sample(frac = 1)n = int(mpg.shape[0] * 0.7)mpg_train = mpg.iloc[:n, :7]mpg_test = mpg.iloc[n:, :7]mpg_train_y = mpg_train.iloc[:, 0].valuesmpg_test_y = mpg_test.iloc[:, 0].valuesmpg_train_X = mpg_train.iloc[:, 1:].valuesmpg_test_X = mpg_test.iloc[:, 1:].valuesxgb_model_mpg = xgb.XGBRegressor(max_depth= 10, learning_rate=0.1, n_estimators=1000, silent=True, \ objective='reg:linear',\ booster='gbtree', subsample= 0.6, colsample_bytree= 0.9, colsample_bylevel= 1, reg_lambda= 20 ,\ random_state=1 , seed= 1, importance_type='gain')xgb_model_mpg.fit(mpg_train_X ,mpg_train_y , eval_set= [(mpg_test_X , mpg_test_y )], eval_metric= xgb_mape,\ early_stopping_rounds= 20)[...]82] validation_0-rmse:3.41167 validation_0-mape:0.085761[83] validation_0-rmse:3.40828 validation_0-mape:0.085618[84] validation_0-rmse:3.40087 validation_0-mape:0.085519[85] validation_0-rmse:3.403 validation_0-mape:0.085631[86] validation_0-rmse:3.39977 validation_0-mape:0.085711[87] validation_0-rmse:3.39626 validation_0-mape:0.085739[88] validation_0-rmse:3.40048 validation_0-mape:0.085727[89] validation_0-rmse:3.40356 validation_0-mape:0.085883[90] validation_0-rmse:3.40341 validation_0-mape:0.085664Stopping. Best iteration:[70] validation_0-rmse:3.42186 validation_0-mape:0.085076所以在这种情况下,在训练期间我得到 8.5% 的 MAPE,当将模型应用于相同的测试集时,我得到接近 9% 的 MAPE。正如我在其他具有更大和更复杂数据集的示例中所说,差异可能更大,例如 41% 与 58%。
1 回答
守候你守候我
TA贡献1802条经验 获得超10个赞
这里有两个不同的问题。一个小问题:你对 xgb 训练和外部的评估函数的定义略有不同(+1xgb 评估中的分母)。一个更重要的问题:(xgboost与 相比lightgbm)默认情况下使用所有经过训练的树而不是最佳树数来计算预测。要获得预测中的最佳树数,请使用y_pred = xgb_model_mpg.predict(mpg_test_X, ntree_limit=xgb_model_mpg.best_ntree_limit)
添加回答
举报
0/150
提交
取消
