训练数据到了千万行:每轮提升还要反复扫全表找分裂,内存和对钟都吃紧。GBDT 思想没错,但「精确预排序每个特征」在工业规模上贵。
轻量梯度提升机(Light Gradient Boosting Machine,LightGBM)仍是梯度提升树,重点改怎么找分裂、怎么长树、怎么少看一些样本/特征:直方图分箱、按叶子生长、单边梯度采样(GOSS)、互斥特征捆绑(EFB)等,让 GBDT 在大数据上更快更省内存。
段末注释:LightGBM 由微软团队提出(NeurIPS 2017);与 XGBoost、CatBoost 同属 GBDT 实现族。本系列按发展顺序排在 CatBoost(同年稍早公开材料)之后。后文沿用 LightGBM。
配图目录:./1204.机器学习-集成学习-2.Boosting-5.LightGBM/。
1. 一句话定位
| 维度 | 一句话 |
|---|---|
| 学习范式 | 监督学习;GBDT 族实现 |
| 输入 → 输出 | 表格特征(可直接声明类别列)→ 多棵树分数之和 |
| 在优化什么 | 与 GBDT 相同的加法提升;用近似与采样把每轮分裂算得起 |
出现背景:Ke 等,LightGBM: A Highly Efficient Gradient Boosting Decision Tree(NeurIPS 2017)。当时预排序式 GBDT(如早期 XGBoost 路径)在海量行上内存与扫描成本高;LightGBM 用直方图、Leaf-wise、GOSS/EFB 等把每轮分裂算得起,面向工业级数据规模。
比喻:不在连续轴上毫米级找刀口,而先把特征值倒进若干桶(bin)里再比较桶边界;长树时也不强迫「同一层所有叶子一起分裂」,而是专挑当前增益最大的那片叶子再长一截。
2. 直觉:两处关键加速


