首页 / 树与集成 / 集成学习

集成学习:三个臭皮匠,到底怎么凑成诸葛亮

单个决策桩(只能横着或竖着切一刀)在月牙上只有 88% 的准确率。 把 30 个桩组合起来,可以到 99%。但组合的方式有两种,逻辑完全不同: Bagging 让它们各自独立做题再投票,AdaBoost 让后一个专门补前一个的漏。 这一页把两种方式的边界一笔一笔画出来。

决策边界:Bagging
准确率随基学习器数量怎么走
当前集成

                
              
①段是这一页自己实现的逻辑;②段是 sklearn 的等价写法。 两种集成的加权错误率与 发言权 α 都已与 sklearn 逐轮对拍过。

① 为什么要集成:把误差拆成两半

模型的泛化误差可以粗略拆成偏差(系统性地错在哪)和 方差(换个训练集就换个答案)。两种集成各治一头:

  • Bagging 降方差:每棵树看一份自助采样(有放回)的数据, 彼此独立。平均起来,各自的随机波动互相抵消。 所以 Bagging 特别适合深而复杂的基学习器。
  • Boosting 降偏差:每轮盯着上一轮做错的样本加大权重, 新基学习器专门补强。所以 Boosting 适合简单的基学习器 (本页默认就是只能切一刀的决策桩)。

② Bagging:平均的力量

假设有 个相互独立、 方差都是 的模型, 平均之后的方差是:

这是 Bagging 的全部理论。它有两个前提:模型要足够独立 (所以要有随机采样),以及平均不会破坏准确性 (所以基学习器不能太弱)。现实中样本有限,树之间总有关联, 降方差的效果会打折——但方向是对的。

③ AdaBoost:给做错的题加权重

每一轮的流程只有四步:

①算这一轮的加权错误率 ε; ②换算成发言权 α——错得越少说话越响, 但 ε = 0.5(和瞎猜一样)时 α = 0,直接作废; ③把答错的样本权重乘上 放大; ④归一化,进入下一轮。

最终预测是按 α 加权投票: 。 页面上圆点的大小画的就是当前样本权重——你会看到被错分的点一轮轮变大。

④ 两者的差别,一句话

还有一个容易被误读的地方:AdaBoost 下右侧那个「单棵树平均」会比 Bagging 低很多 (月牙上实测 66% vs 83%)。这不是实现有问题——那些树是偏科生: 越到后面,它们越专门盯着被放大权重的难分点训练,在整体数据上自然一塌糊涂。 正因为每棵树只负责一小块局部,最后才必须按 α 加权投票把它们拼起来。

Bagging 把弱点的权重均摊,Boosting 把弱点的权重集中。 所以 Bagging 要很多棵树才能看出效果(曲线缓慢上升后饱和), Boosting 往往几轮就见效——但也更容易被噪声点带偏: 一个标错的样本会被反复放大权重,拉着边界往它那儿跑。这就是 Boosting 对 异常值比 Bagging 敏感得多的原因。
1. 为什么 Bagging 常用「深树」而 Boosting 常用「浅树」?
因为两者治的毛病不一样。Bagging 治方差: 深树方差大(换个训练集就长得面目全非),平均正好压住它。 如果基学习器本身就很简单(低方差),Bagging 没什么可治的。 Boosting 治偏差:它靠"后一个补前一个的漏", 基学习器必须够简单,才能被稳步纠正;如果每个基学习器都很强、 已经拟合得七七八八,后面的轮次就没什么可补的,反而容易一起过拟合。 页面上可以把基学习器深度拖到 4 再切到 AdaBoost 试试——性能未必更好。
2. 本页的 AdaBoost 用「只能切一刀的桩」,为什么反而能画出月牙这种弯曲边界?
因为每个桩都是轴平行的半平面切分。 把这些切分按不同权重叠加起来("或"的关系),就能逼近任意复杂的区域—— 这正是决策树的思路,只不过 AdaBoost 是按错误率决定每一刀的重要程度。 30 个桩加上正确的权重,就能把月牙围出来。 也可以反过来看:一棵深度 5 的树也能做到,但 AdaBoost 用一堆浅模型 达到了差不多的效果,而且每一步都容易解释。
3. 当某一轮的加权错误率 ε 恰好等于 0.5(和瞎猜一样),α 会等于多少?
。 这说明这一轮的基学习器彻底没用,发言权为零,对最终投票没有任何影响。 所以实现里必须处理这件事:α ≤ 0 时要么跳过、要么直接停止(sklearn 是停止)。 另一个极端是 ε → 0,此时 α → +∞——所以 ε 通常会被加上一个极小的下限, 防止数值爆炸。本页的对拍里就专门覆盖了这两种边界。
4. 页面上那张「准确率随基学习器数量」的曲线,Bagging 和 AdaBoost 形状有什么不同?
Bagging 通常是快速上升然后平掉:前几棵树把明显的结构抓住, 之后加的树提供的多是重复信息(因为自助采样之间高度相关), 边际收益迅速衰减。AdaBoost 则更"贪心": 每一轮都在针对性地修上一轮的错误,所以早期上升往往更陡, 但后期可能因为过度关注少数难分点而先升后降(过拟合)。 在页面上把数量从 1 拖到 30,两种算法的曲线放在一起看最直观。
5. AdaBoost 里那个「被反复放大权重的样本」,如果本身是个标错的标签呢?
那它就成了一场灾难:模型会不惜扭曲整个边界去迁就这一个错误的点, 因为每轮它都被放大 倍。 这就是 Boosting 对噪声和异常值特别敏感的原因, 也是现实中常见做法的由来:先用 Bagging(比如随机森林)拿一个对噪声更稳的基线, 或者在 Boosting 里限制每轮的 α、降低学习率(learning rate < 1)。 想知道具体长什么样,可以在「月牙」上把基学习器深度开到 4、 数量开到 30,看边界是怎么被少数几个点拽歪的。