假如你想知道新开张的餐厅值不值得推荐,你有两种选择:请一位美食评论家,还是请十位普通食客?评论家再专业,也有自己的口味偏好和判断失误的那一天;而十位食客虽然每个人单独看都算不上完美,但只要大家的喜好不是同一个模子刻出来的,“少数服从多数”的结论往往出奇地稳。集成学习就是这个思路:与其赌一个模型,不如养一群“半吊子”模型,让它们各自表态,最后投票定案。Bagging 是其中最有代表性的一招,全称 Bootstrap Aggregation——自助采样聚合。它的做法像一个自助餐机制:每次从原始数据中有放回地抓一把样本,喂给一个基学习器;重复 T 次,得到 T 个“各吃各的”模型;预测时让大家投票。你会发现,每个模型单独看准确率只有七八成,但合在一起能逼近 99%。“人多反而更准”的背后,是方差被平均掉的数学原理——也是本文要一层层拆开的故事。

岗位关联

掌握 Bagging 是学习随机森林、理解整套集成方法的基石。风控、推荐、信贷评分等工业级项目几乎都会用到 Bagging 家族,理解它能让你在模型泛化调优时直击要害,不再只做“调参侠”。

目录
  1. 可视化演示
  2. 集成学习思想
  3. Bootstrap采样
  4. 并行化训练
  5. 多数投票
  6. 偏差与方差
  7. Bagging对比Boosting
  8. 随机森林扩展
  9. 流程与实战
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

动态演示Bagging的核心机制,通过开始/执行/监控/完成四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

Bagging:Bagg Bagging核心思想与集成学 Bootstrap采样原理与有 核心机制可视化 Bagging整体架构与关键组件

集成学习思想

一位食客再资深,也有口味偏爱和心情起伏。十位“普通”食客分桌而坐、独立打分,反而更接近餐厅的真实水平——因为每个人的偏好和误判会在汇总时相互抵消。这就是集成学习的直觉:不追求打造一个完美模型,而是训练多个“基学习器”(base learner,相当于普通食客),把它们的预测组合起来。每个基学习器只要比瞎猜强一点——错误率低于 0.5——组合起来就可能比任何单一模型都好。

在机器学习里,这个思路叫“集成学习”(Ensemble Learning),Bagging 是其中最重要的成员。为什么“多票”能胜“独断”?做一个思想实验:假设每个基学习器独立判断,出错概率是 ε,只有当超过一半的学习器同时答错时,集成才会出错。用组合数可以算出,集成出错的概率随学习器数量 T 的增大而指数下降。这正是“三个臭皮匠,顶个诸葛亮”的数学版本。

Pens=∑k=⌈T/2⌉T(Tk) εk (1−ε)T−k\displaystyle P_{\text{ens}} = \sum_{k=\lceil T/2 \rceil}^{T} \binom{T}{k}\,\varepsilon^{k}\,(1-\varepsilon)^{T-k}

1. 错误率:每个基学习器独立地犯错,错误概率记为 ε,并假设 ε < 0.5(比抛硬币略强)。

ε=P(ht(x)≠f(x))\varepsilon = P\big(h_t(x) \neq f(x)\big)

2. 失败条件:T 票中出错的学习器达到一半以上(k ≥ ⌈T/2⌉),多数投票才会失败。

k≥⌈T2⌉k \geq \left\lceil \frac{T}{2} \right\rceil

3. 恰好 k 个出错:k 个错误且 T−k 个正确同时发生,组合方式有 C(T,k) 种。

(Tk) εk (1−ε)T−k\binom{T}{k}\,\varepsilon^{k}\,(1-\varepsilon)^{T-k}

4. 失败区间累加:把 k 从半数到 T 全部加起来,就是集成的出错概率。

Pens=∑k=⌈T/2⌉T(Tk) εk (1−ε)T−kP_{\text{ens}} = \sum_{k=\lceil T/2 \rceil}^{T} \binom{T}{k}\,\varepsilon^{k}\,(1-\varepsilon)^{T-k}