| 机制 | 在干什么 |
|---|---|
| Histogram | 特征离散进 bin,在直方图上累积梯度统计再找分裂 |
| Leaf-wise | 每次分裂增益最大的叶(需 max_depth/num_leaves 防过深) |
| GOSS | 保留大梯度样本,小梯度样本下采样并补偿,少算仍近似增益 |
| EFB | 把近似互斥的稀疏特征捆成更少「特征包」,降有效维数 |
直方图做差:兄弟叶直方图可用「父 − 兄」得到,再省一半构造开销(见同目录 Histogram_subtraction.png)。
3. 核心链路
提升主链路与 GBDT/XGBoost 同构:每轮对每个样本算当前损失的负梯度(及海森),再训一棵树 $f_m$,累加 $\nu f_m$。
LightGBM 的差异几乎全在树怎么造得起、怎么长、少看哪些行/列:bin / 直方图加速找分裂,Leaf-wise 决定先长哪片叶,GOSS 少看样本,EFB 少扫特征。
3.1 Bin:把连续特征先收成有限档,通过Histogram做差统计找分裂点
目的:候选切点从「该特征几乎每个不同取值」降到「最多约 max_bin 个边界」,主要针对千万级数据量大训练中,把特征值通过分组,压缩到 bin 个不同分组中,减少训练阶段特征选择的计算量。
bin 的分组只在最开始的初始化阶段进行,后续训练阶段 bin 的分组范围固定不再调整:
- 按特征取值分布(可对
bin_construct_sample_cnt采样)划出分箱边界,使各 bin 样本量大致均匀;上限由max_bin(默认常 255)等参数控颗粒度。 - 每条样本在该特征上得到一个 bin id(离散档),原浮点值可不再反复参与切点枚举。
- bin 只用于每轮找特征切点;损失与梯度仍按样本算。
读参数:max_bin / max_bin_by_feature / min_data_in_bin;改分箱通常需重建 Dataset。
按特征分组的 bin,统计累加落入该 bin 的 $\sum g$、$\sum h$、count,再只在 bin 边界上算增益、选最优切。兄弟叶直方图可用「父 − 兄」做差,少造一半直方图。损失本身仍是样本维;直方图是把已算好的逐样本梯度按 bin 加总来加速选刀。
3.2 Leaf-wise:每次只分裂「当前增益最大」的叶
对照图 2:常见 Level-wise(按层) 同一深度的叶子尽量一起长,树较整齐;LightGBM 默认 Leaf-wise(按叶 / best-first)。
目的
- 在叶子数相近时,优先把分裂预算花在「减损最多」的那片叶上,同
#leaf下往往比按层生长降损失更快。 - 代价:树易长成深浅不一;小数据上更容易过拟合,必须用叶子数/深度等卡住。
原理
设当前已有若干叶子,每片叶都能在直方图上算出「若在此叶再切一刀」的最佳增益 $\Delta$。
Level-wise:本层所有叶都切(或按层推进),不管某叶增益是否很小。
Leaf-wise:在所有候选叶里取
$$
\ell^*=\arg\max_{\ell},\Delta(\ell)
$$
只分裂 $\ell^*$,其余叶先不动;新长出的两片子叶再进入候选池,重复直到触达停止条件。
因此分裂次数相同时,预算集中在高增益区域;树可以一边很深、另一边很浅。
实现方式(训练循环内,每棵树)
- 根节点入候选;用直方图算其最佳分裂与增益。
- 当叶子数 $<$
num_leaves,且仍有增益足够的候选:弹出增益最大的叶 → 执行分裂 → 两子叶各自估增益后入堆/列表。 - 若某叶达到
max_depth、或样本数 / 海森和低于min_data_in_leaf(及同类约束)、或增益不足,则不再分裂该叶。 - 注意:设了
max_depth仍是 Leaf-wise——只是过深的枝被禁止再长,并不是改回 Level-wise。
复杂度旋钮(实务)
| 参数 | 角色 |
|---|---|
num_leaves |
主控一棵树最多多少叶;比单独调深度更贴 Leaf-wise |
max_depth |
深度上限,防单枝过深;宜与 num_leaves 同设,且常令 num_leaves $< 2^{\texttt{max_depth}}$ |
min_data_in_leaf |
叶太碎则停,抑过拟合 |
3.3 GOSS:梯度单边采样,少算样本仍近似增益
GOSS(Gradient-based One-Side Sampling,基于梯度的单边采样)。
目的
造直方图、估分裂增益时,不必每轮扫完全部行。大梯度样本对增益贡献大,整留;小梯度样本贡献小,随机抽一部分并放大权重,使 $\sum g$、$\sum h$ 仍接近全量估计,从而加速。
原理
记本轮各样本梯度强度从大到小。设保留大梯度比例为 $a$(top_rate),从小梯度池再随机保留比例为 $b$(other_rate,相对全样本量 $n$):
- 取梯度最大的约 $a\cdot n$ 条,全部进入本轮训练子集。
- 其余小梯度样本中,再随机抽约 $b\cdot n$ 条。
- 对抽中的小梯度样本,将其梯度/海森乘放大系数
$$
\frac{1-a}{b}
$$
(实现里按整数截断后的实际条数微调),避免「少抽了弱样本」导致分布偏斜。大梯度侧不放大。直方图统计是加权子集上的近似无偏估计,不是朴素丢掉弱样本。
直觉:改卷优先盯大错;小错抽查几份并按比例加权,总分仍能代表全班。
实现方式
- 开启:
boosting_type='goss'(默认gbdt时不走 GOSS)。 - 每轮提升(常在若干预热轮之后)按当前梯度重采样;与 Dataset 分箱采样、与普通
bagging不是同一套开关。 - 在采样子集上建直方图、Leaf-wise 长树;未抽中样本本轮不进直方图,模型仍是全局加法模型。
- 主旋钮:
top_rate(常默认 $0.2$ 量级)、other_rate(常默认 $0.1$ 量级)。$a$ 过大加速有限;$b$ 过小估计更噪。
注意:GOSS 改的是「本轮用哪些行估分裂」,不是改标签语义;小数据上噪声可能盖过收益,未必默认就开。
3.4 EFB:互斥特征捆绑,少扫特征维
EFB(Exclusive Feature Bundling,互斥特征捆绑)。
目的
高维稀疏表(大量 one-hot、文本词袋等)上,很多特征几乎不同时非零。把近似互斥的若干列捆成一个特征包,直方图要扫的有效特征数从 $d$ 降到约「捆数」,加速且省内存。
原理
- 互斥:同一行上至多一个特征取非零。捆在一起时,对参与列加不同 offset,把取值映到不重叠数值段,合成一列仍能区分「来自哪条原特征、取何值」。
- 近似互斥:允许少量同时非零(冲突)。冲突率小则对增益估计影响有界;捆得越狠越快,冲突过大则信息搅在一起。
- 求最少捆数可化为图着色近似:特征为点,非互斥(常同时非零)则连边;同色点可尝试捆成一包(贪心着色)。
实现方式
- 多在 Dataset 构造阶段做捆绑规划与编码(与 bin 边界一样,偏预处理进训练格式);训练循环里对更少的捆绑特征建直方图。
- 捆绑列内部:加 offset 错开取值区间,再写入单一 bundled 特征。
- 开关:
enable_bundle(常默认开启)。论文冲突上限在当前实现中多为内部启发式(历史上曾暴露max_conflict_rate,现一般不当常规调参);稠密数值表收益有限,稀疏高维表收益大。 - 与 GOSS 正交:GOSS 减行,EFB 减列;可同时作用在直方图路径上。
抓住一句:Bin/直方图定刀缝;Leaf-wise 定砍哪片叶;GOSS 定本轮看哪些行;EFB 定直方图要扫哪些(捆后的)列。 损失与逐样本梯度语义不变,变的是估计增益时的计算图。
读参数顺序建议:learning_rate + num_iterations(早停)→ num_leaves(及必要时 max_depth)→ 大数据再考虑 boosting_type=goss 与 top_rate/other_rate → 稀疏高维确认 enable_bundle;类别列用 categorical_feature 声明。
4. 手算完整实例:直方图分箱 + 2 轮叶均值
A. 问题与原始表
一维特征 $x$,回归标签 $y$(示意)。
| $i$ | $x$ | $y$ |
|---|---|---|
| 1 | 1.0 | 1 |
| 2 | 1.2 | 2 |
| 3 | 3.5 | 8 |
| 4 | 3.8 | 9 |
| 5 | 2.0 | 3 |
B. 初始化
把 $x$ 分进 2 个 bin:$x<2.5$ → bin0,$x\ge2.5$ → bin1(直方图候选分裂只比较 bin 边界)。
$F_0=\bar y=4.6$;$\nu=1$。每轮在 bin 上累计残差和与计数,叶值=该 bin 残差均值。
C. 训练过程
第 1 轮:$r=y-4.6$。
| bin | 样本 | $\sum r$ | 计数 | 叶值 $f_1$ |
|---|---|---|---|---|
| 0 | 1,2,5 | $-7.8$ | 3 | $-2.6$ |
| 1 | 3,4 | $+7.8$ | 2 | $+3.9$ |
$F_1=F_0+f_1$ ⇒ bin0 上 $F_1=2.0$,bin1 上 $F_1=8.5$。
第 2 轮:$r=y-F_1$。
| $i$ | $F_1$ | $r$ |
|---|---|---|
| 1 | 2.0 | −1.0 |
| 2 | 2.0 | 0.0 |
| 5 | 2.0 | +1.0 |
| 3 | 8.5 | −0.5 |
| 4 | 8.5 | +0.5 |
| bin | $\sum r$ | 叶值 $f_2$ |
|---|---|---|
| 0 | 0.0 | 0.0 |
| 1 | 0.0 | 0.0 |
本例两轮后残差在 bin 内已对称抹平;$F_2=F_1$(示意「直方图上累加统计 → 更新叶」;实装会换分裂、加多 bin / Leaf-wise)。
D. 可部署对象
分箱规则 + $F_2(x)=4.6+f_1(\mathrm{bin}(x))+f_2(\mathrm{bin}(x))$。
E. 预测 / 推断
- 训练内($i=1$,$x=1.0$):bin0 → $F_2=2.0$。
- 新样本 $x=3.0$:bin1 → $F_2=8.5$。
5. 适用 / 不适用
| 维度 | 判定 | 要求或边界 | 具体例子 |
|---|---|---|---|
| 特征 | 适用 | 大宽表;稀疏/互斥类别多;可声明 categorical | 推荐日志:海量 id 类特征 + 数值上下文,用 EFB/类别分裂 |
| 特征 | 不适用 | 极小表还强上复杂采样;或必须精确到每个浮点分裂点 | 500 行实验设计数据,精确 CART 或线性模型更简单 |
| 训练目标 | 适用 | 回归/分类/排序等 GBDT 常见任务 | 搜索排序、CTR、销量预测 |
| 训练目标 | 不适用 | 只要极致可解释的单棵浅树 | 业务只要三问决策树海报,不必上 LightGBM |
| 训练数据 | 适用 | 行数大、要训练快、内存紧;可分布式 | ent级样本离线训练日更模型 |
| 训练数据 | 不适用 | num_leaves 很大且无早停;噪声点多还 Leaf-wise 拉满 |
错标不少时过深 leaf-wise 把噪声叶子切得很细 |
6. 优缺点与常见坑
优点:大数据上通常更快更省内存;原生类别支持;并行方案成熟。
缺点:Leaf-wise 更需防过拟合;直方图是近似;小数据上相对 XGBoost 优势不明显。
坑:把 num_leaves 开到 $2^{\mathrm{max_depth}}$ 量级却以为「和深度等价」;类别高基数无约束;对比 XGBoost 时未对齐早停与学习率。
7. 最小可运行示例
1 | """LightGBM 二分类:Dataset → train → predict。""" |
说明:公开数据集示例,与上文直方图手算表无关。
重要配置参数(LightGBM)
| 参数(库内常用名) | 训练中的作用与影响 | 参考起点 / 常用范围 | 配置指导 |
|---|---|---|---|
num_leaves |
叶数上限(Leaf-wise 主复杂度旋钮);过大极易过拟合 | 常 31~127;起点可 31 |
过拟合优先减 num_leaves,不要只减 num_boost_round |
learning_rate |
步长;小更稳 | 常 0.03~0.1;起点可 0.05 |
配早停;lr↓ 则放宽最大轮数 |
max_bin |
直方图分箱数;大更细、更慢、更占内存 | 默认常够;内存紧可略降 | 极值噪声多时可略降;精度不够再升 |
min_data_in_leaf |
叶最小样本;越大越保守 | 视样本量;过拟合可增大 | 小数据尤需防止叶过碎 |
boosting_type / top_rate / other_rate |
goss 时大梯度全留、小梯度抽样并加权;减行加速 |
大数据可试 goss;top_rate≈0.2,other_rate≈0.1 |
与普通 bagging 不同;小数据慎开 |
feature_fraction / bagging_fraction |
列/行随机采样(非 GOSS);抗过拟合、加速 | 常 0.7~1.0;bagging 需 bagging_freq>0 |
与 goss 勿混为一谈 |
enable_bundle |
EFB:近似互斥稀疏特征捆绑,减有效列 | 常默认开 | 稠密纯数值收益小;稀疏高维保持开启 |
早停 early_stopping |
验证停滞停训 | 常 20~50 轮 |
预测用 best_iteration,与 XGBoost 同理 |
8. 和近邻算法怎么挑
| 需求 | 更优先考虑 |
|---|---|
| 教学:加重错分 | AdaBoost |
| 残差提升框架 | GBDT |
| 通用数值表强基线 | XGBoost |
| 类别多、防目标编码泄漏 | CatBoost |
| 行数极大、要更快训练 | LightGBM |
| 要整段预测分布 | NGBoost |
9. 小结
- LightGBM = GBDT 主链路 + 直方图 / Leaf-wise / GOSS / EFB 等加速。
- 大数据表格训练的常用首选之一;小数据先对齐验证方式再和 XGBoost 比速度。
- 最易踩的坑:
num_leaves过大 + 无早停。
参考文献
- Ke G. et al. LightGBM: A Highly Efficient Gradient Boosting Decision Tree. NeurIPS 2017.
- LightGBM 文档
- Microsoft LightGBM GitHub