Boosting 集成学习与梯度提升决策树(GBDT)详解
核心结论:Boosting 模型通过串行训练多棵树、让每一棵新树拟合前面所有树累积的残差(在一般损失函数下为负梯度),逐步逼近真实答案,从而实现比 Bagging 更高的预测精度。
集成学习的两大主流思想
集成学习的目标是把一群比较弱的模型组合成一个强的模型。金融学习领域有两大主流思想:Bagging 和 Boosting。虽然目标相同——将弱模型组合为强模型——但它们的实现路径截然不同。
Bagging:少数服从多数
典型代表:随机森林(Random Forest)。
核心机制:
- 有放回的采样:并行训练 N 棵树,每棵树使用随机采样得到的不同的训练数据
- 特征随机选取:每棵树分裂时随机选取特征子集,让每棵树学到不同视角
- 并行训练:多棵树同时训练、互不依赖
- 综合结果:
- 回归问题:取所有树预测结果的均值
- 分类问题:所有树进行投票
Boosting:接力赛式的串行纠错
典型代表:XGBoost、LightGBM、CatBoost。
核心机制:
- 串行训练:先训练第一棵树,观察它与最终结果的差距(残差),再训练第二棵树修复误差,若未完全修复则继续训练第三棵树……
- 每棵树专注残差:每一棵树都专注于修复前面所有树加起来剩下的误差
- 预测时累加:将所有树的预测结果累加得到最终预测
高尔夫球的直观类比
用打高尔夫球理解 Boosting 的串行纠错过程:
- 目标:把球从 350 米外打进洞
- 第一杆(第一棵树):大力开球,球飞了 300 米,距球洞还差 50 米
- 第二杆(第二棵树):不再重复训练 350 米的目标,而是补上这 50 米的误差;打出了 45 米,距球洞还差 5 米
- 第三杆(第三棵树):再补上这 5 米的误差
- 逐杆逼近:最终把球打进洞
最终结果 = 把几杆(几棵树)的距离加起来,才是从起点到球洞的总预测结果。Boosting 的精髓在于:每一个模型都在拟合前面模型的残差,通过接力合作逐渐逼近真实答案。
两种思想核心对比
| 对比维度 | Bagging(随机森林) | Boosting(GBDT) |
|---|---|---|
| 训练方式 | 并行训练多棵树 | 串行逐棵训练 |
| 每棵树的目标 | 学习最初始的目标(独立预测) | 学习前面树累积的残差 |
| 代表算法 | 随机森林 | XGBoost、LightGBM、CatBoost |
| 训练速度 | 相对较快 | 较慢(必须串行) |
梯度提升决策树(Gradient Boosting Decision Tree, GBDT)概念澄清
在展开介绍 Boosting 模型之前,有一个最容易被误解的概念需要澄清。很多同学认为这个模型应该叫"残差下降决策树"——因为模型通过不断训练新树让残差越来越小。但它的实际通用名称是梯度提升决策树。
第一个疑问:为什么用梯度而不用残差?
残差只是当损失函数为 MSE(均方误差)时的特殊情况。在其他损失函数下,应该使用负梯度。所有情况下的通用方向是梯度(负梯度),残差只是 MSE 损失下的特例。
第二个疑问:梯度不是应该越来越小吗,为什么叫"提升"?
- "梯度":指的是利用梯度下降的方法引导每棵树的学习方向
- "提升"并不是指梯度越来越大,而是指多棵弱的决策树逐步叠加,让模型能力不断变强
- 类似的翻译困惑:如果翻译成"梯度增强决策树"可能更好理解
第三个疑问:既然用的是决策树,为什么是 gradient boosting 而不是单纯的 boosting?
decision tree:使用的基础模型是决策树gradient boosting:利用梯度下降方式让多棵决策树组合起来的模型能力越来越强- 这与线性回归有固定的参数不同,GBDT 的优化方式是在每一轮末尾新增一棵树,树与树之间通过逐步累加构成整体模型
GBDT 的数学原理与梯度下降的对应关系
与经典梯度下降的类比
经典梯度下降:
- 优化对象:参数 θ
- 更新方向:负梯度方向
- 更新方式:θ_new = θ_old − 学习率 × 梯度(即加上负梯度乘以学习率)
梯度提升决策树:
- 优化对象:函数 F(x)(而非参数)
- 更新方向:仍然是负梯度方向——唯一区别是梯度是对函数求导,而非对参数求导
- 更新方式:F_new = F_old + 学习率 × 新树的预测值(等价于沿着梯度下降方向走一小步)
为什么残差恰好等于负梯度(仅在 MSE 下成立)
当损失函数是 MSE(均方误差)时:
- 损失函数形式:L = ½ (y − F(x))²
- 对 F(x) 求导后,负梯度为:−(∂L/∂F) = y − F(x),这正是残差
关键推论:当损失函数改为 MAE(平均绝对误差)或对数损失等其他形式时,负梯度不再等于残差。因此,需要用"梯度提升"这一更通用的名称。
每轮训练的核心步骤
- 对每个训练样本计算负梯度值(当前模型最该修正的方向)
- 训练一棵决策树拟合这些负梯度值
- 将新训练出的决策树乘以学习率,加到当前模型上
学习率的作用:让模型沿下坡方向走一小步,而不是一次把所有残差全部拟合完毕。若学习率过大、单步修正过多,非常容易产生震荡——这与梯度下降中学习率的作用完全一致。
GBDT 实现过程演示
实验设置
- 构造数据:带噪声的正弦曲线
- 引入决策树库
- 设置初始学习率
- 记录每轮的树和函数
训练过程关键代码逻辑
初始化:第一轮函数直接使用目标值的均值(因为没有历史模型可用)。
逐轮迭代:
- 计算残差(负梯度):
residual = y − F(x)——在 MSE 损失下即为残差 - 训练一棵决策树拟合残差:决策树最大深度设为 2,使用全部特征、全部训练数据
- 保存当前树及预测值
- 更新模型:将新树预测值乘以学习率,加到当前模型上
可视化观察结果
前 3 轮的表现:
- 第 1 轮(只用均值):红色预测线与真实含噪声数据完全不像
- 第 2 轮加第一棵树后:MSE 开始减小
- 第 3 轮:预测线开始逐渐接近真实数据,残差变小
第 9 轮的表现:
- 预测曲线已与真实数据非常温和地贴合,仅剩少量偏差
残差分布变化观察:
- 初始时(只用均值):残差分布范围几乎与数据分布相同
- 随着树的数量增加:残差逐渐逼近零线
- 最终:残差基本在零线上下小幅波动
这个过程清晰展示了 Boosting 模型的核心理念:每棵树都在查漏补缺,模型一轮比一轮更精准,逐步纠错逼近真实结果。
GBDT 的优缺点
优点
| 优点 | 说明 |
|---|---|
| 预测精度极高 | 在结构化数据(表格数据)上,精度非常高,是 Kaggle 竞赛中最常用的方法 |
| 任务覆盖广 | 既能处理回归问题,也能处理分类问题 |
| 特征重要性 | 由于使用决策树为基础模型,可以输出特征重要性 |
| 对特征缩放不敏感 | 不需要做标准化或归一化处理 |
| 损失函数灵活 | 可以设置各种不同的损失函数 |
缺点
| 缺点 | 说明 |
|---|---|
| 训练速度慢 | 本质上是串行训练,无法并行化 |
| 容易过拟合 | 在噪声较大时容易产生过拟合现象 |
| 超参数敏感 | 对超参数的调整非常敏感,训练不易 |
| 高维稀疏数据表现差 | 对 one-hot 后的高维稀疏数据占用空间大 |
| 类别特征处理不便 | 需要手工对特征进行编码(如 one-hot),不太方便 |
三大进化版 Boosting 算法
XGBoost(2014 年诞生)
在 Kaggle 竞赛中使用最多,是机器学习历史上最有影响力的开源项目之一。它对 GBDT 的新增优势主要由三方面构成。
1. 加入正则化
- 针对 GBDT 易过拟合的缺陷
- 对叶子数量和叶子权重使用 L2 正则化 进行惩罚
2. 使用二阶梯度信息
- 传统 GBDT 只使用一阶梯度(知道下降方向)
- XGBoost 使用二阶梯度(泰勒二次展开),不仅知道往哪个方向走,还知道该走快一点还是慢一点
- 类比理解:一阶导数是速度(位移对时间),二阶导数是加速度(速度的变化率)
- 在选特征分界点时可以更精准
3. 大量工程优化
- 目标是让串行训练更快
- 在精度和速度之间取得平衡
局限:XGBoost 默认在训练时对所有数据点的特征找分界点。当特征中取值特别多时,训练会非常慢。(注意:每棵树之间本身是串行的,无法并行。)
LightGBM(2017 年,微软发布)
从名字中的 "Light" 可以看出其主打特点是快。在数据量较大时,训练速度大约是 XGBoost 的 5~10 倍。
加速策略一:直方图算法
- 并非遍历特征中的所有值
- 先将特征值离散化为直方图(例如 1000 个数据分成 25 个桶)
- 只查看 25 个桶边界上的值,不遍历所有数据点
- 效果:特征分裂速度明变快
加速策略二:带深度限制的生长策略
- 传统决策树一层一层整齐生长(Leaf-wise → Level-wise 对比)
- LightGBM:谁的残差(增益)最大就沿谁继续生长
- 优势:大数据下精确度仍能保持较高
- 注意:树的形状可能不平衡,可能出现某一分支特别长的情况
其他黑科技:还有其他进一步加快训练速度的工程优化。
适用场景:大数据量场景下比 XGBoost 更合适。
CatBoost(2017 年,俄罗斯 Yandex 发布)
全称:Category Boosting,主要针对类别特征(categorical features) 进行优化。
原生支持类别特征
- 无需自己用 one-hot 编码
- 使用场景说明:如果类别只有"男/女"两种,one-hot 用 0/1 即可;但若分类有 1000 个取值,one-hot 会用 1000 位(其中只有 1 位有效),极其浪费空间
- CatBoost 可原生高效处理这种大量类别特征的情况
解决预测偏移问题
- 普通 GBDT 的隐患:在计算残差和做下一轮预测时使用同一个样本值,相当于模型在训练时"看了答案",容易导致过拟合
- CatBoost 的解决思路:在计算某个样本的残差时,只用该样本前面的值来计算,不使用样本自身的值参与(防止模型通过"偷看答案"产生偏差)
对称树结构
- 强制生成的决策树是完全对称的
- 好处:推理速度快(注意:是推理速度,不是训练速度)
适用场景:数据中包含大量类别特征(无论是分类任务本身,还是特征中有大量类别型数据)时最合适;也能做数值预测和类别预测。
模型选型建议
Kaggle 竞赛场景
- 数据量不是特别大,但比的是精度:优先用 XGBoost
- 数据量特别大:用 LightGBM,或先用 LightGBM 跑一个基线
- 技巧:可以将 XGBoost 和 LightGBM 叠加(集成)使用
工业界场景
- 工业界训练数据量通常较大:LightGBM 应用非常广泛
- 数据中有大量类别特征:使用 CatBoost 非常合适
实战演示:XGBoost 预测加州房价并与随机森林对比
实验设置
- 数据:加州房价数据集(与之前课程相同)
- 流程:加载数据 → 划分训练集与测试集 → 分别训练随机森林和 XGBoost → 对比耗时与评价指标
XGBoost 的安装与引入
需要单独安装 xgboost 包,随机森林在 sklearn 中即可使用。
模型配置
随机森林:
- 最大深度:12
- 树的数量:200 棵
- 使用全部 CPU 核并行处理
XGBoost:
- 树的数量:200 棵
- 最大深度:5(设置稍小)
- 学习率:0.1
subsample:每次训练使用样本比例colsample_bytree:每次训练使用的特征比例- 使用全部 CPU 核运行(注意:XGBoost 的并行是指单棵树内部的节点分裂可以并行,树与树之间仍为串行)
实验结果对比
| 指标 | 随机森林 | XGBoost |
|---|---|---|
| MSE | 0.29 | 0.21 |
| R² | 0.77 | 0.83 |
| 训练耗时 | 稍长 | 更少 |
结论:XGBoost 在训练结果(MSE 更低、R² 更高)和训练速度上均优于随机森林。这也是 Boosting 模型在竞赛和工业界中使用比随机森林更频繁的原因。
XGBoost 的早停机制(Early Stopping)
解决什么问题:普通 GBDT 中学习率不好设置,设置太大容易震荡,太小则训练很慢;同时树的数量也不知道选多少合适。
早停机制的工作方式:
- 设置一个很大的树数量上限(例如 10000 棵)
- 使用非常小的学习率
- 算法自动训练,当精度不再变化时自动停止
示例结果:训练到第 1205 轮时自动停止,最佳轮数为 1186 棵。
可视化观察:
- 初始阶段:RMSE 下降速度非常非常快
- 到 1100~1200 轮左右:误差不再变化
- 模型自动停下,用户无需手动纠结树的数目
决策树、随机森林与 Boosting 三类模型的系统性对比
| 对比维度 | 决策树 | 随机森林 | Boosting 系列(XGBoost 等) |
|---|---|---|---|
| 集成的树数量 | 单棵树 | 并行多棵树 | 串行多棵树 |
| 集成思想 | 无 | Bagging(投票/均值) | Boosting(逐棵累加纠错) |
| 训练方式 | — | 并行 | 串行 |
| 树的深度 | 可深可浅(随意设定) | 一般较深 | 一般较浅 |
| 核心目标 | 作为可解释的基线模型 | 降低方差 | 降低偏差 |
| 过拟合风险 | 问题较多 | 风险较低 | 相对更低(但有自身风险) |
| 主要用途 | Baseline 模型,简单、符合直觉 | 并行投票降低方差 | 通过串行纠错降低偏差 |
不推荐直接使用原始 GBDT
日常应用中不会直接使用原始的梯度提升决策树,而是在实践中使用 2014 年、2017 年由各路大神优化过的 XGBoost、LightGBM 和 CatBoost——它们在原始 GBDT 基础上解决了训练速度、过拟合、类别特征处理等多个痛点。
总结与后续学习方向
- Boosting 系列与 Bagging 系列构成了集成学习的两大核心思想体系
- GBDT 的核心可以概括为:以决策树为基础学习器、用梯度下降的方法、让多棵弱决策树逐步叠加、使模型能力不断增强
- 三大现代 Boosting 框架各有侧重:XGBoost 侧重精度与正则化、LightGBM 侧重大数据下的速度、CatBoost 侧重类别特征的高效处理
- 决策树系列乃至整个监督学习系列在此告一段落
后续学习方向:无监督学习,主要包括聚类和降维两大主题。