3.2 目标函数 (Objective Functions)


文档摘要

3.2 目标函数 (Objective Functions) 本节摘要:目标函数是模型的"北极星",通过 objective 参数指定,决定了模型在训练时到底要把什么量最小化。它和 metric 不是一回事:objective 是真正被优化的目标,metric 只是训练日志里观察用的仪表。本节按回归、二分类、多分类、排序四类任务逐一展开,重点对比 L1 与 L2、Huber 与 Fair、交叉熵与 Focal Loss、Softmax 多分类与 One-vs-All 之间的取舍,说明当数据有异常值、类别不平衡或需要预测分位数时,该把默认目标函数换成什么。 本节导航 阅读完本节,你应当能够: 说清 objective 与 metric 的本质区别,避免把"观察指标"误当成"优化目标"。

3.2 目标函数 (Objective Functions)

本节摘要:目标函数是模型的"北极星",通过 objective 参数指定,决定了模型在训练时到底要把什么量最小化。它和 metric 不是一回事:objective 是真正被优化的目标,metric 只是训练日志里观察用的仪表。本节按回归、二分类、多分类、排序四类任务逐一展开,重点对比 L1 与 L2、Huber 与 Fair、交叉熵与 Focal Loss、Softmax 多分类与 One-vs-All 之间的取舍,说明当数据有异常值、类别不平衡或需要预测分位数时,该把默认目标函数换成什么。

本节导航

阅读完本节,你应当能够:

  1. 说清 objective 与 metric 的本质区别,避免把"观察指标"误当成"优化目标"。
  2. 对比 L1、L2、Huber、Fair 对异常值的敏感程度,并给出各自适用场景。
  3. 解释 Quantile 回归与 Poisson 回归分别解决什么问题,以及它们的参数含义。
  4. 说明 Focal Loss 如何通过聚焦难样本缓解类别不平衡,gamma 参数起什么作用。
  5. 区分 multiclass 与 multiclassova 两种多分类实现,知道何时该选哪种。
  6. 了解 lambdarank 这类排序目标函数在优化什么,以及它要求怎样的数据组织方式。

一、目标函数是模型的北极星

在梯度提升里,每一轮训练都做同一件事:计算当前预测与真实值之间的"差距",再训练一棵新树去补这个差距。这里"差距"怎么算,就是目标函数说了算。它决定了模型的优化方向,也决定了最终学出来的模型对什么更宽容、对什么更敏感。

有个误区值得一开始就点破:目标函数和评估指标不是一回事。objective 是训练时真正被梯度优化的量,metric 只是你贴在日志上看的仪表。你可以一边用 binary 作为目标函数、一边用 auc 作为监控指标,两者完全可以不同。但反过来,如果你只盯着 metric 换着看,却把 objective 填错,那模型等于朝着错误的方向狂奔,仪表再好看也是白搭。

好在大多数时候,objective 不用你从头设计,LightGBM 内置了一套覆盖四大任务的现成目标函数。你真正要做的判断,往往只集中在一个问题上:我的数据有什么"脾气",默认的那个目标函数还吃不吃得消。

二、回归目标函数:围绕异常值的一场拉锯

回归默认的 objective 是 regression_l2,也就是均方误差。它算的是"预测值与真实值之差的平方",光滑可导、优化方便,所以成了默认。但平方这个动作会放大误差:真实值 100,预测 110,误差 10,平方后是 100;预测 130,误差 30,平方后变成 900。误差越大,被放得越狠。于是只要数据里混进几个离谱的异常值,模型就会为了迁就这几个点而整体跑偏。

这正是 L1 存在的理由。regression_l1 算的是误差的绝对值,不平方,异常值不会被几何级放大,模型更稳。代价是它在零点处不可导,收敛偶尔会慢一点,而且 L1 优化出来的结果更贴近中位数而非均值。一句话总结:数据干净、追求均值意义上的最优,选 L2;数据里有脏点、希望模型不被带偏,选 L1。

