什么是 Stacking 和 Blending?和 Bagging/Boosting 有什么不同?
简化版
Stacking 把一级模型对样本的预测当作新特征,再训练元模型学习组合。一级模型可以异构,也可以是同类但具互补误差的模型;关键不是名字不同,而是元训练行必须来自该样本未参与拟合的 OOF 预测。Blending 用单个 holdout 产生元训练特征,实现简单但元模型只看到留出部分,结果更依赖一次切分。Bagging 通过随机化后平均,Boosting 串行优化加法模型,Stacking 则显式学习预测之上的映射;这些方法不以“同质/异质”作为严格定义。
详细版
三种集成流派对比:
| Bagging | Boosting | Stacking | |
|---|---|---|---|
| 基学习器 | 常同类,也可扩展 | 常同类弱学习器 | 同类或异类,重在互补 OOF 预测 |
| 训练 | 并行独立 | 串行纠错 | 基模型并行 + 元模型 |
| 组合方式 | 典型为投票/平均 | 串行学习加法更新 | 元模型学习组合 |
| 代表 | 随机森林 | GBDT | 竞赛冲榜常用 |
Stacking 流程(两层):
① 训练多个基学习器(Level-0):LR、RF、XGB、SVM...
② 用 K 折交叉验证生成每个基模型对训练集的 out-of-fold 预测 → 组成元特征
③ 用元特征训练元模型(Level-1,常用简单模型如 LR)
④ 预测:新样本 → 各基模型预测 → 元模型给最终结果
Blending: 用 holdout 验证集(而非 K 折)生成元特征,简单、无泄露风险低但数据利用率低。
完整版教学
一、Stacking 的核心思想:让模型来学「怎么组合」
Bagging 典型地采用平均/投票,Boosting 则在串行训练中学习每轮加法更新;Stacking 的区别是把一级预测显式变成第二层监督学习的输入。它不天然“更高级”,而是增加了一个可学习组合层和相应泄漏、过拟合与运维成本。
于是 Stacking 分两层:
- 第一层(Level-0,基学习器):训练多个一级模型;算法可以不同,也可以通过特征、损失或随机化形成互补的同类模型。
- 第二层(Level-1,元学习器 meta-learner):把第一层各模型的预测输出当作新特征,训练一个元模型,学习「在什么情况下该更相信哪个基模型」,输出最终结果。
如果一级模型的 OOF 错误确有互补性,元模型可能在不同区域分配不同信任;若预测高度同质,复杂融合可能没有净收益。是否优于最佳单模必须在独立数据上验证。
二、关键难点:怎么生成元特征而不泄露
Stacking 最容易出错、也是面试重点的地方是:怎么用基模型的预测生成元模型的训练特征?
错误做法:用全部训练数据训练基模型,再用同一批训练数据让基模型预测、拿这些预测当元特征。这样严重数据泄露——基模型在训练集上「见过答案」,预测过于乐观,元模型学到的是基模型的过拟合,泛化崩溃。
正确做法:用 K 折交叉验证生成 out-of-fold(OOF)预测:
把训练集分成 K 折:
for 每一折 k:
用「其余 K-1 折」训练基模型
对「第 k 折」预测 → 得到第 k 折的元特征(这一折是基模型没见过的)
拼起来 → 整个训练集的 out-of-fold 预测,作为元模型的训练特征
关键在于每个训练样本的元特征来自没有用它拟合的一级模型。测试元特征可由 K 个折模型预测后平均,或由全量重训模型产生;后者训练量与 OOF 折模型不同,可能带来分布差异,应固定一种协议并验证,而不是认为全量重训必然与 OOF 完全同定义。
三、Blending:Stacking 的简化版
Blending 用更简单的方式生成元特征——留出一个验证集(holdout):
① 把训练集切成两部分:训练部分 + 留出验证部分(如 80% / 20%)
② 基模型只在「训练部分」训练
③ 让基模型对「留出验证部分」预测 → 作为元特征训练元模型
④ 测试集同样由基模型预测生成元特征
Blending vs Stacking:
| Stacking(K 折) | Blending(holdout) | |
|---|---|---|
| 元特征来源 | K 折 out-of-fold 预测 | 单个留出验证集 |
| 数据利用 | 充分(每个样本都用上) | 浪费(留出部分不参与基模型训练) |
| 实现 | 复杂 | 简单 |
| 泄露风险 | 需小心处理折 | 简单、不易泄露 |
| 稳定性 | 更稳 | 依赖那一次划分、方差大 |
Blending 简单、不易出泄露 bug,但浪费了留出集的数据、结果依赖单次划分;Stacking 用满数据、更稳,但实现复杂、要小心 OOF 流程。
四、和 Bagging/Boosting 的本质区别
- 基学习器:Bagging/Boosting 常用同类基函数,但这不是严格限制;Stacking 也不要求一级模型异构或“强”。
- 组合方式:Bagging 典型为平均,Boosting 的加法更新在训练中逐轮学习;Stacking 另建元模型学习一级输出到最终预测的映射。
- 多样性来源:Bagging/Boosting 靠数据/样本权重制造多样性;Stacking 靠不同类型模型的天然差异制造多样性。
Stacking 可以把随机森林、GBDT 本身作为一级模型,但多一层不代表必然更优;元层需要独立验证互补收益并承担额外推理与版本成本。
五、实践要点与坑
- 元模型宜简单:常用逻辑回归 / 线性模型作元模型,避免元层再过拟合(基模型输出已是强特征,元模型只需做简单的加权组合)。
- 基模型要有多样性:选差异大的模型(线性 + 树 + 核方法…),太相似的基模型融合收益小。
- 严格防泄露:OOF 流程要正确,别用「见过样本」的基模型预测生成它的元特征。
- 可多层:理论上可以堆更多层,但收益递减、易过拟合、复杂度高,实践一般两层。
- 收益 vs 成本:Stacking 常能再榨出一点精度(竞赛关键),但工程复杂、维护成本高、可解释性差,工业界要权衡。
六、常见追问
- Stacking 为什么要 K 折 OOF? 防止元特征泄露——保证每个样本的元特征来自没训练过它的基模型。
- 元模型为什么用简单模型? 基模型输出已很强,元模型只需学简单组合,复杂元模型易在元层过拟合。
- Blending 和 Stacking 哪个好? Stacking 用满数据更稳、精度略高;Blending 简单省事、不易泄露,数据多时够用。
- Stacking 基模型能包括 GBDT/RF 吗? 能,甚至鼓励——把不同集成模型再 stack,是竞赛常见套路。
- 和投票法(Voting)区别? Voting 是固定平均/多数;Stacking 用元模型学习加权,更灵活。
七、用五折 OOF 说明为何不会泄露
有 1000 条训练数据做 5 折 Stacking,每轮用 800 条训练一级模型、给剩余 200 条生成预测;循环 5 次后,每条样本都得到一个“模型没见过它时”的 OOF 预测。若有 3 个一级模型,元训练集就是 1000×3 的预测矩阵。测试集可由五个折模型预测取平均;若改为在全部 1000 条上重训一级模型,应额外确认这种训练规模变化不会让元模型输入分布明显漂移。
Z_train[i, model] = prediction from a fold model that did not train on i
meta_model.fit(Z_train, y_train)
Z_test = average_predictions_across_fold_models or predictions_from_refit_models
| 对象/方案 | 核心机制 | 选择或风险 |
|---|---|---|
| Stacking | K 折 OOF 生成元特征 | 数据利用率高、训练成本高 |
| Blending | 固定 holdout 生成元特征 | 简单快、浪费部分训练数据 |
| 直接平均 | 不训练元模型 | 泄漏风险低但组合能力有限 |
训练集 K 折 → 一级模型 OOF 预测 → 拼接元特征 Z
→ 元模型拟合 Z,y → 一级模型重训/折均值 → 测试预测
记忆钩子:Stacking 最容易错的不是模型选型,而是元特征必须来自样本未参与训练的预测。
八、常见误区与追问
- 误区:一级模型在全训练集拟合后预测训练集即可做元特征。 这会把过拟合预测泄露给元模型。
- 误区:Stacking 的一级模型越相似越稳。 高度同质的误差难提供互补信息。
- 追问:分类时元特征用标签还是概率? 通常用概率或决策分数保留信息,并确保列顺序一致。
- 追问:预处理在哪一层拟合? 每个折内分别拟合,避免标准化、编码或特征选择泄漏。
- 追问:Blending 为什么更简单? 只需一次留出集预测,但元模型只看到较少数据。
九、加强记忆
Stacking 用一级模型预测构成元特征,再由元模型学习组合;一级模型可以同类或异类,关键是错误互补。训练元特征必须是 OOF 预测,预处理也在折内拟合;测试端使用折模型平均还是全量重训模型,要固定并验证分布一致性。Blending 用单个 holdout 训练元层,流程简单但浪费一级训练/元训练数据且依赖一次划分。它与 Bagging 的平均、Boosting 的串行加法更新是不同组合机制,不应简化成“同质弱模型对异质强模型”。