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

使用sklearn指标作为XGBClassifier评估指标触发ValueError问题

问题:XGBClassifier搭配sklearn评估指标与验证集训练时触发类型不匹配错误

复现代码

import numpy as np
from xgboost import XGBClassifier
from sklearn.metrics import accuracy_score

x_train, y_train = np.random.rand(10,3), np.where(np.random.rand(10,)>0.5, 1, 0)
x_valid, y_valid = np.random.rand(5,3), np.where(np.random.rand(5,)>0.5, 1, 0)

model = XGBClassifier(
    n_estimators=100,
    eval_metric=accuracy_score
)

model.fit(
    X=x_train, y=y_train,
    eval_set=[(x_train, y_train), (x_valid, y_valid)]
)

报错信息

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-5-b63cd5cfabda> in <cell line: 1>()
----> 1 model.fit(
      2     X=x_train, y=y_train,
      3     eval_set=[(x_train, y_train), (x_valid, y_valid)]
      4 )

9 frames
/usr/local/lib/python3.10/dist-packages/sklearn/metrics/_classification.py in _check_targets(y_true, y_pred)
     93 
     94     if len(y_type) > 1:
---&gt; 95         raise ValueError(
     96             "Classification metrics can't handle a mix of {0} and {1} targets".format(
     97                 type_true, type_pred

ValueError: Classification metrics can't handle a mix of binary and continuous targets

错误原因

直接将sklearn的分类指标(如accuracy_score)传给XGBoost的eval_metric参数时,XGBoost会把模型输出的连续概率值(二分类场景下是样本属于正类的概率)传入sklearn指标函数,但sklearn的分类指标要求预测值是离散的类别标签(0/1),而非连续概率,因此触发了「binary真实标签与continuous预测值不匹配」的错误。

当使用eval_metric="error"时,XGBoost内部会自动处理概率到标签的转换,因此可以正常运行;注释eval_set时,验证逻辑不执行,自然也不会触发错误。

解决方法

自定义评估函数,先将XGBoost输出的概率转换为类别标签,再调用sklearn的指标函数。XGBoost要求自定义eval_metric的函数签名为(y_true, y_pred) -> (metric_name, metric_value, is_higher_better),其中:

  • y_true是真实标签数组
  • y_pred是模型输出的概率数组(二分类下形状为(n_samples,),多分类下为(n_samples, n_classes))

示例代码

1. 二分类场景适配(支持accuracy、balanced_accuracy、recall)

import numpy as np
from xgboost import XGBClassifier
from sklearn.metrics import accuracy_score, balanced_accuracy_score, recall_score

# 自定义准确率评估函数
def custom_accuracy(y_true, y_pred):
    # 二分类下将概率转换为0/1标签(阈值设为0.5)
    y_pred_labels = (y_pred > 0.5).astype(int)
    return 'accuracy', accuracy_score(y_true, y_pred_labels), True

# 自定义平衡准确率评估函数
def custom_balanced_accuracy(y_true, y_pred):
    y_pred_labels = (y_pred > 0.5).astype(int)
    return 'balanced_accuracy', balanced_accuracy_score(y_true, y_pred_labels), True

# 自定义召回率评估函数(默认针对正类1)
def custom_recall(y_true, y_pred):
    y_pred_labels = (y_pred > 0.5).astype(int)
    return 'recall', recall_score(y_true, y_pred_labels), True

x_train, y_train = np.random.rand(10,3), np.where(np.random.rand(10,)>0.5, 1, 0)
x_valid, y_valid = np.random.rand(5,3), np.where(np.random.rand(5,)>0.5, 1, 0)

model = XGBClassifier(
    n_estimators=100,
    # 可传入多个自定义评估函数,以列表形式传入
    eval_metric=[custom_accuracy, custom_balanced_accuracy, custom_recall]
)

model.fit(
    X=x_train, y=y_train,
    eval_set=[(x_train, y_train), (x_valid, y_valid)]
)

2. 多分类场景扩展

如果是多分类任务,需要将y_pred转换为类别标签时使用np.argmax(y_pred, axis=1),例如:

def custom_multi_accuracy(y_true, y_pred):
    y_pred_labels = np.argmax(y_pred, axis=1)
    return 'multi_accuracy', accuracy_score(y_true, y_pred_labels), True

注意事项

  • 自定义函数的返回值必须是三元组:(指标名称字符串, 指标数值, 是否越高越好的布尔值)
  • 概率转标签的阈值(如0.5)可根据业务需求调整
  • 多分类场景下,sklearn的指标可能需要指定average参数,例如recall_score(y_true, y_pred_labels, average='macro')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 00:32:36