XGBoost Classifier自定义eval_metric接收预测值形状不符合预期问题
XGBoost多分类自定义评估函数形状适配问题解决
问题原因
你遇到的输出形状差异确实是3分类任务的正常机制:
- XGBoost Regressor只有一个预测目标,因此自定义评估函数收到的预测结果形状为
(n, 1),对应每个样本的回归预测值 - XGBoost Classifier做多分类任务时,默认返回每个样本对应所有类别的预测概率,k分类就返回形状为
(n, k)的结果,你做3分类所以输出是(120000, 3),每列分别代表样本属于类别0、类别1、类别2的概率
解决方法
要获取预测标签,只需要在自定义评估函数中,对预测结果按行取概率最大值对应的索引即可,该索引就是样本的预测类别。
你提供的复现代码还存在几处语法问题需要同步修正:
- 不能用Python关键字
class作为变量名 - 训练时的验证集参数应为
eval_set而非evals_set - XGBoost传入自定义评估函数的真实标签参数是DMatrix对象,需要调用
get_label()方法才能拿到实际的标签数组
修改后的可运行代码示例
import numpy as np from xgboost import XGBClassifier # 避免用关键字class做变量名 xgb_clf = XGBClassifier() # 以下替换为你的实际数据 X_train = np.random.rand(10000, 144) # 示例训练特征,形状(m,144) y_train = np.random.randint(0,3,size=(10000,1)) # 示例3分类标签 X_test = np.random.rand(120000, 144) y_test = np.random.randint(0,3,size=(120000,1)) def eval_function(predicted, true): # 按行取最大概率的索引,得到预测标签,形状变为(120000,) pred_labels = np.argmax(predicted, axis=1) # 从DMatrix对象中取出真实标签,展平后方便后续计算指标 true_labels = true.get_label().flatten() # 此处替换为你自己的评估逻辑,比如计算准确率、F1等 acc = np.mean(pred_labels == true_labels) # 自定义评估函数返回格式为 (指标名, 指标值),如果是越小越好的指标可以设置`greater_is_better=False` return ("custom_acc", acc) xgb_clf.fit( X_train, y_train, eval_set=[(X_test, y_test)], eval_metric=eval_function )
内容的提问来源于stack exchange,提问作者TheRammus
相关产品推荐
相关产品推荐

