
机器学习数学推导(十二):XGBoost 与 LightGBM
从 XGBoost 的二阶泰勒展开到 LightGBM 的直方图加速,本文系统推导两大工业级梯度提升框架——正则化目标函数、分裂增益闭式解、GOSS 单边采样与 EFB 互斥特征绑定的数学原理。
XGBoost 和 LightGBM 是表格数据领域的两大利器——从 Kaggle 排行榜到风控系统、广告排序和用户流失预测,背后几乎都有它们的身影。两者都基于梯度提升树(Gradient-Boosted Trees,见第 11 篇),但在工程设计上选择了截然不同的方向:
- XGBoost 主攻数学优化:把损失函数的二阶导数引入目标函数,对树结构本身做正则化,并将分裂点选择转化为一个闭式解公式。
- LightGBM 主攻系统效率:将特征离散化为小直方图,按叶子节点逐层生长,丢弃信息量低的样本(GOSS),并合并互斥的稀疏特征(EFB)。
从 API 看,两者似乎可以无缝替换,但当数据量 $N$ 或特征维度 $d$ 增大时,它们的表现差异会变得非常明显。本文将推导这些设计背后的每一个公式,让你在阅读调参指南时,能清楚知道每个参数存在的原因。

你将学到什么#
- XGBoost 的二阶泰勒展开如何直接计算出最优叶权重的闭式解,以及任意树结构的“结构分数”。
- 分裂增益公式中为什么自带一个剪枝惩罚项 $\gamma$ 。
- LightGBM 的直方图算法怎样把单特征分裂的复杂度从 $O(N)$ 降到 $O(K)$ ,并实现“直方图减法”技巧。
- GOSS 的统计学原理是什么,EFB 的具体构造方法又是怎样的。
- 按层生长和按叶子生长分别在什么情况下表现更好。
前置知识#
- GBDT 基础(本系列第 11 篇)。
- 一阶和二阶泰勒展开。
- 使用不纯度和增益进行决策树分裂。
一张图看懂 Boosting#
先别管公式,直接看梯度提升到底在干什么。我们从一个常数预测开始(也就是 $y$ 的均值),然后让每棵新树去拟合当前的残差。前面的树抓住大趋势,后面的树专注于修正局部细节。