就像 21 位食客投票,只要他们不是被同一份“美食攻略”洗脑(独立性),错误的口味很难形成多数。这也预告了 Bagging 的两大支柱:让每位“食客”口味有差异,再让投票定输赢。

Bootstrap采样

自助餐的取菜规则是:你端着盘子从几十道菜里挑,每挑一次,菜还在那里——同一道菜可以反复取。Bagging 的“自助”二字正来自这个动作:原始数据有 m 个样本,每次从中有放回地抽一个,抽 m 次,得到一份和原始数据一样大的新训练集。重复 T 次,就有了 T 份“菜盘”,喂给 T 个模型。

这个看似简单的抽样办法有一个绝妙结论:某个样本在 m 次抽取中一次都没有被抽中的概率,约等于 36.8%。也就是说,每份自助样本大约覆盖原始数据的 63.2%,其余位置是重复出现的样本。没被抽中的那 36.8%,被称为“袋外数据”(Out-of-Bag,简称 OOB)——它免费为模型提供了一份验证集。

(1−1m)m≈e−1≈0.368\displaystyle \left(1 - \frac{1}{m}\right)^{m} \approx e^{-1} \approx 0.368

1. 单次落选概率:在 m 个样本里抽一次,某个特定样本没被抽中的概率。

1−1m1 - \frac{1}{m}

2. 连续 m 次落选:有放回地抽 m 次,每次都轮不上它。

(1−1m)m\left(1 - \frac{1}{m}\right)^{m}

3. 极限逼近:当 m 足够大,此式趋近自然常数 e 的倒数。

lim⁡m→∞(1−1m)m=e−1≈0.368\lim_{m \to \infty}\left(1 - \frac{1}{m}\right)^{m} = e^{-1} \approx 0.368

4. 反面即覆盖率:被抽中的概率约 63.2%,也就是自助样本的“新鲜样本覆盖率”。

1−e−1≈0.6321 - e^{-1} \approx 0.632

食客没尝过的那 36.8% 的菜,并不是浪费——它正好用来检验这位食客的味觉是否可靠。这就是后面要讲的 OOB 验证:谁没吃过这道菜,谁就有资格给这道菜“挑刺”。

并行化训练

食客们要分桌而坐、互不通气:如果允许互相参考,先点的会带动后点的,十个人的评分就会高度雷同,投票就失去了意义。Bagging 在算法上做到了真正的“隔离”——T 份自助样本彼此独立,T 个模型各自训练、互不通信。因此它天然支持并行计算:把 T 个训练任务丢到多核 CPU 或多台机器上同时跑,训练总时长接近训练单个模型的时间。

这种并行背后有一组值得咀嚼的性质:每份训练集都是从同一个数据分布中抽样得到的,所以模型的“底子”相似(同分布);但抽到的样本又各不相同,所以模型“各有特色”(有差异)。这种“和而不同”正是平均化能够奏效的前提。假如 T 个模型完全独立、每个的预测方差都是 σ²,那么把它们取平均后,方差会缩小到原来的 1/T。

Var⁡ ⁣(1T∑t=1Tf^t(x))=σ2T\displaystyle \operatorname{Var}\!\left(\frac{1}{T}\sum_{t=1}^{T}\hat{f}_t(x)\right) = \frac{\sigma^2}{T}

1. 单个模型方差:每个基学习器预测值围绕其期望的波动幅度记为 σ²。

Var⁡(f^t(x))=σ2\operatorname{Var}\big(\hat{f}_t(x)\big) = \sigma^2

2. 常数的平方:对平均操作求方差时,常数 1/T 提出后要平方。

Var⁡ ⁣(1T∑t=1Tf^t(x))=1T2Var⁡ ⁣(∑t=1Tf^t(x))\operatorname{Var}\!\left(\frac{1}{T}\sum_{t=1}^{T}\hat{f}_t(x)\right) = \frac{1}{T^2}\operatorname{Var}\!\left(\sum_{t=1}^{T}\hat{f}_t(x)\right)

3. 独立则相加:模型互不相关时协方差为 0,方差直接累加。