Huber 则想做"中间派":误差小的时候按平方算,享受 L2 的光滑;误差大的时候转成线性,享受 L1 的稳健。中间那个转折点由 huber_delta 参数控制,默认 1.0。Fair 是 Huber 的"远亲",思路类似——误差小时近似平方、误差大时近似线性,靠 fair_c 参数调节稳健程度。这俩适合"既担心异常值、又不想完全放弃小误差下的精度"的场景,属于比 L1 更精致的折中。

再往外走,还有两个针对特殊分布的成员。Quantile 回归解决的是"我不想预测均值,我想预测分位数"的需求,比如预测房价时给出一个"90% 情况下不会超过"的上限,比一个均值更有工程价值,alpha 参数就用来指定分位点。Poisson 回归则面向计数型数据——点击次数、事故起数这类非负整数,它假设目标服从泊松分布,用对数链接把线性预测映射成期望计数。

回归目标函数横向对比

目标函数 对异常值 优化点 典型场景
regression_l2 敏感 均值 数据干净、目标近似正态的默认选择
regression_l1 稳健 中位数 有异常值、想求稳健预测
huber 折中 均值与中位数之间 想兼顾小误差精度与大误差稳健
fair 折中 可调稳健度 需要比 Huber 更精细调节的场景
quantile 稳健 指定分位数 预测上限、下限、区间
poisson 视分布而定 期望计数 点击量、事故数等非负整数

三、分类目标函数:从概率出发

二分类的默认目标是 binary,也就是二元交叉熵。它要求模型输出样本属于正类的概率,然后衡量"这个概率离真实标签 0 或 1 有多远"。它有一个漂亮的特性:梯度光滑稳定,而且直接产出概率,做风控、点击率预估这类需要概率的场景特别顺手。

binary 有个容易忽视的盲区——类别不平衡。当正样本只占千分之一时,模型只要把所有样本都预测成负类,损失就已经很低了,它根本没有动力去学那稀少的正类。针对这个痛点,LightGBM 在较新版本里提供了 focal_loss。它的核心是 focal_loss_gamma 参数:gamma 越大,越会压低"已经分对的样本"的损失权重,让模型的注意力集中到"还分不对的难样本"上。gamma 为 0 时它退化成普通交叉熵;调到 1.0、2.0 时,对不平衡数据的改善通常很明显。

多分类的默认目标是 multiclass,用的是 Softmax 加多类交叉熵。Softmax 会把模型对每个类别的原始输出压成一个和为 1 的概率分布,模型要同时面对所有类别竞争。它需要你额外指定 num_class 告诉模型一共有几类。另一种选择是 multiclassova,也就是 One-vs-All:把多分类拆成若干个"这一类 vs 其余所有类"的二分类问题分别训练。类别数特别多、且某些类别之间区分度差异很大时,ova 有时会更稳,代价是训练成本随类别数线性上升。

分类目标函数横向对比

目标函数 适用任务 关键参数 特点
binary 二分类 默认选择,输出概率,梯度稳定
focal_loss 二分类 focal_loss_gamma 聚焦难样本,缓解类别不平衡
multiclass 多分类 num_class Softmax 多类竞争,默认选择
multiclassova 多分类 num_class 拆成多个二分类,类别多时更稳

四、排序目标函数:优化的是"顺序"而非"数值"

前两类目标函数关心的是"预测值准不准",排序任务关心的却是"排在前面的对不对"。搜索引擎、推荐系统里,用户只会看前几条结果,所以你并不需要精确预测每条结果的相关性分数,只需要让"更相关的排在更相关的上面"。

LightGBM 里最经典的排序目标是 lambdarank。它直接对列表整体的排序质量做优化,思想来自 LambdaRank 算法:不逐条看误差,而是看"任意两条结果的相对顺序排错会造成多大的 NDCG 损失",再把梯度按这个损失反传。因此它优化的是 NDCG 这类排序指标本身,而不是某个逐点的回归误差。使用它时,数据要按"查询"分组组织,同一个查询下的所有文档放在一组,还要告诉模型每组的样本数,这样才能在组内正确计算排序梯度。较新的版本还提供了 rank_xendcg 等面向 XENDCG 指标的目标函数,作为 lambdarank 的补充。