第一棵树拟合完后,结果是个粗糙的阶梯函数,残差非常大;等累积到一百棵小步长树($\eta = 0.1$ )后,整体已经捕捉到了底层的 $\sin(1.5x) + 0.35x$ 趋势,残差基本变成了噪声。XGBoost 和 LightGBM 的区别只在于它们拟合每棵树的具体方法——但上面这个迭代框架是完全一样的。
XGBoost:把数学做到极致#
正则化目标函数#
$$ \mathcal{L}^{(t)} \;=\; \sum_{i=1}^N L\bigl(y_i,\; \hat y_i^{(t-1)} + f_t(\mathbf{x}_i)\bigr) \;+\; \Omega(f_t), $$ $$ \Omega(f_t) \;=\; \gamma\, T \;+\; \tfrac{1}{2}\lambda \sum_{j=1}^T w_j^2. $$- $T$ 是叶子节点的数量,$\gamma T$ 是每片叶子的成本,相当于一个软剪枝阈值。
- $w_j$ 是叶子 $j$ 的预测值,$\tfrac{1}{2}\lambda \sum w_j^2$ 是对叶子权重的 L2 收缩。
二阶泰勒展开#
$$ L\bigl(y_i,\; \hat y_i^{(t-1)} + f_t(\mathbf{x}_i)\bigr) \;\approx\; L\bigl(y_i,\; \hat y_i^{(t-1)}\bigr) + g_i\, f_t(\mathbf{x}_i) + \tfrac{1}{2}h_i\, f_t(\mathbf{x}_i)^2, $$ $$ g_i \;=\; \partial L / \partial \hat y_i^{(t-1)}, \qquad h_i \;=\; \partial^2 L / \partial (\hat y_i^{(t-1)})^2. $$ $$ \widetilde{\mathcal{L}}^{(t)} \;=\; \sum_{i=1}^N \Bigl[g_i\, f_t(\mathbf{x}_i) + \tfrac{1}{2}h_i\, f_t(\mathbf{x}_i)^2\Bigr] + \Omega(f_t). $$这是 XGBoost 和传统 GBDT 的核心区别:二阶导数 $h_i$ 进入了目标函数,相当于免费拿到了牛顿法的曲率信息。
最优叶权重与结构分数#
$$ G_j = \sum_{i \in I_j} g_i, \qquad H_j = \sum_{i \in I_j} h_i. $$ $$ \widetilde{\mathcal{L}}^{(t)} \;=\; \sum_{j=1}^T \Bigl[G_j\, w_j + \tfrac{1}{2}(H_j + \lambda)\, w_j^2\Bigr] + \gamma T. $$ $$ \boxed{\,w_j^{*} \;=\; -\frac{G_j}{H_j + \lambda}\,} $$ $$ \widetilde{\mathcal{L}}^{*}(q) \;=\; -\frac{1}{2}\sum_{j=1}^{T}\frac{G_j^2}{H_j + \lambda} \;+\; \gamma T. $$分数越低越好。注意,结构分数只依赖于树结构 $q$ ,权重已经被解析地优化掉了。这样一来,树学习就变成了结构搜索问题。
分裂增益#
$$ \boxed{\;\text{Gain} \;=\; \frac{1}{2}\!\left[\frac{G_L^2}{H_L+\lambda} + \frac{G_R^2}{H_R+\lambda} - \frac{(G_L+G_R)^2}{H_L+H_R+\lambda}\right] - \gamma\;} $$这里有两点值得注意:
- 中括号里的部分是结构分数和的下降量,在减去 $\gamma$ 之前总是非负的(柯西–施瓦茨/方差分解)。
- 常数 $\gamma$ 直接充当分裂的阈值:如果结构改善不足以超过 $\gamma$ ,分裂就会被拒绝。不需要额外的后剪枝步骤,剪枝已经内嵌在增益公式里。
常见损失函数的梯度#
| 损失 | $g_i$ | $h_i$ |
|---|---|---|
| 平方损失 $\tfrac{1}{2}(y-\hat y)^2$ | $\hat y_i - y_i$ | $1$ |
| Logistic ($p = \sigma(\hat y)$ ) | $p_i - y_i$ | $p_i(1-p_i)$ |
| Softmax (类别 $c$ ) | $p_{ic} - \mathbb{1}[y_i = c]$ | $p_{ic}(1-p_{ic})$ |
平方损失的 $h_i \equiv 1$ ,二阶目标退化为普通的残差拟合,XGBoost 就回到了 GBDT。Logistic 和 Softmax 的海森矩阵携带了真实信息(饱和区 $p(1-p)$ 很小),牛顿步的优势明显。
分裂查找算法#
有了增益公式,剩下的问题就是如何枚举候选分裂点。把每个特征都预排序就是精确算法,单特征单节点复杂度是 $O(N)$ ;近似算法只挑少量候选分位点(用 $h_i$ 加权,因为 $h_i$ 在二次目标中代表样本重要性)。稀疏感知变体在每次分裂时学习一个“缺失值默认走向”,遍历时只扫非缺失项——在稀疏 one-hot 数据上效果显著。

左图扫描所有不同取值(共 $N-1$ 个候选)。右图把同一份数据分成 $K = 32$ 个桶,只评估 $K-1$ 个候选切点——却几乎选到了同一个阈值、同一个增益。这正是 LightGBM 的核心思路:$N$ 维度的分辨率大部分都是浪费。
LightGBM:极致的工程优化#