Var⁡ ⁣(∑t=1Tf^t(x))=∑t=1TVar⁡(f^t(x))=Tσ2\operatorname{Var}\!\left(\sum_{t=1}^{T}\hat{f}_t(x)\right) = \sum_{t=1}^{T}\operatorname{Var}\big(\hat{f}_t(x)\big) = T\sigma^2

4. 代入得结论:平均之后方差变为原来的 1/T。

Tσ2T2=σ2T\frac{T\sigma^2}{T^2} = \frac{\sigma^2}{T}

十个食客都生活在同一座城市(同分布),口味会有共性;但各自私藏的小馆子不同(样本差异),合起来反而比单打独斗稳定得多。并行训练则保证了这种“多样性”不被互相干扰。

多数投票

每位食客最后要表态:推荐,还是不推荐?一张票而已。更细心的评审团会让每人打 1~5 星,最后求平均分——分数比“是/否”保留了更多信息。Bagging 也是这样:分类问题用“多数投票”,数一数哪个类别得到的票最多;回归问题用“取平均”,把 T 个模型的数值预测加起来除以 T。

硬投票只管最终类别,软投票则更进一步:让每个模型先输出各类别的概率,再对所有模型的概率取平均。这样,那些“犹豫不决”的模型也能把不确定性表达出来,通常能带来微小但稳定的提升。实践中,Bagging 最常搭配决策树这种天然能输出概率或类别的模型。

H(x)=arg⁡max⁡y∈Y ∑t=1T1(ht(x)=y)\displaystyle H(x) = \arg\max_{y \in \mathcal{Y}}\ \sum_{t=1}^{T}\mathbb{1}\big(h_t(x) = y\big)

1. 指示函数即一张票:第 t 个模型输出类别 y 时记 1,否则记 0。

