【问题标题】:XGBoost ROC AUC during training does not fit to the end result训练期间的 XGBoost ROC AUC 不适合最终结果
【发布时间】:2022-11-11 05:36:59
【问题描述】:

我正在使用 XGBoost 训练 BDT 对 22 个特征进行二进制分类。我有 1800 万个样本。 (60% 用于训练,40% 用于测试)

我在训练期间得到的 ROC AUC 不符合我得到的最终结果,我不明白这是怎么回事。此外,ROC AUC 显示出比任何其他指标都更多的过度训练,并且它似乎在测试数据上具有最大值。

有没有人遇到过类似的问题,或者知道我的模型有什么问题,或者我如何找出问题所在?

我的代码的本质:

params = {
 "model_params": {
    "n_estimators": 2000,
    "max_depth": 4,
    "learning_rate": 0.1,
    "scale_pos_weight": 11.986832275943744,
    "objective": "binary:logistic",
    "tree_method": "hist"
  },
  "train_params": {
    "eval_metric": [
      "logloss",
      "error",
      "auc",
      "aucpr",
      "map"
    ]
  }
}

model = xgb.XGBClassifier(**params["model_params"], use_label_encoder=False)
model.fit(X_train, y_train, 
          eval_set=[(X_train, y_train), (X_test, y_test)], 
          **params["train_params"])

train_history = model.evals_result()

...

plt.plot(iterations, train_history["validation_0"]["auc"], label="training data")
plt.plot(iterations, train_history["validation_1"]["auc"], label="test data")

...

y_pred_proba_train = model.predict_proba(X_train)
y_pred_proba_test = model.predict_proba(X_test)

fpr_test, tpr_test, _ = sklearn.metrics.roc_curve(y_test, y_pred_proba_test[:, 1])
fpr_train, tpr_train, _ = sklearn.metrics.roc_curve(y_train, y_pred_proba_train[:, 1])

auc_test = sklearn.metrics.auc(fpr_test, tpr_test)
auc_train = sklearn.metrics.auc(fpr_train, tpr_train)

...

plt.title(f"ROC curve, AUC=(test: {auc_test:.4f}, train: {auc_train:.4f})")
plt.plot(fpr_test, tpr_test, label="test data")
plt.plot(fpr_train, tpr_train, label="train data")

...

【问题讨论】:

  • scikit-learn 默认采用macro average auc,我不确定xgboost 是做什么的,但我怀疑它采用微观平均值。你的数据集不平衡吗?这可以解释它,特别是如果您的测试集没有分层。
  • 我刚刚测试了这个。我手动使用roc_curve + auc。这会产生与 roc_auc_scoremacroweightedNone 相同的结果。但是,roc_auc_scoremicro 对训练和测试数据产生的分数要低得多,为 0.71。我不认为是这样,但有趣的观察! samples 不知何故需要很长时间才能计算出来。
  • 并回答您的问题:我的数据集与 12:1 不平衡(类别:0、1)我对sklearn.model_selection.train_test_split 进行了分层。
  • 你是在集群上训练吗? XGBoost 平均每个节点的 auc。
  • 是的,我正在一台具有多个 CPU 的服务器上进行培训。我不明白您的意思,您能否提供进一步阅读的链接或在答案中解释它?这听起来像是一个很有希望的解释。

标签: python machine-learning scikit-learn xgboost


【解决方案1】:

它是not clear in the documentation,但是当提供验证集时,XGBoost 可能会在使用 scikit-learn API 时使用具有最佳验证指标(在您的情况下为map)的迭代模型状态进行预测。

你没有做错任何事;当允许训练多次迭代时,GBT 过度拟合是完全正常的。

编辑:这并不能解释它;根据更新的 OP,验证 map 在每次迭代中都在不断改进。

【讨论】:

  • “具有最佳验证指标”是什么意思?我担心的是,最终模型只显示了轻微的过拟合,但训练历史显示出严重的过拟合。测试数据上的 AUC 较高,而训练数据上的 AUC 较低。
  • 您的模型将使用迭代中显示最佳验证的模型状态map(您提供的最后一个指标)。这是在迭代 #40 左右,验证 auc 的峰值在您的图中可见,稍后训练和验证 auc 匹配您自己的测试。训练历史显示严重的过度拟合,因为您继续训练额外的 1960 次迭代,但由于验证指标没有改善,您的模型使用迭代 ~40 的状态(在它变得过度拟合之前)进行预测。
  • 我认为那不是真的。 model.best_iteration 产生 1999map 历史在迭代 <100 时没有达到峰值。 (我将其添加到帖子中)此外,我在训练后获得的 AUC 分数与训练期间的 AUC 分数非常不同,即使在迭代 ~40 时也是如此。还是我错过了什么?不管怎么说,还是要谢谢你!我不知道大部分。
  • 另外,我没有使用提前停止。
【解决方案2】:

在集群上训练时,XGBoost calculates the AUC (ctrl-f for 'auc') 作为每个节点的宏观平均值。特别是考虑到您的班级不平衡,我怀疑这是罪魁祸首。

【讨论】:

  • 也不是这样。我只是在一个 CPU 上训练它并得到基本相同的结果。另外,我现在认为我正在使用的服务器并不能真正算作分布式环境。
猜你喜欢
  • 2019-02-13
  • 2019-11-26
  • 2020-09-01
  • 2018-12-03
  • 2020-03-20
  • 2020-04-23
  • 2015-08-02
  • 2019-05-02
  • 2017-06-17
相关资源
最近更新 更多