直方图算法#
$$ G_b \;=\; \sum_{i:\, \text{bin}(x_{ij}) = b} g_i, \qquad H_b \;=\; \sum_{i:\, \text{bin}(x_{ij}) = b} h_i. $$单特征的复杂度从 $O(N)$ 降到 $O(K)$ ,内存占用和分裂查找都受益:
| 维度 | 精确(XGBoost) | 直方图(LightGBM) |
|---|---|---|
| 单特征内存 | $O(N)$ | $O(K)$ |
| 单特征分裂查找 | $O(N)$ | $O(K)$ |
| 缓存友好度 | 差(随机访问预排序数据) | 好(连续存储的桶) |
还有一个直方图减法技巧:如果已知一个子节点的直方图,另一个子节点的直方图可以直接用父节点减去已知子节点得到。这样,构建两个子节点的代价就等于构建一个子节点的代价。在深树中,这种方法可以将每层的工作量减半。
按叶子生长 vs 按层生长#
XGBoost 默认使用按层生长(BFS):先分裂当前深度的所有节点,再进入下一层。而 LightGBM 使用按叶子生长(best-first):始终选择增益最大的叶子节点进行分裂。

在相同的节点预算下,按层生长会生成一棵深度为 $\log_2 T$
的平衡树;而按叶子生长可能形成一条细长的链,深入输入空间的某个区域。同样数量的叶子节点,按叶子生长通常能获得更低的训练损失——但如果不限制 max_depth 和 min_data_in_leaf,很容易过拟合。
GOSS:基于梯度的单边采样#
海森加权后的梯度 $g_i$ 能直接反映样本 $i$ 对下一个分裂的贡献。在一棵已经拟合得不错的树中,大多数样本的 $|g_i| \approx 0$ (已经被很好地拟合了)。丢弃这些样本几乎不会损失信息——只要重新调整权重,确保 $G$ 和 $H$ 的统计量保持无偏。
GOSS 通过 $a, b \in (0, 1)$ 分三步完成:
- 按 $|g_i|$ 降序排列,保留前 $a\cdot N$ 个样本,记为 $A$ 。
- 从剩下的 $(1-a) N$ 个样本中随机抽取 $b \cdot N$ 个,记为 $B$ 。
- 计算 $G_L, H_L, G_R, H_R$ 时,将 $B$ 中的样本统一乘以 $\dfrac{1-a}{b}$ 来抵消子采样的影响。
LightGBM 论文证明,这种子采样引入的方差是 $O(1/\sqrt{n_l})$ ,比叶子内部本身的采样噪声衰减得更快。

右图是关键:取 $a = 0.20, b = 0.10$ ,每轮只处理 30% 的样本,但重加权后的 $G$ 总和仍与全数据 $G$ 在期望上相等。
EFB:互斥特征绑定#
高维稀疏特征——如 one-hot 类别、词袋模型、点击标志——很少同时非零:一行有 country = JP 就不会有 country = US。EFB 利用这种互斥性来压缩特征轴。
具体做法是构建一张冲突图:节点是特征,边权是两特征同时非零的行数。将彼此无边的特征装进同一个组,这是图着色问题。EFB 用贪心算法解决:按度数降序遍历特征,将每个特征放入第一个“没有冲突邻居”的现有组。
$$ \tilde f_n \;=\; \begin{cases} \text{bin}(x_{n, i_k}) + o_k & \text{若 } x_{n, i_k} \neq 0 \\ 0 & \text{否则} \end{cases}, \qquad o_k = \sum_{r < k} K_{i_r}. $$
A 面板是一段近乎互斥的稀疏块(想象 6 个 one-hot 哑变量)。B 面板的红边标出违反互斥的特征对,节点颜色是贪心着色给出的组号。C 面板是合并后的列:每个原特征占据互不重叠的桶段,因此 $\tilde f$ 的直方图能精确还原各原特征的统计量——但列数减少了。
在高维稀疏问题中,EFB 经常将有效 $d$ 减少 5 到 10 倍,进一步放大了直方图构建的加速效果。
两种“重要性”定义:同一个模型,两种视角#
XGBoost 和 LightGBM 都提供了特征重要性的计算方法,但它们回答的问题并不相同。