除了目标函数本身,排序任务对数据的组织方式还有额外要求。LightGBM 需要知道哪些样本属于同一次查询,才能在组内正确计算排序梯度。通常的做法是把同一个查询下的所有文档放在连续的位置,再用一个分组长度信息告诉模型每组各有多少条;组长度一旦搞错,梯度就会算串,模型学出来的排序关系也是错的。这也是排序任务比普通回归、分类更容易在数据准备阶段翻车的地方——它不是换一个字符串就能跑通,数据形状也得跟着改。

下面这张图把四类任务到目标函数的选择路径串了起来:

五、自定义目标函数与选择建议

内置的目标函数覆盖了绝大多数场景,但总有覆盖不到的时候——比如你要优化一个业务上自造的损失。LightGBM 允许你传入一个自定义目标函数,它接收真实值和预测值,返回一阶梯度和二阶梯度。对梯度提升来说,只要你能算出这两样东西,就能把任何光滑的损失函数接进来。这给了框架很大的弹性,但也要提醒一句:自定义目标函数意味着你要自己保证梯度的正确性,出错了框架不会帮你兜底,排查起来远比换一个内置字符串麻烦。

选目标函数的顺序,我的建议是:先看任务类型确定大类,再看数据脾气决定是否换掉默认值。数据干净就留在默认,有异常值就切 L1 或 Huber,类别不平衡就切 focal_loss,计数数据切 Poisson,要分位数切 Quantile,排序切 lambdarank。绝大多数项目走到这一步就够了,真到了需要自定义目标函数的那一天,你多半已经很清楚自己在做什么。

# 四类任务怎么填 objective,其余差异藏在数据形状与配套参数里 reg = {'objective': 'regression_l2'} bin_clf = {'objective': 'binary'} multi = {'objective': 'multiclass', 'num_class': 3} rank = {'objective': 'lambdarank'}

这四行几乎就是四类任务的开关语句,选定之后,剩下的工作才是围绕它去搭数据、配参数。很多人调参卡壳,其实卡在第一步就把 objective 当成了"随便填填"的选项,结果在错误的优化方向上反复折腾。记住:目标函数是这四类任务里最不该省的一次判断。

⚠️ 常见坑:切换 objective 时忘了同步改 metric,或者反过来只改 metric 不改 objective。前者会让你对着一个和优化目标脱节的数字误判早停时机,后者则根本改变不了模型学什么。两个字符串要一起审视。
💡 关键直觉:目标函数选错,模型练得再久也是在错误的方向上用力。与其纠结"哪个目标函数最强",不如先问一句"我的数据里,异常值、不平衡、分位数需求这三样占了哪一样"——答案往往直接指向正确选项。

温故知新

  • objective 是优化目标,metric 是观察仪表:两者可以不同,但 objective 才是决定模型学什么的关键。
  • L2 对异常值敏感,L1 稳健:数据干净选 L2,有脏点选 L1,Huber 与 Fair 是两者之间的折中。
  • Quantile 预测分位数,Poisson 处理计数:用 alpha 指定分位点,用对数链接拟合非负整数。
  • binary 输出概率但怕类别不平衡:focal_loss 靠 gamma 参数聚焦难样本,是不平衡数据的补救手段。
  • multiclass 用 Softmax 多类竞争:需要 num_class 指定类别数,ova 则是拆成多个二分类的替代方案。
  • lambdarank 优化排序质量:直接面向 NDCG,要求数据按查询分组组织。
  • 自定义目标函数是最后手段:能算出梯度就能接入,但要自己承担正确性责任。

目标函数决定了模型"往哪学",可模型学得好不好,最终还得靠评估指标来量。下一节我们就把各任务对应的评估指标串一遍,看看 auc 为什么比准确率更抗类别不平衡、NDCG 又凭什么能评价排序。


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