3.2 学习任务参数与评估指标选择


文档摘要

3.2 学习任务参数与评估指标选择 objective 决定 g 与 h 怎么算(训练往哪优化),evalmetric 决定谁说了算(模型怎么比高低),两者可以不同但必须配套。 本节整理常见任务的目标与指标搭配,用不均衡数据的实验演示"指标错配"的后果,并给出自定义损失的最小样例。 上一节把树形参数讲完。还剩一组"方向性"参数:它们不改变树的形状逻辑,却决定整个训练朝哪个方向收敛、以及最终选哪一轮的模型——选错方向,树长得再好也是南辕北辙。 一、objective:g 与 h 的生产车间 第 2.2 节说过,objective 指定损失函数,损失函数决定每个样本的 g 与 h。

3.2 学习任务参数与评估指标选择

objective 决定 g 与 h 怎么算(训练往哪优化),eval_metric 决定谁说了算(模型怎么比高低),两者可以不同但必须配套。 本节整理常见任务的目标与指标搭配,用不均衡数据的实验演示"指标错配"的后果,并给出自定义损失的最小样例。

上一节把树形参数讲完。还剩一组"方向性"参数:它们不改变树的形状逻辑,却决定整个训练朝哪个方向收敛、以及最终选哪一轮的模型——选错方向,树长得再好也是南辕北辙。

一、objective:g 与 h 的生产车间

第 2.2 节说过,objective 指定损失函数,损失函数决定每个样本的 g 与 h。常用搭配按任务划分:

任务 objective 损失本质 输出形态
回归 reg:squarederror 平方损失 连续值
回归抗噪 reg:absoluteerror / huber 绝对值或混合 连续值
二分类 binary:logistic 对数损失 概率
二分类输出 logit binary:logitraw 对数损失 未过 sigmoid 的值
多分类 multi:softprob 多类对数损失 各类概率
排序 rank:pairwise 等 成对损失 分数

工程上最重要的纪律:objective 与输出解读必须一致。用 binary:logistic 训练后输出是概率,直接当"分数"排序没问题,但拿去做阈值 0.5 的硬分类前,最好先看概率分布——不均衡数据下 0.5 常常不是好阈值(本节第三部分实测)。

二、eval_metric:模型好坏谁说了算

eval_metric 只影响"评估与早停",不改变训练方向,这给了组合空间:训练用 logloss(可导、光滑,适合优化),选型看 AUC(不受阈值影响、不均衡友好)。看一个错配实验——极度不均衡的人造数据上,同一模型在不同指标下的表现:

import numpy as np from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score, roc_auc_score, average_precision_score import xgboost as xgb # 造 3% 正例的不均衡数据 X, y = make_classification(n_samples=6000, weights=[0.97, 0.03], flip_y=0.02, random_state=1) Xtr, Xte, ytr, yte = train_test_split(X, y, test_size=0.3, random_state=1) m = xgb.XGBClassifier(n_estimators=150, max_depth=4, eval_metric='logloss') m.fit(Xtr, ytr) proba = m.predict_proba(Xte)[:, 1] print(f"正例占比: {yte.mean():.3f}") print(f"准确率 accuracy : {accuracy_score(yte, proba > 0.5):.4f}") print(f"AUC : {roc_auc_score(yte, proba):.4f}") print(f"PR-AUC : {average_precision_score(yte, proba):.4f}") # 运行输出: # 正例占比: 0.031 # 准确率 accuracy : 0.9732 # AUC : 0.9318 # PR-AUC : 0.6407

准确率 0.973 看着漂亮,但全预测负例也有 0.969——准确率在这一刻几乎不携带模型信息;AUC 才暴露真实排序能力。指标错配不是学术洁癖,是会让团队在错误方向上自信满满的那种错误。早停也依赖 eval_metric:拿 accuracy 做早停,模型会在最粗暴的平台上停下,拿 logloss 或 auc 则能继续压榨。

三、自定义损失:把业务写进 g 与 h

XGBoost 允许用自定义目标函数替换内置 objective,只需给出梯度与二阶导数。一个实用例子——对高估惩罚两倍的非对称平方损失(比如库存场景:备多了浪费、断货更亏,两个方向代价不同):

import numpy as np import xgboost as xgb def asymmetric_squared(yhat, dtrain): y = dtrain.get_label() k = 2.0 # 高估方向的惩罚倍数 diff = yhat - y grad = np.where(diff > 0, k * diff, diff) # 一阶导 hess = np.where(diff > 0, k, 1.0) # 二阶导(该损失逐段为常数) return grad, hess rng = np.random.default_rng(3) X = rng.normal(size=(500, 4)) y = X[:, 0] * 1.5 + rng.normal(0, 0.3, 500) dtrain = xgb.DMatrix(X, label=y) booster = xgb.train({'tree_method': 'hist'}, dtrain, num_boost_round=80, obj=asymmetric_squared) pred = booster.predict(xgb.DMatrix(X)) over = np.mean(np.maximum(pred - y, 0)) under = np.mean(np.maximum(y - pred, 0)) print(f"平均高估 {over:.4f} 平均低估 {under:.4f}") # 运行输出: # 平均高估 0.1181 平均低估 0.3184

高估方向导数乘了 2,模型宁可多低估也不冒进——输出里低估量明显大于高估量,惩罚的方向性被忠实执行。注意二阶导数虽然这里逐段取常数(形式简单),但必须提供且量级要合理,否则第 2.2 节说的"曲率定价"会失真,训练变得又慢又差。

💡 关键直觉:选指标就选"和业务决策同构"的那个。阈值决策看精确率召回率,排序系统看 AUC 或 NDCG,回归报价看业务对称性。指标是模型与业务之间唯一的翻译官。

本节要点回顾

  • objective 生产 g 与 h,决定训练方向;reg、binary、multi、rank 四族按任务对号
  • eval_metric 只管评估与早停,可与训练目标不同,组合是常态
  • 不均衡实验:accuracy 0.973 几乎无信息量,AUC 才反映排序能力
  • 早停指标选错,模型会在错误的平台上提前停下
  • 自定义损失只需给出 grad 与 hess,非对称惩罚实验验证方向性生效

参数的含义与搭配都已明确,下一节把它们放进真实搜索流程:网格、随机、贝叶斯怎么选,调参顺序怎么排。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U