- XGBoost (gain) 每次用某个特征进行分裂时,会累加增益值。它更倾向于奖励那些能一次性大幅降低损失的特征。
- LightGBM (split count) 统计每个特征被选为分裂点的次数。它更关注那些频繁被选中的特征,即使每次分裂的效果并不显著。
两种排名经常不一致——但都没错,只是侧重点不同。如果我想知道“哪些特征对损失下降贡献最大”,我会看 gain;如果我想了解“模型在迭代中依赖了哪些特征”,我会看 split count。如果需要一个与模型无关的解释方法,SHAP 值可以衡量每个特征对预测结果的边际贡献。
XGBoost 和 LightGBM 对比速览#
| 维度 | XGBoost | LightGBM |
|---|---|---|
| 分裂策略 | 按层(BFS) | 按叶子(best-first) |
| 基础算法 | 预排序精确 / 分位 sketch | 直方图,$K$ 桶 |
| 单特征内存 | $O(N)$ | $O(K)$ |
| 样本效率 | 行列子采样 | GOSS |
| 稀疏/类别特征 | 稀疏感知默认方向 | EFB + 原生类别支持 |
| 失败模式 | 数据量大时变慢 | 不设 max_depth 易过拟合 |
| 适用场景 | 小/中等数据量,调参精细 | 大数据量,高维度,稀疏特征 |
实战中的训练成本#
LightGBM 的直方图、GOSS 和 EFB 技术栈,换来的是更高的吞吐量:

