You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何XGBoost预测AUC低于eval_set中同数据的评估值?

问题解析:XGBoost eval_set AUC与预测后计算AUC的差异

问题背景

训练二分类器时,尝试两种方式获取测试集AUC:

  1. 将测试集传入eval_set,从model.evals_result()中提取每轮迭代的AUC
  2. 训练完成后对测试集预测,再计算AUC

但第二种方法得到的AUC远低于第一种,复现代码及结果如下:

复现代码

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.metrics import RocCurveDisplay, roc_curve, auc
from xgboost import XGBClassifier # xgboost version 1.7.6
import matplotlib.pyplot as plt

# 加载红酒质量数据集
data = pd.read_csv('winequality-red.csv')

# 构造二分类标签:质量>=7为1,否则为0
X = data.drop('quality', axis=1)
y = data['quality'].map(lambda x: 1 if x >= 7 else 0)

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 训练XGBoost模型
params = {
    'eval_metric':'auc',
    'objective':'binary:logistic'
}
model = XGBClassifier(**params)
model.fit(
    X_train, 
    y_train,
    eval_set=[(X_test, y_test)]
)

两种方式的结果对比

  1. 从eval_set提取AUC
results = model.evals_result()
plt.plot(np.arange(0,100),results['validation_0']['auc'])
plt.title("AUC from eval_set")
plt.xlabel("Estimator (boosting round)")
plt.ylabel("AUC")
plt.show()

AUC from eval_set

  1. 原错误预测后计算AUC
test_predictions = model.predict(X_test)
fpr, tpr, thresholds = roc_curve(y_true=y_test, y_score=test_predictions,pos_label=1)
roc_auc = auc(fpr, tpr)
display = RocCurveDisplay(roc_auc=roc_auc, fpr=fpr, tpr=tpr)
display.plot()
plt.show()

ROC Curve

原方法得到的AUC为0.81,远低于eval_set中最低的AUC值。


核心原因

问题出在预测时使用的函数错误:

  • XGBoost在eval_set中计算AUC时,使用的是模型输出的正类预测概率(连续数值,范围0~1),这能反映模型对每个样本属于正类的置信度,是计算AUC的正确输入。
  • 而model.predict()返回的是离散的类别标签(0或1),它默认用0.5作为阈值将概率转换为类别,丢失了概率的连续信息。用离散标签计算AUC时,相当于只使用了一个阈值(0.5)的结果,ROC曲线只有少数几个点,自然会导致AUC偏低。

修正方法

使用model.predict_proba()获取正类的预测概率,再计算AUC:

# 获取正类的预测概率(第二列对应标签1的概率)
test_probs = model.predict_proba(X_test)[:, 1]
fpr, tpr, thresholds = roc_curve(y_true=y_test, y_score=test_probs, pos_label=1)
roc_auc = auc(fpr, tpr)
display = RocCurveDisplay(roc_auc=roc_auc, fpr=fpr, tpr=tpr)
display.plot()
plt.show()

修正后计算的AUC会和eval_set中最后一轮迭代的AUC值几乎完全一致(因为模型训练完成后用的是全部迭代树的结果,对应eval_set最后一轮的指标)。


内容的提问来源于stack exchange,提问作者j45612

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 16:42:36