XGBoost:# 轮数等于 n_estimators?

数据挖掘 scikit-学习 回归 xgboost
2022-03-04 16:29:17

我正在运行回归 XGBoost 模型并尝试通过使用以下代码观察训练和测试错误来防止过度拟合:

eval_set = [(X_train, y_train), (X_test, y_test)]

xg_reg = xgb.XGBRegressor(booster='gbtree',
                          objective ='reg:squarederror',
                          max_depth = 6,
                          n_estimators = 100,
                          min_child_weight = 1,
                          learning_rate = 0.05,
                          seed = 1,early_stopping_rounds = 10)


xg_reg.fit(X_train,y_train,eval_metric="rmse", eval_set = eval_set, verbose = True)

打印如下:

[93]    validation_0-rmse:0.233752      validation_1-rmse:0.373165
[94]    validation_0-rmse:0.2334        validation_1-rmse:0.37314
[95]    validation_0-rmse:0.232194      validation_1-rmse:0.372643
[96]    validation_0-rmse:0.231809      validation_1-rmse:0.372675
[97]    validation_0-rmse:0.231392      validation_1-rmse:0.372702
[98]    validation_0-rmse:0.230033      validation_1-rmse:0.372244
[99]    validation_0-rmse:0.228548      validation_1-rmse:0.372253

但是,我注意到打印出来的训练轮数并且在 evals_results 中总是等于 n_estimators。

In [92]: len(results['validation_0']['rmse'])
Out[92]: 100

如果我将树的数量更改为 600,轮数会增加到 600,等等。我的印象是打印的是每轮训练的度量结果,包括一次训练所有树。

这里发生了什么?每一层树都被认为是一个单独的训练轮吗?

1个回答

对于梯度提升,确实没有“树层”的概念,我认为这是发生混乱的地方。提升的每次迭代(轮次)将单个树拟合到某个损失函数的负梯度(使用所有先前迭代中更新模型的预测计算),在您的情况下,均方根误差。该算法在每次迭代时都不适合树的集合。然后将每棵树(具有最佳权重)添加到所有先前拟合的树+先前迭代中的最佳权重,以得出最终预测。

因此,您看到的验证分数是完整模型的分数,直到拟合的树迭代。所以这里的这一行例如:

[93]    validation_0-rmse:0.233752      validation_1-rmse:0.373165

是模型在validation_0 和validation_1 上的性能,该模型在先前迭代中生成的过去梯度上拟合了93棵树。