当 $N = 10^4$ 时,三种工具的训练时间相差不过几秒,选哪个都行。但当 $N = 10^6$ 时,LightGBM 的速度比 XGBoost 快了大约 5 倍,测试精度却几乎没差别。CatBoost 的速度介于两者之间,但在类别特征密集的场景下,靠 ordered boosting 技术独占优势。
极简 NumPy 版 XGBoost#
这段代码实现了二阶目标、闭式叶权重计算、基于增益的分裂以及 $\gamma$ 剪枝功能:
| |
整套二阶机制能在 100 行内实现,原因在于有了增益公式后,算法的核心就是不断寻找最优分裂点、递归构建树结构并重复这一过程。
Q&A 精选#
为什么需要二阶信息?#
一阶信息告诉你方向,二阶信息告诉你曲率,也就是步子能迈多大才安全。牛顿法在接近最优解时之所以能二次收敛,就是因为考虑了曲率。对每个叶子节点,二阶目标直接给出闭式最优权重 $-G/(H+\lambda)$ ,而不是靠学习率去试探。
为什么 XGBoost 用 $\gamma$ 剪枝,而不是事后剪?#
因为结构分数本质上就是损失减去 $\gamma T$ 。如果某个分裂的增益达不到 $\gamma$ ,那它实际上会让正则化损失变大。拒绝这种分裂不是凭经验,而是目标函数下的正确选择。
按叶子生长什么时候会出问题?#
小数据集上容易出问题,因为最高增益的叶子可能只是在追逐噪声。解决办法是设置 max_depth 和 min_data_in_leaf(小数据集上可以设到 100–1000)。大数据集上,按叶子生长基本不会有问题。
调参顺序是什么?#
- 先把学习率设为
0.05–0.1,用早停法确定n_estimators。 - 调整树的形状:
max_depth(LightGBM 用num_leaves)、min_child_weight或min_data_in_leaf。 - 调整正则化参数:
gamma、lambda,再加上行采样和列采样(subsample、colsample_bytree)。 - 如果还是欠拟合,就降低学习率,同时增加
n_estimators。
GBDT 和深度学习怎么选?#
表格数据:几乎总是 GBDT 更强。非结构化数据(图像、文本、音频):深度学习完胜。分界点大概在“是否已经学到了稠密表征”——一旦特征变得稠密且连续,深度网络就能追上来。
练习题#
练习 1 —— 二阶梯度 平方损失 $L = \tfrac{1}{2}(y - \hat y)^2$ ,其中 $y = 5$ 、$\hat y = 3$ 。计算得 $g = \hat y - y = -2$ ,$h = 1$ 。当 $\lambda = 0$ 时,单叶子的牛顿步长 $w^* = -g/h = 2$ ,刚好等于残差。
$$ \text{Gain} = \tfrac{1}{2}\!\left[\tfrac{2.25}{7} + \tfrac{0.25}{5} - \tfrac{4}{11}\right] - 0.5 \approx -0.50. $$结构改进不足以抵消 $\gamma$ ,因此放弃这次分裂。增大 $\gamma$ 会让阈值更严格,减小 $\lambda$ 则会放宽阈值。
练习 3 —— GOSS 采样预算 假设 $N = 1000$ 、$a = 0.2$ 、$b = 0.1$ :保留 $200$ 个大梯度样本,再加 $0.1 \cdot 800 = 80$ 个小梯度样本。有效样本数为 $280$ (占 $28\%$ )。小样本集的重加权因子为 $(1 - a)/b = 8$ 。
下一步#
到此为止,监督学习这条线我已经从线性模型一路走到了集成树的工程极致。但现实中很多问题根本没有标签——客户分群、主题发现、异常检测、生成建模。下一章起我转入无监督学习与隐变量模型,从 EM 算法和高斯混合模型开始。
EM 是隐变量模型的标准武器:当数据生成过程里有看不见的中间变量(簇标签、主题、状态),直接对边缘似然做 MLE 会变得 intractable,EM 用一个迭代的 E 步(推断隐变量后验)和 M 步(最大化期望完全数据似然)绕过这个困难。我会用 GMM 作为最干净的样例把 EM 推到底——它既是 K-means 的概率版本,又是后面变分推断、HMM 学习、隐变量模型整条主线的入口。
参考文献#
- Chen, T., & Guestrin, C. (2016). XGBoost: A Scalable Tree Boosting System. KDD.
- Ke, G., Meng, Q., Finley, T., et al. (2017). LightGBM: A Highly Efficient Gradient Boosting Decision Tree. NeurIPS.
- Prokhorenkova, L., Gusev, G., Vorobev, A., et al. (2018). CatBoost: Unbiased Boosting with Categorical Features. NeurIPS.
- Friedman, J. H. (2001). Greedy function approximation: a gradient boosting machine. Annals of Statistics.
机器学习数学推导 20 篇
- 01 机器学习数学推导(一):绪论与数学基础
- 02 机器学习数学推导(二):线性代数与矩阵论
- 03 机器学习数学推导(三):概率论与统计推断
- 04 机器学习数学推导(四):凸优化理论
- 05 机器学习数学推导(五):线性回归
- 06 机器学习数学推导(六):逻辑回归与分类
- 07 机器学习数学推导(七):决策树
- 08 机器学习数学推导(八):支持向量机
- 09 机器学习数学推导(九):朴素贝叶斯
- 10 机器学习数学推导(十):半朴素贝叶斯与贝叶斯网络
- 11 机器学习数学推导(十一):集成学习
- 12 机器学习数学推导(十二):XGBoost 与 LightGBM 当前
- 13 机器学习数学推导(十三):EM 算法与 GMM
- 14 机器学习数学推导(十四):变分推断与变分 EM
- 15 机器学习数学推导(十五):隐马尔可夫模型
- 16 机器学习数学推导(十六):条件随机场
- 17 机器学习数学推导(十七):降维与主成分分析
- 18 机器学习数学推导(十八):聚类算法
- 19 机器学习数学推导(十九):神经网络与反向传播
- 20 机器学习数学推导(二十):正则化与模型选择