1(ht(x)=y)={1,ht(x)=y0,ht(x)≠y\mathbb{1}\big(h_t(x)=y\big) = \begin{cases}1, & h_t(x)=y \\[2pt] 0, & h_t(x)\neq y\end{cases}

2. 逐类计票:把 T 个模型的投票按类别累加,得到每个类别的总票数。

vote(y)=∑t=1T1(ht(x)=y)\text{vote}(y) = \sum_{t=1}^{T}\mathbb{1}\big(h_t(x)=y\big)

3. 取票数最多者:argmax 返回得票最多的类别作为最终输出。

H(x)=arg⁡max⁡y∈Y vote(y)H(x) = \arg\max_{y \in \mathcal{Y}}\ \text{vote}(y)

就像大众点评上“推荐”与“不推荐”的百分比是硬投票,星级均分是软投票——后台其实都是这么聚合众人口味的。投票规则虽朴素,却是 Bagging 把“群意”变成“决断”的最后一公里。

偏差与方差

食客对同一道菜的评价为何不一致?一种原因是某位食客天生偏甜或偏咸,这是“偏差”(bias);另一种原因是今天饿与不饿造成的状态波动,这是“方差”(variance)。一个靠谱的评审团,既要压低系统性偏差,也要压住随机波动。机器学习中的偏差-方差分解把模型误差拆成三部分:不可消除的噪声、偏差的平方、方差。

偏差衡量模型对真实规律的系统性偏离——比如用直线去硬拟合一条曲线;方差衡量模型对不同训练集的敏感程度——比如一棵深度决策树,换一批数据决策边界就剧烈变化。Bagging 的奇妙之处在于:它不改变单个模型的偏差(平均的仍然是同一类模型),却能把方差压到原来的约 1/T。因此它对“低偏差、高方差”的模型(典型如深决策树)提升立竿见影,对“高偏差”模型(如欠拟合的线性模型)几乎帮不上忙。

E[(y−f^(x))2]=σ2+Bias2(f^(x))+Var(f^(x))\displaystyle \mathbb{E}\big[(y - \hat{f}(x))^2\big] = \sigma^2 + \text{Bias}^2\big(\hat{f}(x)\big) + \text{Var}\big(\hat{f}(x)\big)

1. 噪声项:数据生成过程中的固有随机波动,任何模型都无法消除。

σ2=E[(y−f(x))2]\sigma^2 = \mathbb{E}\big[(y - f(x))^2\big]

2. 偏差平方:模型在众多训练集上的平均预测与真实规律的偏离程度。

Bias2=(f(x)−E[f^(x)])2\text{Bias}^2 = \big(f(x) - \mathbb{E}[\hat{f}(x)]\big)^2

3. 方差项:模型预测围绕其期望的波动幅度,正是 Bagging 着力压制的对象。

Var=E[(f^(x)−E[f^(x)])2]\text{Var} = \mathbb{E}\Big[\big(\hat{f}(x) - \mathbb{E}[\hat{f}(x)]\big)^2\Big]

如果食客们全都“只会说好吃”(系统性偏差),投票再多也还是两个字;但如果只是“时好时坏”(方差),一桌人平均下来就是稳定发挥。偏差与方差的这场博弈,决定了 Bagging 什么时候是神药、什么时候是安慰剂。

Bagging对比Boosting

两种团建方式:一种是“自助评审团”——大家各吃各的,最后投票;另一种是“闯关训练营”——第二个人专挑第一个人评错的菜再评,后面的人依次踩在前人的肩膀上。前者是 Bagging,并行、等权、主降方差;后者是 Boosting,串行、加权、主降偏差。AdaBoost、GBDT、XGBoost 都属于 Boosting 家族。

从数学形式上看,两者都可以写成“基学习器加权求和后取符号”的加性模型。区别在于权重怎么来:Bagging 对每个模型一视同仁,权重恒为 1;Boosting 则给每个模型分配一个权重 α_t,准确率越高的模型权重越大,并且每次迭代都会加大对上一轮错分样本的关注。一个靠“自助”制造差异,一个靠“纠错”步步紧逼。

HBagging(x)=sign⁡ ⁣(∑t=1Tht(x)),HBoosting(x)=sign⁡ ⁣(∑t=1Tαt ht(x))\displaystyle H_{\text{Bagging}}(x) = \operatorname{sign}\!\left(\sum_{t=1}^{T} h_t(x)\right), \qquad H_{\text{Boosting}}(x) = \operatorname{sign}\!\left(\sum_{t=1}^{T} \alpha_t\, h_t(x)\right)

1. 统一视角:两者都是“基学习器加权求和后取符号”的加性模型。

H(x)=sign⁡ ⁣(∑t=1Twt ht(x))H(x) = \operatorname{sign}\!\left(\sum_{t=1}^{T} w_t\, h_t(x)\right)

2. Bagging 的等权:所有模型权重相同 w_t = 1,纯靠票数说话。

wt=1,t=1,2,…,Tw_t = 1,\quad t = 1, 2, \dots, T

3. Boosting 的加权:权重 α_t 由该模型的加权错误率 ε_t 决定,错得越少权重越大。

αt=12ln⁡1−εtεt\alpha_t = \frac{1}{2}\ln\frac{1-\varepsilon_t}{\varepsilon_t}

4. 一句话差异:Bagging 求“稳”,Boosting 求“准”——分别对应方差与偏差。

εt↑  ⇒  αt↓\varepsilon_t \uparrow \;\Rightarrow\; \alpha_t \downarrow

想要多家医院独立会诊得结论,选 Bagging;想让徒弟快速出师、专攻师父的错题,选 Boosting。两者没有绝对的优劣,只有是否匹配你的误差来源。

随机森林扩展

食客团有个隐患:如果大家私下都刷了同一份美食排行榜,口味会严重“撞车”——投票就退化成一个人投了十票。怎么办?没收攻略,每人只发菜单的一页:有人只看前菜,有人只看主菜,有人只看甜点。随机森林正是这个思路的系统化:在 Bagging 基础上加入“特征随机选择”。

随机森林(Random Forest)= Bagging + CART 决策树 + 特征随机选择。每棵树在分裂时,不是从所有 d 个特征里挑最优,而是先从特征全集里随机抽 k 个(常用 k = log₂(d) 或 √d),再在这 k 个里选最优。这强制让不同树的“关注点”错开,树与树之间的相关性大幅降低,方差压缩效果比朴素 Bagging 更好。它还附带两个赠品:OOB 误差免费做验证,以及基于 Gini 不纯度下降量计算的特征重要性。

Gini(D)=1−∑k=1Kpk2\displaystyle \text{Gini}(D) = 1 - \sum_{k=1}^{K} p_k^2

1. 类别占比:数据集 D 中第 k 类样本所占比例记为 p_k。

pk=∣Dk∣∣D∣p_k = \frac{|D_k|}{|D|}

2. 占比平方和:平方和越大,说明样本越集中在少数类别,节点越“纯”。

∑k=1Kpk2\sum_{k=1}^{K} p_k^2

3. 补成不纯度:1 减去平方和得到 Gini 不纯度,值越小越好;CART 分裂时选择使 Gini 下降最多的特征。

Gini(D)=1−∑k=1Kpk2\text{Gini}(D) = 1 - \sum_{k=1}^{K} p_k^2

“没收美食榜、随机发菜单”,让每位食客的偏见不再同步,投票质量反而更高。随机森林也因此被许多人视为 Bagging 家族最成熟、最实用的成员。

流程与实战

把整套食客评审写成标准手册:筹备组(确定模型数量 T)→ 发菜单(自助采样)→ 隔离试吃(并行训练)→ 收评分(汇总预测)→ 复盘(OOB 检验)。Bagging 的算法流程同样清晰:对 t = 1 到 T,先从原始数据有放回地抽 m 次得到自助训练集,再在每份训练集上独立训练一个基学习器;预测时,分类用多数投票、回归用平均。

实战中最重要的参数是 T(基学习器数量)和基学习器的容量。T 越大结果越稳,但边际收益递减,一般 100~500 足够;基学习器建议选“高方差”模型(如不剪枝的深决策树),否则 Bagging 收益有限。另一个高频技巧是用 OOB 误差代替交叉验证——它几乎零成本,却与测试误差高度相关。

εOOB=1m∑i=1m1(HOOB(xi)≠yi)\displaystyle \varepsilon_{\text{OOB}} = \frac{1}{m}\sum_{i=1}^{m}\mathbb{1}\big(H_{\text{OOB}}(x_i) \neq y_i\big)

1. 袋外成员集合:对样本 i,收集所有未把它纳入训练集的基学习器,记为集合 T(i)。

T(i)={t∣i∉Dt}\mathcal{T}(i) = \{ t \mid i \notin D_t \}

2. 袋外投票:只用这些“没见过 i”的学习器对 i 做多数投票,得到 OOB 预测。

HOOB(xi)=arg⁡max⁡y  ∑t∈T(i)1(ht(xi)=y)H_{\text{OOB}}(x_i) = \arg\max_{y}\; \sum_{t \in \mathcal{T}(i)} \mathbb{1}\big(h_t(x_i) = y\big)

3. 平均错误率:对所有样本的错误指示取平均,得到泛化误差的估计值。

εOOB=1m∑i=1m1(HOOB(xi)≠yi)\varepsilon_{\text{OOB}} = \frac{1}{m}\sum_{i=1}^{m}\mathbb{1}\big(H_{\text{OOB}}(x_i) \neq y_i\big)

手册写完了,餐厅也要开业了。Bagging 就是那种“平凡但可靠”的招数:没有花哨的聪明,却能在风控、推荐、医疗等场景里稳稳坐镇 C 位。

AI 应用场景

信贷风控中的反欺诈识别

阶段:模型训练与评估

解决的问题:交易数据维度高、噪声大、正负样本极不平衡,单棵决策树对个别异常商户过拟合,线上 AUC 波动明显。Bagging 通过自助采样 + 多树投票显著压低方差,让欺诈识别更稳定。

具体案例:某支付平台对 24 小时内的交易做实时风控,用 500 棵树的随机森林为每笔交易输出“欺诈概率”,并借助 OOB 误差免去额外切分验证集。模型上线后,误报率下降了约 18%,深夜大额交易识别召回率提升 12%。

电商销量预测与库存备货

阶段:预测建模与上线监控

解决的问题:销量序列受促销、天气、节假日多重因素干扰,单模型预测方差大,常导致缺货或积压。Bagging 回归把“一锤子买卖”变成“全体表决”,预测曲线大幅平滑。

具体案例:某零售企业用 Bagging 回归(基学习器为深回归树)预测 SKU 日销量,相比单棵 CART,RMSE 下降 12%;且训练过程天然并行,全量 2000 万条数据仅需 40 分钟即可完成重训。

医疗辅助诊断的特征重要性排序

阶段:特征工程与可解释性分析

解决的问题:医生需要知道哪些指标(年龄、血压、某项化验值)对诊断最关键,传统逻辑回归系数不稳定且难以解释。随机森林基于 Gini 下降量输出特征重要性排序,成为沟通医生与算法的“翻译官”。

具体案例:某医疗 AI 团队用随机森林从 80 项体检指标中筛出与糖尿病强相关的 12 项,生成重要性条形图辅助医生解读,并作为后续深度模型的特征白名单,模型可解释性与性能同时提升。

Python 演示

python77 行
"""从零实现 Bagging:Bootstrap 有放回采样 + 决策树桩 + 多数投票"""import numpy as np  class Stump:    """决策树桩:在某个特征上寻找最优阈值做二分,作为弱学习器"""     def __init__(self):        self.feat = 0        self.thr = 0.0        self.left = 0        self.right = 1     def fit(self, X, y):        best_err = 1.0        for f in range(X.shape[1]):            vals = np.unique(X[:, f])            if vals.size < 2:                continue            for t in (vals[:-1] + vals[1:]) / 2:                mask = X[:, f] <= t                for l in (0, 1):                    err = (np.sum(y[mask] != l) + np.sum(y[~mask] != 1 - l)) / len(y)                    if err < best_err:                        best_err = err                        self.feat, self.thr = f, t                        self.left, self.right = l, 1 - l     def predict(self, X):        return np.where(X[:, self.feat] <= self.thr, self.left, self.right)  class Bagging:    """Bagging 集成:对每个基学习器做 bootstrap 采样,独立训练,最后投票"""     def __init__(self, n_estimators=50):        self.n_estimators = n_estimators        self.models = []     def fit(self, X, y):        n = len(X)        for _ in range(self.n_estimators):            idx = np.random.choice(n, n, replace=True)   # 有放回采样            weak = Stump()            weak.fit(X[idx], y[idx])            self.models.append(weak)     def predict(self, X):        votes = np.zeros((len(X), 2))        for m in self.models:            votes[np.arange(len(X)), m.predict(X)] += 1        return votes.argmax(axis=1)  if __name__ == "__main__":    rng = np.random.RandomState(42)    X0 = rng.randn(300, 2) + np.array([-2.0, 0.0])    X1 = rng.randn(300, 2) + np.array([2.0, 0.0])    X = np.vstack([X0, X1])    y = np.array([0] * 300 + [1] * 300)     order = rng.permutation(len(X))    X, y = X[order], y[order]     X_train, y_train = X[:480], y[:480]    X_test, y_test = X[480:], y[480:]     single = Stump()    single.fit(X_train, y_train)    acc1 = np.mean(single.predict(X_test) == y_test)     bag = Bagging(n_estimators=50)    bag.fit(X_train, y_train)    acc2 = np.mean(bag.predict(X_test) == y_test)     print("单棵决策树桩准确率: %.3f" % acc1)    print("Bagging 集成准确率: %.3f" % acc2)
目的:用不到 100 行代码实现完整的 Bagging 流程——Bootstrap 有放回采样、并行训练的决策树桩、多数投票预测,并对比单模型与集成的准确率差距。
  1. idx = np.random.choice(n, n, replace=True)核心的“有放回抽样”,产出与原始数据等大的自助样本,正是自助餐式取菜
  2. weak.fit(X[idx], y[idx])每个弱学习器只在各自的自助样本上训练,互不通信,对应“分桌试吃”
  3. self.models.append(weak)T 个模型各练各的,最后统一汇总,体现并行化的思想
  4. votes[np.arange(len(X)), m.predict(X)] += 1对每个测试样本按模型预测的类别累加票数,实现多数投票
  5. votes.argmax(axis=1)返回票数最多的类别,就是 Bagging 的最终判决

常见误区

误区我以为 Bagging 就是“多弄几个模型一起投票”,那对欠拟合的模型也应该有效,把线性模型 Bagging 一下说不定也能大幅提升准确率吧?

正解Bagging 的核心能力是降低方差,而不是补救偏差。如果单个模型存在系统性偏差(比如线性模型去拟合明显非线性的关系),无论并行多少个、投多少次票,错的方向是一致的,平均之后依然错。这就像十个食客都只爱吃甜的,投再多次也评不出咸淡。Bagging 对“准但飘”(低偏差高方差)的模型——深决策树、近邻模型——效果最好。

为何常见:很多人把“集成 = 多模型 = 更准”当成铁律,忽略了 Bagging 的数学机制是方差平均;看到随机森林效果好,就误以为它对所有模型一视同仁。

误区有放回抽样,那不是每次只抽到了 63% 的样本吗?白白丢了 37% 的数据,模型会不会欠拟合?

正解自助抽样得到的新训练集和原始数据一样大:抽 m 次就有 m 条记录,只是其中约 36.8% 是重复出现的。所谓“63.2% 的样本被抽中”指的是不同样本的覆盖率,不是样本容量缩水。相反,在小样本场景下 bootstrap 尤其受欢迎,因为它不需要额外划分数据就能变出多份训练集;而被漏掉的样本恰好作为袋外数据用于验证。

为何常见:把“被抽中的概率约 63.2%”误听成“样本容量只剩 63.2%”,混淆了概率表述与容量变化。

误区既然是并行训练、互不通信,那 Bagging 的 T 个模型就是完全独立的,方差应该严格降为原来的 1/T 才对。

正解模型之间只是“近似独立”。它们共享同一份原始数据(尽管自助样本不同),也用同一个模型族和同样的超参数,因此预测结果之间存在正相关。方差的实际缩减比例取决于模型间的相关系数 ρ:ρ 越大,Bagging 的收益越小。这也正是随机森林要做“特征随机选择”来压低 ρ 的原因。

为何常见:“并行”让人直觉联想到“独立”,却忽略了样本同分布和同模型族带来的天然相关性。

误区每次总有约 37% 的样本没被抽到,这些数据既不参与训练、又舍不得删,感觉特别鸡肋。

正解OOB 数据是免费的验证集。对样本 i,只用那些“没见过它”的基学习器投票,得到预测后统计错误率,就是 OOB 误差——它与交叉验证得到的泛化误差高度一致,且几乎不增加计算成本。随机森林的特征重要性也大量借助 OOB 或节点纯度下降来实现。可以说,OOB 是 Bagging 顺带送的“体检报告”。

为何常见:初学者只关注“训练要用哪些数据”,还没有建立验证与泛化的视角,自然看不到 OOB 的复用价值。

面试题

Q1. 在 Bagging 中,每个基学习器的训练数据是如何得到的?

单选题 · easy

  • A.直接使用全量原始数据
  • B.有放回的自助采样← 正确答案
  • C.无放回的均匀抽样
  • D.按特征重要性加权抽样

答案:B。Bagging 对原始 m 条样本做“有放回地抽 m 次”,得到与原始数据同大小、约含 63.2% 不同样本的训练集。A 是普通训练,没有多样性;C 是无放回抽样(对应 pasting);D 是特征层面的操作。就像食客从菜单上有放回地取菜。

Q2. Bootstrap 采样中,某个样本在一次抽样中从未被抽中的概率约为多少?

单选题 · easy

  • A.0.368← 正确答案
  • B.0.632
  • C.0.500
  • D.0.135

答案:A。(1 − 1/m)^m 在 m 很大时趋近 e⁻¹ ≈ 0.368,所以样本“被抽中”的概率约 0.632。B 是被抽中的概率;C 是无放回抽一半的直觉;D 是 e⁻²。这对应食客从未尝过某道菜的概率。

Q3. 假设 T 个基学习器互不相关、方差均为 σ²,则取平均后的方差约为多少?

单选题 · mid

  • A.σ²
  • B.σ²/T← 正确答案
  • C.Tσ²
  • D.σ/T

答案:B。Var((1/T)Σh_t) = (1/T²)·Tσ² = σ²/T,这是“平均化降低方差”的数学依据。注意现实中模型间有正相关,实际收益小于该理想值;Tσ² 是错误地把方差相加当结论。

Q4. Bagging 主要能降低机器学习误差中的哪一项?

单选题 · mid

  • A.噪声
  • B.偏差
  • C.方差← 正确答案
  • D.数据缺失

答案:C。Bagging 通过重采样与组合,把多个模型的预测平均化,核心作用是压缩方差项;它不改变单个模型的系统性偏差,对噪声也基本无能为力。这正是它与 Boosting(主降偏差)的本质分工。

Q5. 下列哪种基学习器最适合发挥 Bagging 的优势?

单选题 · mid

  • A.线性回归
  • B.深决策树← 正确答案
  • C.逻辑回归
  • D.朴素贝叶斯

答案:B。深决策树是典型“低偏差、高方差”模型——换一批数据决策边界就剧烈变化,Bagging 恰好吃这一口,把抖动边界平均得平滑稳定。线性模型和逻辑回归偏差主导,集成收益有限。

Q6. 关于随机森林,下列说法正确的有哪些?

多选题 · mid

  • A.是 Bagging 加决策树的组合← 正确答案
  • B.同时随机选择特征子集← 正确答案
  • C.只能用于回归问题
  • D.可以用 OOB 误差做验证← 正确答案

答案:ABD。随机森林 = Bagging + CART 决策树 + 特征随机选择(A、B 正确),并天然提供 OOB 验证(D)。C 错误:随机森林分类、回归都支持。特征随机化的目的是降低树间相关性,防止投票变成“重复表态”。

Q7. 随机森林中“特征随机选择”最主要的目的在于?

单选题 · extreme

  • A.加快模型收敛的速度
  • B.降低树与树的相关性← 正确答案
  • C.减少参与训练的特征数
  • D.提升单棵树的预测精度

答案:B。如果所有树都优先用最强的那个特征分裂,树之间会高度相似,投票等于一个人投了十票。随机选特征子集强制每棵树“各有侧重”,压低相关系数,让 Bagging 的方差压缩更有效。C 是伴随现象而不是目的;D 反而可能因特征受限而下降。

Q8. 关于 Bagging 的预测输出方式,下列说法正确的有哪些?

多选题 · mid

  • A.分类任务用多数投票← 正确答案
  • B.回归任务取模型平均← 正确答案
  • C.分类任务一定用平均
  • D.回归任务一定用中位数

答案:AB。分类用“少数服从多数”(众数),回归用“取平均”,这是 Bagging 的标准输出。C 和 D 张冠李戴;此外还有软投票——先平均概率再取类别,往往略优于硬投票。

Q9. 与 Boosting 相比,Bagging 的特点包括哪些?

多选题 · hard

  • A.各基学习器可并行训练← 正确答案
  • B.主要降低偏差而非方差
  • C.各模型以等权方式组合← 正确答案
  • D.对高方差模型更友好← 正确答案

答案:ACD。Bagging 各样本集独立、可并行(A),模型等权投票(C),主打降方差、对高方差模型友好(D)。B 说反了——“主要降低偏差”是 Boosting 的特征:串行训练、聚焦上一轮错分样本、按准确率加权。

Q10. sklearn 中用于直接构建 Bagging 分类器的类是哪个?

单选题 · easy

  • A.AdaBoostClassifier
  • B.BaggingClassifier← 正确答案
  • C.GradientBoostingRegressor
  • D.LogisticRegression

答案:B。BaggingClassifier 是通用 Bagging 封装,可指定基学习器(如决策树)。A 和 C 属于 Boosting 家族;D 是单模型。工程上也可直接用 RandomForestClassifier,它等价于“Bagging + 决策树 + 特征随机选择”。