机器学习基础

梯度提升:把错误一层层补上

14 分钟

随机森林是「很多棵树各自独立、最后投票」。梯度提升走的是完全相反的思路:树一棵接一棵地长,每一棵专门修正前面所有树的错误。

这个思路在表格数据上长期占据统治地位——Kaggle 上的结构化数据竞赛,冠军方案几乎清一色是它。


核心思想:拟合残差

用一个极简的例子。预测房价,真实值 100 万:

轮次 这棵树预测 累计预测 还差多少(残差)
第 1 棵 80 80 20
第 2 棵 15 95 5
第 3 棵 4 99 1

第 2 棵树的训练目标不是 100,而是第 1 棵留下的残差 20。 第 3 棵拟合第 2 棵留下的残差 5。

最终预测 = 所有树的预测相加。 每棵树都很弱(通常只有 3–6 层深),但一层层叠加后极其强大。


为什么叫「梯度」提升

上面用「残差」是为了直观。更一般的表述是:每棵新树拟合的是损失函数关于当前预测的负梯度。

当损失函数是平方误差 时:

负梯度恰好就是残差。 所以「拟合残差」是平方损失下的特例。

换成别的损失函数(分类用的对数损失、回归用的绝对误差),负梯度就不是残差了,但框架完全一样。这就是「梯度」二字的来历——它是在函数空间里做梯度下降。


三个关键超参数

参数 作用 典型值
learning_rate 每棵树的贡献打多少折 0.01–0.1
n_estimators 树的数量 100–2000
max_depth 单棵树深度 3–6

学习率和树数量是一对:学习率调小,就要用更多树来补偿。小学习率 + 多树,通常比大学习率 + 少树效果好,代价是训练更慢。

注意 max_depth 只有 3–6——和随机森林用深树完全相反。因为提升法要的是「弱学习器」,每棵树只需要捕捉一点点信号,深了反而容易过拟合。


和随机森林的根本区别

随机森林 梯度提升
树的关系 独立并行 串行依赖
单棵树 深、强 浅、弱
主要降低 方差 偏差
能否并行 树之间可以 树之间不能(但单树内部可以)
树多了会过拟合吗 不会 ,需要早停
调参难度

最后两行是实践中最重要的差别。 梯度提升必须用早停(early_stopping_rounds)来决定树的数量,否则一定会过拟合。


三个主流实现

特点
XGBoost 最早流行,工程优化扎实,生态成熟
LightGBM 速度快、内存省,用直方图算法和 leaf-wise 生长,大数据首选
CatBoost 类别特征处理最好,默认参数就很能打
import lightgbm as lgb
model = lgb.LGBMClassifier(learning_rate=0.05, n_estimators=1000, max_depth=5)
model.fit(X_tr, y_tr,
          eval_set=[(X_val, y_val)],
          callbacks=[lgb.early_stopping(50)])   # 50 轮不提升就停

练习:解释一下——为什么梯度提升的单棵树要浅(3–6 层),而随机森林的单棵树可以很深?(提示:想想各自主要在对抗偏差还是方差)

小纸条

梯度提升和随机森林在「树的关系」和「主要降低什么」上有什么根本区别?为什么梯度提升的单棵树要浅?

登录 后可看答案