0. 写在前面

站内已有两篇相关文章: 《XGBoost梯度提升树建模教程》负责工程全景, 《从泰勒展开到 XGBoost 优化过程》负责泰勒先修课与测试题。本文只做一件事: 把”目标函数的泰勒展开与简化”从第一行推到最后一行, 一步不跳, 每步解说, 并补齐三件姊妹篇没展开的事: 余项是怎么算出来的、哪些常数会被吃掉、复杂度项 Ω 为什么不用展开。

前提仍然只有一个: 会加法和乘法。例外是第 2.3 节的余项推导需要一点分部积分, 不想看证明的读者可以只记结论框, 不影响主线。

1. 出发点: 第 t 轮的总目标

训练第 $t$ 棵树时, 前 $t-1$ 棵已经冻结。XGBoost 的总目标是:

\[Obj = \sum_{i=1}^{n} Loss(y_i,\ \hat{y}_i^t) + \sum_{j=1}^{t} \Omega(cart_j)\]
符号 含义
$n$ 训练样本总数
$y_i$ 样本 $i$ 的真实标签, 印死在数据里
$x_i$ 样本 $i$ 的特征向量, 同样印死在数据里
$\hat{y}_i^t$ 前 $t$ 棵树对样本 $i$ 的总预测
$f_t$ 第 $t$ 棵树 (本轮要新长的), 输入特征输出分数
$\Omega$ 复杂度罚单: $\Omega = \gamma T + \frac{1}{2}\lambda\sum_{j=1}^{T} w_j^2$
$T$ 当前这棵树的叶子数; $w_j$ 是第 $j$ 个叶子的分数
$\gamma,\ \lambda$ 罚单单价: 每片叶子收 $\gamma$, 叶子分数平方和按 $\lambda$ 收税
$g_i,\ h_i$ 损失对预测值的一阶、二阶导数 (第 5 节才会登场)

总目标的两半分工明确: 损失管”答得准不准”, 复杂度管”队伍臃不臃肿”。注意两者的待遇从一开始就不同: 损失项是”复杂函数裹着未知数”, 需要泰勒展开来拆解; 复杂度项是配角, 第 7 节会说明它为什么免检。

2. 预备: 泰勒模板与余项

2.1 0/1/2 阶模板

站在 $x$ 点, 想知道迈一小步 $\Delta$ 之后函数值变成多少:

\[f(x+\Delta) \approx f(x) + f'(x)\Delta + \frac{1}{2}f''(x)\Delta^2\]

三格含义: 旧值 (高度)、一阶项 (坡度 × 步长)、二阶项 (弯曲修正)。步长越小, 近似越准。

2.2 完整通式: 阶数没有上限

每升一阶, 导数多求一次、阶乘乘一个、步长多乘一次:

\[f(x+\Delta) = f(x) + f'(x)\Delta + \frac{f''(x)}{2!}\Delta^2 + \frac{f'''(x)}{3!}\Delta^3 + \cdots\]

所以”只用 0、1、2 阶”从来不是泰勒展开的极限, 而是后文会论证的一个刻意选择。

2.3 余项是什么, 怎么算出来的

泰勒定理的诚实形态: 截断到 $n$ 阶后, 下面这个等式是精确成立的:

\[f(x+\Delta) = f(x) + f'(x)\Delta + \cdots + \frac{f^{(n)}(x)}{n!}\Delta^n + R_n\]

差额 $R_n$ 就是余项。对二阶截断 ($n=2$), 结论是:

\[R_2 = \frac{f'''(\xi)}{6}\Delta^3, \qquad \xi \text{ 在 } x \text{ 与 } x+\Delta \text{ 之间}\]

这个式子是怎么来的? 下面用四步推出来。工具是分部积分 (乘积求导法则的逆向操作), 这是全篇唯一需要微积分的地方。

第 1 步 (微积分基本定理): 函数值的增量等于导数的积分:

\[f(x+\Delta) = f(x) + \int_x^{x+\Delta} f'(t)\,dt\]

第 2 步 (第一次分部积分): 对右边的积分取 $u = f’(t)$, $dv = dt$, 并故意选 $v = t - x - \Delta$ (让上限处 $v=0$, 结果干净):

\[\int_x^{x+\Delta} f'(t)\,dt = \Big[f'(t)(t-x-\Delta)\Big]_{t=x}^{t=x+\Delta} - \int_x^{x+\Delta} (t-x-\Delta)f''(t)\,dt\]

代入上下限: 上限处 $f’(x+\Delta)\cdot 0 = 0$; 下限处 $f’(x)\cdot(-\Delta) = -\Delta f’(x)$。差值为 $0 - (-\Delta f’(x)) = \Delta f’(x)$。再把 $(t-x-\Delta) = -(x+\Delta-t)$ 的负号收进积分:

\[= f'(x)\Delta + \int_x^{x+\Delta} (x+\Delta-t)\,f''(t)\,dt\]

第 3 步 (第二次分部积分): 对新出现的积分取 $u = f’‘(t)$, $dv = (x+\Delta-t)dt$, 则 $v = -\frac{1}{2}(x+\Delta-t)^2$:

\[\int_x^{x+\Delta} (x+\Delta-t)f''(t)\,dt = \Big[-\frac{1}{2}(x+\Delta-t)^2 f''(t)\Big]_{t=x}^{t=x+\Delta} + \int_x^{x+\Delta} \frac{1}{2}(x+\Delta-t)^2 f'''(t)\,dt\]

上限处 $-\frac{1}{2}\cdot 0^2 \cdot f’‘(x+\Delta) = 0$; 下限处 $-\frac{1}{2}\Delta^2 f’‘(x)$。差值为 $\frac{1}{2}\Delta^2 f’‘(x)$。

第 4 步 (合并 + 积分中值定理): 把三块拼回去, 等式已经精确成立:

\[f(x+\Delta) = f(x) + f'(x)\Delta + \frac{1}{2}f''(x)\Delta^2 + \underbrace{\int_x^{x+\Delta} \frac{1}{2}(x+\Delta-t)^2 f'''(t)\,dt}_{\text{积分形式的余项 } R_2}\]

余项里的权重 $\frac{1}{2}(x+\Delta-t)^2$ 在积分区间上连续非负, 由积分中值定理, 存在某个 $\xi$ 让 $f’’’(\xi)$ 提到积分号外:

\[R_2 = \frac{f'''(\xi)}{2}\int_x^{x+\Delta}(x+\Delta-t)^2\,dt = \frac{f'''(\xi)}{2}\cdot\frac{\Delta^3}{3} = \frac{f'''(\xi)}{6}\Delta^3\]

(最后那个积分换元 $u = x+\Delta - t$ 后就是 $\int_0^{\Delta} u^2 du = \Delta^3/3$。)

结论框: 二阶截断的余项 = “下一阶 (三阶) 导数在途中某点的取值 ÷ 6 × 步长的三次方”。误差由两件事决定: 被扔掉的下一阶导数有多大, 以及步长的三次方有多小。

2.4 余项的两副面孔: 尾项之和与单项压缩

一个很自然的疑问: 误差不就是”截到 2 阶后, 第 3 阶起所有剩余项之和”吗? 为什么上面只写了一项 $\frac{f’’’(\xi)}{6}\Delta^3$?

答案是: 两者严格相等, 是同一个余项的两副面孔。

面孔 A (级数尾项): 把没写出来的全部展开:

\[R_2 = \frac{f'''(x)}{3!}\Delta^3 + \frac{f^{(4)}(x)}{4!}\Delta^4 + \frac{f^{(5)}(x)}{5!}\Delta^5 + \cdots\]

面孔 B (拉格朗日余项):

\[R_2 = \frac{f'''(\xi)}{6}\Delta^3, \qquad \xi \in (x,\ x+\Delta)\]

泰勒定理的内容就是 A = B: 左边是无穷多项的累加, 右边奇迹般地只剩一项, 三阶导数在途中某个点 $\xi$ 的取值。$\xi$ 具体是谁不知道, 只知道它保证存在。

压缩是怎么发生的? 2.3 节四步分部积分的终点已经给出了答案: 余项先以积分形式出现:

\[R_2 = \int_x^{x+\Delta} \frac{1}{2}(x+\Delta-t)^2 f'''(t)\,dt\]

这个积分正是”所有高阶项之和”的打包形态 (它等于 3 阶、4 阶、……无穷项的总和)。然后积分中值定理只做一步: 权重函数连续非负, 整个积分就等于某个中间点处的 $f’’’(\xi)$ 乘以权重函数自身的积分值 ($\Delta^3/6$)。一句话: 无穷尾项, 打包成一个积分, 压缩成一个中间点的导数值。

两个可亲手验证的例子:

  • $f(t)=t^3$ (三阶导是常数 6): 精确展开是 $x^3 + 3x^2\Delta + 3x\Delta^2 + \Delta^3$, 截到 2 阶后尾项之和恰为 $\Delta^3$; 拉格朗日给 $\frac{6}{6}\Delta^3 = \Delta^3$, 分毫不差, 且 $f’’’$ 是常数, $\xi$ 是谁都无所谓。
  • $f(t)=e^t$ 在 $x=0$ 处截到 2 阶、取 $\Delta=1$: 尾项之和 $= e - (1+1+\frac{1}{2}) = 0.21828$; 拉格朗日声称 $\frac{e^{\xi}}{6} = 0.21828$, 解出 $\xi \approx 0.269$, 确实落在 $(0,1)$ 区间内。

那为什么工程上写 B 不写 A? 三个理由:

  1. A 没法估大小, B 可以。 A 含无穷多个未知系数, 算不完也控不住; B 只有一个未知点 $\xi$, 而 $\xi$ 被夹在区间里, 只要取”区间内 $|f’’’|$ 的最大值 $M_3$”, 立刻得到可用上界:
\[|R_2| \le \frac{M_3}{6}|\Delta|^3\]

“敢不敢扔余项”要的从来不是余项的定义, 而是这个能拍在桌面上的上界。

  1. B 的适用条件更宽。 面孔 A 要求函数能展开成收敛回自身的级数 (解析函数); 有些光滑函数 (如 $e^{-1/x^2}$) 的泰勒级数并不收敛回它自己, 尾项之和的画像在那里失灵。拉格朗日余项只要求三阶可导, 依然成立。

  2. 还有第三种最省事的写法: 皮亚诺余项 $R_2 = o(\Delta^3)$, 只声明”是比 $\Delta^3$ 更高阶的小量”, 连 $\xi$ 都不要, 适合只关心误差的阶、不关心数值的场合。

一句话总结: 尾项之和是余项的名词解释, 拉格朗日余项是它的可操作定义; 判断”该不该扔”需要的是后者给出的上界, 而不是前者给出的定义。

2.5 从余项看截断的代价

一般地, 截断到 $n$ 阶的余项量级是 $f^{(n+1)}(\xi)\cdot\Delta^{n+1}/(n+1)!$。它交代了”≈”的底气: 只要步长小, 误差按步长的幂次快速塌缩; 而误差的上限由被扔掉的下一阶导数控制。记住这个结构, 第 8 节判断”该不该丢”时全靠它。

3. 第一步加工: 拆分总预测

加法模型说: 总预测 = 所有树输出的总和。把前 $t-1$ 项的和命名为 $\hat{y}_i^{t-1}$:

\[\hat{y}_i^t = \underbrace{f_1(x_i) + \cdots + f_{t-1}(x_i)}_{=\ \hat{y}_i^{t-1}} + f_t(x_i) = \hat{y}_i^{t-1} + f_t(x_i)\]

代入总目标的损失项 (这一步只是代入, 没有任何近似):

\[\sum_{i=1}^{n} Loss\big(y_i,\ \hat{y}_i^{t-1} + f_t(x_i)\big)\]

新树不重新预测, 只在旧预测上加一个修正量 —— 这就是”补差价”。

4. 第二步加工: 把二元 Loss 折叠成一元 L

$Loss(y, \hat{y})$ 有两个输入槽。训练第 $t$ 轮时, 标签 $y_i$ 印死在数据里、永远不变, 于是可以把它焊死在第一个槽里, 得到单变量函数:

\[L_i(\cdot) \equiv Loss(y_i,\ \cdot) \quad\Longrightarrow\quad \sum_{i=1}^{n} L_i\big(\hat{y}_i^{t-1} + f_t(x_i)\big)\]

三点澄清:

  1. $L$ 和 $Loss$ 是同一条计算规则, 不是两个函数。$Loss$ 是两槽机器, $L_i$ 是”标签槽焊死后的单槽机器”。好比评分规则与”按你的答卷定制的评分规则”。
  2. $L_i$ 带下标: 每个样本的 $y_i$ 不同, 焊出来的曲线各不相同。文档里常把下标省掉, 读者要心里补上。
  3. 后面所有对 $L$ 的求导, 求导对象都是预测值 (唯一的活槽), 这为 $g, h$ 的定义铺路。

5. 第三步加工: 逐样本套用泰勒模板

对照模板 $f(x+\Delta) \approx f(x) + f’(x)\Delta + \frac{1}{2}f’‘(x)\Delta^2$, 逐一认领角色:

模板中的角色 本场景中的身份
函数 $f$ $L_i$ (样本 $i$ 的单变量损失)
展开点 $x$ 旧预测 $\hat{y}_i^{t-1}$ (已冻结)
步长 $\Delta$ 新树输出 $f_t(x_i)$ (未知, 要优化)

原样填入三个格子:

\[L_i\big(\hat{y}_i^{t-1} + f_t(x_i)\big) \approx \underbrace{L_i(\hat{y}_i^{t-1})}_{\text{旧损失}} + \underbrace{L_i'(\hat{y}_i^{t-1})\cdot f_t(x_i)}_{\text{坡度}\times\text{步长}} + \underbrace{\frac{1}{2}L_i''(\hat{y}_i^{t-1})\cdot f_t^2(x_i)}_{\text{半}\times\text{弯曲}\times\text{步长}^2}\]

给两个导数起名字 (这就是 $g, h$ 的全部出身):

\[g_i \equiv L_i'(\hat{y}_i^{t-1}),\qquad h_i \equiv L_i''(\hat{y}_i^{t-1})\]

注意: 求导在旧预测处”一次性算完”, 所以对第 $t$ 棵树而言 $g_i, h_i$ 只是两个已知的数字, 每个样本各一对。损失项成为:

\[\sum_{i=1}^{n}\Big[L_i(\hat{y}_i^{t-1}) + g_i f_t(x_i) + \frac{1}{2}h_i f_t^2(x_i)\Big]\]

6. 第四步加工: 常数审查 — 哪些被吃掉, 哪些是变量

判据只有一条: 这一项的数值, 会不会因为”第 $t$ 棵树长成什么样”而改变? 不会的, 都是常数。

\[\underbrace{\sum_{i=1}^{n} L_i(\hat{y}_i^{t-1})}_{\text{常数 A}} + \underbrace{\sum_{i=1}^{n}\Big[g_i f_t(x_i) + \frac{1}{2}h_i f_t^2(x_i)\Big]}_{\text{随 } f_t \text{ 变}} + \underbrace{\sum_{j<t}\Omega(cart_j)}_{\text{常数 B}}\]
项 判定 理由
$\sum_i L_i(\hat{y}_i^{t-1})$ 被吃掉的常数 旧预测由冻结老树决定, $y_i$ 是数据, 都动不了
$\sum_{j<t}\Omega(cart_j)$ 被吃掉的常数 老树的罚单金额已定, 与新树无关
$g_i,\ h_i$ 不是被吃, 是被”提前消化” 它们在冻结点一次性算完, 把 $y_i$ 和旧预测的信息打包成已知系数, 是新树唯一能看到的”错误报告”
$f_t(x_i),\ f_t^2(x_i)$ 变量 新树还没长, 输出未定, 正是优化对象
$\Omega(f_t)$ 变量 新树的叶子数和叶子值未定

为什么常数可以放心删? 训练要做的是”比较哪棵新树更好”, 比较看的是目标函数的差值, 两个候选树的差值里常数自动抵消, 删掉它们不改变谁优谁劣。删完常数、留新树自己的罚单, 就得到本文的主角 (第 9 节)。

7. 复杂度项 Ω: 为什么不需要展开, 如何处理

\[\Omega(f_t) = \gamma T + \frac{1}{2}\lambda\sum_{j=1}^{T} w_j^2\]

它不需要泰勒展开, 三个理由:

  1. 直接可算: 拿到任何候选树, 数叶子、读叶子分数, 罚单当场算出, 中间没有非线性外壳。
  2. 它已经是二次多项式: 泰勒展开的产出是多项式, 而 Ω 出厂即是关于 $w_j$ 的二次式, 和展开后的损失”同一种语言”, 拼接后每个叶子的目标依然是干净的抛物线。
  3. 对它做展开是白费功夫甚至无意义: 对二次函数做二阶泰勒展开会零误差地返回它自己 (余项为零, 就是 $x^2$ 例子的结论); 更严格地, Ω 里的 $T$ 是叶子数, 一个离散整数, 泰勒展开对连续变量定义, 对 $T$ 连”展开”这个操作都不存在。

它如何处理? 分两笔账: 老树的 $\sum_{j<t}\Omega$ 是常数, 第 6 节已经吃掉; 新树的 $\Omega(f_t)$ 原样保留进最终目标 (不展开、不变形), 等到按叶子分组时, $\frac{1}{2}\lambda\sum w_j^2$ 会自然拆到每个叶子头上, 变成叶子权重公式分母里的 $\lambda$。

往深一层: Ω 的形状是刻意选的。选二次的 $\frac{1}{2}\lambda\sum w_j^2$, 就是为了和展开后的损失无缝拼装、保住凸碗和闭式解。反例: 若换成 L1 的 $\alpha\sum|w_j|$, 抛物线在 $w=0$ 处折出尖角, 解退化成分段软阈值; 若换成非线性项, 碗直接碎掉。

8. 丢弃余项的三个理由

把 2.3 节的精确等式接到本场景 ($f \to L_i$, $x \to \hat{y}_i^{t-1}$, $\Delta \to f_t(x_i)$):

\[L_i\big(\hat{y}_i^{t-1} + f_t(x_i)\big) = L_i(\hat{y}_i^{t-1}) + g_i f_t(x_i) + \frac{1}{2}h_i f_t^2(x_i) + \frac{L_i'''(\xi)}{6}f_t^3(x_i)\]

我们扔掉的最后一项 $R = \frac{L_i’’’(\xi)}{6}f_t^3(x_i)$, 理由按说服力排序:

理由一: 它量级极小, 且错误会被下一轮自动修复。 新树的贡献要乘学习率 (如 0.1), 步长 $\Delta$ 的量级约 0.1, $\Delta^3$ 就是千分之一量级; 更关键的是 XGBoost 是迭代算法, 下一轮会在新位置用全新的 $g, h$ 重新展开, 这一轮近似的残余误差, 下一轮开头就被重新计算纠正。展开只需要”这一小步内够准”, 不需要全局精确。

理由二: 保留它反而把题做坏。 留下三阶项, 每个叶子面对的目标变成三次多项式 —— 奇次多项式两端必有一端冲向 $-\infty$, 最小值根本不存在, 闭式解全部报废。高阶项不是”锦上添花用不上”, 而是”直接破坏可解性”。

理由三: 对照竞争者, 2 阶是唯一甜蜜点。 截断到 1 阶 (GBDT 路线), 目标是线性函数, 没有最低点, 只能拟合负梯度沿坡盲走, 步长要靠外部 line search 补; 截断到 2 阶, 方向和步长齐备, 目标是有唯一碗底的二次函数, 一次除法解出叶子值; 截断到 3 阶以上, 想知道的”步长在移动中怎么变”对单轮一小步毫无用处。取舍标准不是”越准越好”, 而是”这一轮用得上, 且这一轮解得动” —— 同时满足两条的恰好只有 2 阶。

9. 简化后的最终目标函数

把第 3~7 节的四步加工全部落定, 得到 XGBoost 每一轮真正求解的目标:

\[\boxed{\ Obj^t \approx \sum_{i=1}^{n}\Big[g_i f_t(x_i) + \frac{1}{2}h_i f_t^2(x_i)\Big] + \Omega(f_t)\ }\]

其中 $\Omega(f_t) = \gamma T + \frac{1}{2}\lambda\sum_{j=1}^{T}w_j^2$, $g_i = L_i’(\hat{y}_i^{t-1})$, $h_i = L_i’’(\hat{y}_i^{t-1})$。

这就是”展开与简化”的终点。它的下一站 (本文不展开, 详见《从泰勒展开到 XGBoost 优化过程》的 4.6 节与《XGBoost梯度提升树建模教程》的第 3 章): 把样本按”落在哪个叶子”分组, 记叶内 $g$ 之和为 $G_j$、$h$ 之和为 $H_j$, 每个叶子的目标成为 $G_j w_j + \frac{1}{2}(H_j+\lambda)w_j^2$, 抛物线求最低点解出 $w_j^* = -\frac{G_j}{H_j+\lambda}$, 再代回可得分裂增益与 $\gamma$ 剪枝。

10. 案例一: MSE (平方损失) 的 g 与 h

平方损失 (预测槽记为 $z$):

\[L(z) = \frac{1}{2}(z - y)^2\]

逐步求导: 幂规则求导, 系数 $\frac{1}{2}$ 与求导产生的 2 相消:

\[L'(z) = 2\cdot\frac{1}{2}\cdot(z-y) = z - y \quad\Longrightarrow\quad g = \hat{y}_i^{t-1} - y\] \[L''(z) = 1 \quad\Longrightarrow\quad h = 1\]

三格填入: 旧损失 $\frac{1}{2}(\hat{y}_i^{t-1}-y)^2$, 坡度项 $(\hat{y}_i^{t-1}-y)f_t(x_i)$, 弯曲项 $\frac{1}{2}f_t^2(x_i)$。

数字验证: 取 $y=1$, $\hat{y}_i^{t-1}=0.4$, 则 $g = -0.6$, $h = 1$, 近似式 $= 0.18 - 0.6f + 0.5f^2$; 精确值 $\frac{1}{2}(0.4+f-1)^2 = \frac{1}{2}(f-0.6)^2 = 0.18 - 0.6f + 0.5f^2$ —— 分毫不差。原因: 平方损失本身就是二次多项式, 二阶展开把它写尽了, 余项恒为零。

顺带一个观察: $h\equiv 1$ 时, 叶子值公式 $w^* = -G/(H+\lambda)$ 里 $G = \sum(\hat{y}-y)$ 恰是负残差之和, $\lambda=0$ 时 $w^*$ 就是叶内残差均值 —— 平方损失下 GBDT 的残差拟合与 XGBoost 几乎重合, 两者的差异要在非二次损失上才显现。

11. 案例二: 交叉熵 (含二元交叉熵特例) 的 g 与 h

11.1 公式与”激活”怎么看

一般形式 (C 类): $l = -\sum_{c=1}^{C} y_c \log p_c$, 其中 $y_c$ 是 one-hot 标签, $p_c$ 是模型给的各类概率。

二分类是它的特例: 类别只有两个, 概率 $\hat{y}$ 与 $1-\hat{y}$, 标签 $y$ 与 $1-y$, 求和只有两项:

\[Loss(y,\ \hat{y}) = -\big[y\log(\hat{y}) + (1-y)\log(1-\hat{y})\big]\]

每个选项激活哪一项怎么看: 看系数。$y\log(\hat{y})$ 的系数是 $y$, $(1-y)\log(1-\hat{y})$ 的系数是 $(1-y)$; $y$ 只能取 0 或 1, 把值代进去, 乘 0 的那项当场消失 —— 任何时刻恰好一项存活:

  • $y=1$: 激活 $-\log(\hat{y})$, 含义是”模型押给正确答案 (类 1) 的概率取负对数”;
  • $y=0$: 激活 $-\log(1-\hat{y})$, 同理换成了类 0 的那份押注。

数字感受: $y=1,\ \hat{y}=0.9$: 损失 $=-\log 0.9 \approx 0.105$; $y=0,\ \hat{y}=0.9$: 损失 $=-\log 0.1 \approx 2.303$。同一个预测值, 答对近乎免罚, 答错重罚。

11.2 为什么取负号

$\hat{y} \in (0,1)$, 而小于 1 的数取 log 恒为负。负号完成一次翻转: 全对 (押满概率) = 0 分, 越错分越大, 这才配叫损失, 优化器才能照常”越小越好”地工作。统计视角下, 负号把”极大化似然”翻译成”极小化损失”; 信息论视角下, $-\log p$ 是”惊讶度”: 必然事件零惊讶, 小概率事件发生则惊讶度冲向无穷。

11.3 方括号里为什么相加

那不是两笔罚金相加, 而是用加法写出的 if-else: 系数 $y$ 与 $(1-y)$ 恒有一个为 0, 加法只是让两个分支共用一行公式。额外好处: 若以后做标签平滑 (标签不再是纯 0/1), 这个形式一个字都不用改。

11.4 交叉熵和熵的区别

看 log 前面站的是谁:

\[\text{熵 } H(p) = -\sum p\log p \qquad\text{vs}\qquad \text{交叉熵 } H(p,q) = -\sum p\log q\]

熵是自己乘自己, 度量一个分布自身的不确定性, 与模型无关; 交叉熵是真相加权模型, 度量”真相按 $p$ 说话、你却按 $q$ 唱”要付的代价。两者相差 $H(p,q) = H(p) + KL(p|q)$。本文场景里标签是硬标签 (纯 0 或 1), 真实分布是 one-hot, 它自身的熵为 0 —— 所以二元交叉熵里其实一点”熵”的成分都没有, 纯粹是”模型押给正确答案的概率取负对数”, 叫交叉熵只是信息论的家谱叫法。

11.5 逐步求导: g = p − y, h = p(1−p)

设 margin 为 $z$, 概率 $p = \sigma(z) = 1/(1+e^{-z})$, 损失 $l = -[y\log p + (1-y)\log(1-p)]$, 求导对象是 $z$。

第一步: $l$ 对 $p$ 求导 (log 的导数是 1/自变量, 第二项链式多出一个负号):

\[\frac{\partial l}{\partial p} = -\Big[\frac{y}{p} + (1-y)\cdot\frac{-1}{1-p}\Big] = -\frac{y}{p} + \frac{1-y}{1-p}\]

第二步: 通分到 $p(1-p)$:

\[= \frac{-y(1-p) + (1-y)p}{p(1-p)} = \frac{-y + yp + p - yp}{p(1-p)} = \frac{p-y}{p(1-p)}\]

第三步: $p$ 对 $z$ 求导 (复合函数求导):

\[\frac{dp}{dz} = -\big(1+e^{-z}\big)^{-2}\cdot\big(-e^{-z}\big) = \frac{e^{-z}}{(1+e^{-z})^2}\]

而 $p(1-p) = \frac{1}{1+e^{-z}}\cdot\frac{e^{-z}}{1+e^{-z}} = \frac{e^{-z}}{(1+e^{-z})^2}$, 恰好相等, 所以:

\[\frac{dp}{dz} = p(1-p)\]

第四步: 链式法则相乘, 灾难性消项:

\[g = \frac{\partial l}{\partial z} = \frac{p-y}{p(1-p)}\cdot p(1-p) = p - y\]

第五步: 再求一次导得 $h$ (对 $z-y$ 求导, $y$ 是常数):

\[h = \frac{\partial^2 l}{\partial z^2} = \frac{\partial}{\partial z}(p-y) = \frac{dp}{dz} = p(1-p)\]

sigmoid 的导数自带 $p(1-p)$, 与交叉熵的梯度精准互消 —— 这对”天生配对”是 $g$ 公式如此干净的原因。

11.6 交叉熵是多项式吗 (澄清一个易混点)

不是。 多项式只允许变量之间加减乘与非负整数次幂, 而 $-\log(\cdot)$ 含对数, 交叉熵不是多项式。多项式性来自泰勒展开, 不来自交叉熵本身: 展开后它在旧预测附近的局部近似 $l(\hat{y}^{t-1}) + g\cdot f + \frac{1}{2}h\cdot f^2$ 才是二次多项式。这恰恰是泰勒展开的价值所在 —— 把任意光滑损失局部”多项式化”, 统一塞进抛物线求最低点的框架。平方损失是幸运的特例 (本身就是多项式, 展开零误差); 交叉熵是常态的例子 (展开是近似, 余项非零, 但第 8 节已经论证可以放心扔)。

11.7 数字验证

$y=1,\ p=0.2$: $g = 0.2-1 = -0.8$ (强烈要求把分数往上推), $h = 0.2\times 0.8 = 0.16$。 $y=0,\ p=0.8$: $g = 0.8-0 = 0.8$ (强烈要求往下压), $h = 0.16$。 $p$ 越靠近 0 或 1, $h$ 越接近 0: 模型对笃定的预测不再提供曲率信息, 这也是 min_child_weight 要给 $H$ 设下限的原因。

12. 全链路总结

一条线串起全文:

\[\text{总目标} \xrightarrow{\text{拆分总预测}} \text{补差价形式} \xrightarrow{\text{折叠 } L} \text{一元损失} \xrightarrow{\text{二阶泰勒}} \text{三格展开} \xrightarrow{\text{吃掉常数}} \text{留下变量与 } \Omega(f_t)\]

最终式:

\[Obj^t \approx \sum_{i=1}^{n}\Big[g_i f_t(x_i) + \frac{1}{2}h_i f_t^2(x_i)\Big] + \gamma T + \frac{1}{2}\lambda\sum_{j=1}^{T}w_j^2\]

五个关键记忆点: 一, $g, h$ 是泰勒机器在旧预测处一次性算完的已知数字, MSE 下是 $\hat{y}-y$ 与 $1$, 交叉熵下是 $p-y$ 与 $p(1-p)$; 二, 被吃掉的只有两类常数 (旧损失、老树罚单), 因为它们不随新树变化; 三, Ω 不需要展开, 因为它出厂就是二次多项式, 且 $T$ 是离散量根本没有展开操作; 四, 丢掉的余项是 $\frac{L’’’}{6}f_t^3$, 量级千分之一、下轮自修复、保留反而砸掉闭式解; 五, “交叉熵是多项式”是错觉, 多项式性来自展开而非损失本身。