想象你是一口大鱼塘的主人。你想知道塘里有多少条鱼,可一个人站在岸边数,怎么看都不准——今天风大、鱼群躲在深水区、阳光又晃眼,你数到的数量忽高忽低,像极了一个人拍脑袋做判断时的犹豫。 聪明的做法是请一群渔夫来帮忙:每个渔夫撒下一网,捞起几条鱼,数完又放回去(有放回),再捞一网。有人偏向浅滩,有人习惯深水,最后把所有人的估计放在一起取平均——这个平均数,远比任何单独一次估计都稳。 这个“捞了放回、多请渔夫、综合判断”的思路,就是机器学习里的 Bagging(Bootstrap Aggregating)。Bootstrap 是有放回采样,Aggregating 是聚合,它是最经典的“人多力量大”的智慧。本文就带你从这口鱼塘出发,看懂 Bootstrap 背后的概率、袋外样本的妙用、以及它为何能降低方差,最后看一看它最著名的应用——随机森林。

岗位关联

掌握 Bagging 与 Bootstrap,是理解随机森林、XGBoost 等主流集成模型的基石。面试常考、工程常用,学完后你在“模型为什么更稳”的问题上,就有了数学和直觉的双重底气。

目录
  1. 可视化演示
  2. Bagging集成思想
  3. Bootstrap采样
  4. 样本概率分析
  5. Out-of-bag估计
  6. 降低方差原理
  7. 随机森林
  8. 偏差方差权衡
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

通过逐步展示Lomuto分区法的快速排序过程,直观理解枢轴选择、分区操作与递归调用的执行流程。

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

快速排序 Lomuto 分区 紫色条为当前枢轴元素 粉色高亮为正在比较的元素 T(n) = O(n log n) 逐步展示分区与递归过程

Bagging集成思想

你站在鱼塘边数鱼,水面上波光粼粼。你数了一遍,大概 200 条;换个位置再数,变成了 160 条。鱼没变,为什么数字在变?因为每一次观察都带着偶然性——鱼群在游动、光线在折射、你的眼睛在疲劳。单独一次观察,就像一张曝光不准的照片,充满噪声。

机器学习里的“一锤子买卖”有同样的问题。假设你训练一棵决策树,训练数据的分布、噪声、抽样偏差,都会让这棵树的预测“忽高忽低”。统计学家把这种随机波动称为方差。Bagging 的策略简单而优雅:不要只训练一个模型,而是制造出 M 份“略有不同的训练数据”,在每个数据上训练一个独立的模型,最后让 M 个模型一起投票或取平均。这就是 Bagging(Bootstrap Aggregating)的核心思想,也叫自助采样集成。

具体分两步:第一步,用 Bootstrap 从原始训练集 \(D\) 中生成 M 个有差异的训练子集;第二步,在每个子集上独立训练一个基学习器,最终预测通过平均(回归)或多数投票(分类)得到。

就像你请十个渔夫分别估算鱼量:有人估多、有人估少,但平均下来往往接近真实值——运气差的那位被运气好的拉了回来。Bagging 不相信某一次观察,它相信群体判断。

f^(x)=1M∑i=1Mfi(x)\displaystyle \hat{f}(\mathbf{x}) = \frac{1}{M}\sum_{i=1}^{M} f_i(\mathbf{x})
这是 Bagging 在回归任务中的“最终答案”公式:把每个模型的预测值加起来求平均,让极端估计被拉回中心。
  1. 基模型预测\(f_i(\mathbf{x})\) 表示第 \(i\) 个模型对输入 \(\mathbf{x}\) 的预测结果。这里的 \(\mathbf{x}\) 可以是一份体检数据,也可以是一份用户画像。
    fi(x)\displaystyle f_i(\mathbf{x})
  2. 求和累加\(\sum_{i=1}^{M}\) 表示从第 1 个模型到第 \(M\) 个模型,把所有预测值加起来。
    ∑i=1Mfi(x)\displaystyle \sum_{i=1}^{M} f_i(\mathbf{x})
  3. 取平均\(\frac{1}{M}\) 把总和除以模型个数,得到平均预测。回归用平均,分类则改成“少数服从多数”的投票。
    1M∑i=1Mfi(x)\displaystyle \frac{1}{M}\sum_{i=1}^{M} f_i(\mathbf{x})

Bootstrap采样

渔夫下网捞鱼,最讲究“捞完放回”。放回意味着同一条鱼可能被同一个人捞到两次,也可能今天根本没进网。正是这种“重复”与“缺失”,让每一网鱼都成为鱼塘的一个独特缩影。

统计学中的 Bootstrap(自助法) 也是这个操作。给定包含 \(N\) 个记录的原始数据集 \(D\),用有放回抽样的方式,每次从中随机抽取 1 条记录,重复 \(N\) 次,得到新数据集 \(D'\)。这个 \(D'\) 的样本数仍然是 \(N\),但它并不等于 \(D\)——有些记录重复出现,有些记录一次都没出现。

每个基模型都使用一个不同的 \(D'\) 来训练。因为抽样过程带有随机性,M 个基模型的训练数据彼此差异明显,这保证了模型之间的“多样性”——多样性正是集成能生效的前提。

每一网都有自己独特的“鱼组合”:有的鱼被反复捞起,有的鱼从未露面。Bootstrap 正是用这种看似随意的“捞了放回”,为每一个基模型提供了一份差异化十足的训练菜单。

P(xj 在每次抽样中被选中)=1N\displaystyle P\left(x_j \text{ 在每次抽样中被选中}\right) = \frac{1}{N}
这是“捞鱼放回”的数学表达:在 \(N\) 条鱼中捞一条,每条鱼被捞到的机会均等。
  1. 样本标识\(x_j\) 表示数据集中的第 \(j\) 个样本,对应鱼塘里的某一条特定的鱼。
    xj\displaystyle x_j
  2. 等概率抽取每次抽样时,\(N\) 个样本被抽中的概率都是 \(\frac{1}{N}\),一视同仁。
    1N\displaystyle \frac{1}{N}
  3. 有放回的含义抽中后放回,下一次抽样时它还有同样的概率再次被抽中,所以一轮中可能多次出现同一个样本。
    P(xj)=1N(每次都相同)\displaystyle P(x_j) = \frac{1}{N} \text{(每次都相同)}

样本概率分析

现在到了最有趣的部分。一个渔夫捞一网鱼要捞 \(N\) 次,那么在全部 \(N\) 次捞取中,某条特定的鱼一次都没被捞到的概率是多少?直觉上好像不低——毕竟鱼塘那么大。

算一下:单次抽样没抽到这条鱼的概率是 \(1 - \frac{1}{N}\)。因为每次抽样相互独立,连续 \(N\) 次都没抽到它的概率就是 \(\left(1 - \frac{1}{N}\right)^{N}\)。当 \(N\) 足够大时,这个值趋近于 \(e^{-1} \approx 0.368\)。也就是说,一个 Bootstrap 数据集大约包含原始数据中 63.2% 的不同样本,而 36.8% 的样本被漏掉了。

原来,一网鱼从来不是鱼塘的完整复制品,而是约三分之二的面孔加上三分之一的老朋友。重复与缺失交织,这正是 Bootstrap 产生多样性的根源:每个基模型都在“熟悉的 63.2% 加上陌生的 36.8%”里学习。

lim⁡N→∞(1−1N)N=e−1≈0.368\displaystyle \lim_{N \to \infty}\left(1 - \frac{1}{N}\right)^{N} = e^{-1} \approx 0.368
这个极限公式是“漏网之鱼”比例的数学根源,也是 Bagging 一切性质的出发点。
  1. 单次未中概率\(1 - \frac{1}{N}\) 表示一次抽样中,某条鱼没被抽到的机会。
    1−1N\displaystyle 1 - \frac{1}{N}
  2. 连续 N 次未中\(\left(1 - \frac{1}{N}\right)^{N}\) 是 N 次独立抽样都没抽到它的概率,这里使用了独立事件概率相乘的原则。
    (1−1N)N\displaystyle \left(1 - \frac{1}{N}\right)^{N}
  3. 取极限当 \(N \to \infty\) 时,该式子收敛到 \(e^{-1}\),约 36.8%。这是数学中的重要极限。
    lim⁡N→∞(1−1N)N=e−1\displaystyle \lim_{N \to \infty}\left(1 - \frac{1}{N}\right)^{N} = e^{-1}
  4. 至少一次的概率反过来,\(1 - e^{-1} \approx 0.632\),这就是著名的 63.2% 法则。
    1−e−1≈0.632\displaystyle 1 - e^{-1} \approx 0.632

Out-of-bag估计

细心的渔夫会发现一个现象:每次捞鱼,总有约 37% 的鱼没被捞进这一网。这些“漏网之鱼”不仅不是浪费,反而成了免费的考官。

在 Bagging 中,对某个基模型来说,训练它所用的 Bootstrap 样本里没有出现的那些原始样本,叫做 Out-of-Bag(袋外)样本。用这些样本去测试这个模型,就能在完全不碰测试集的情况下估计它的表现。把所有样本的袋外预测汇总起来,计算出的误差叫袋外误差(OOB Error)。

袋外误差的效果与交叉验证非常接近,但几乎不增加额外计算成本——因为每个基模型训练完后,顺手就能用没见过的样本做一次检验。这也是 Bagging 比普通模型更“省钱”的地方:不需要专门划分验证集。

每一网鱼都在不知不觉中帮我们检验了渔夫的眼光:不是让渔夫自我评价,而是请那些没被他捞到的鱼来打分。袋外样本是 Bagging 自带的验证机制,既便宜又靠谱。

Eoob=1N∑i=1Nℓ(yi,y^ioob)\displaystyle E_{\text{oob}} = \frac{1}{N}\sum_{i=1}^{N} \ell\left(y_i, \hat{y}_i^{\text{oob}}\right)
袋外误差的公式:把每个样本的真实标签和“没见过它的那些模型”的预测进行比较,误差求平均。
  1. 真实标签\(y_i\) 是第 \(i\) 个样本的真实答案,对应鱼的真实重量。
    yi\displaystyle y_i
  2. 袋外预测\(\hat{y}_i^{\text{oob}}\) 是集成中所有“训练时没见过样本 \(i\)”的模型对它的投票或平均预测,也就是没捞到这条鱼的渔夫对它的评价。
    y^ioob\displaystyle \hat{y}_i^{\text{oob}}
  3. 损失函数\(\ell(y_i, \hat{y}_i^{\text{oob}})\) 比较真实值与袋外预测的差距,分类任务常用 0-1 损失,回归任务常用平方误差。
    ℓ(yi,y^ioob)\displaystyle \ell\left(y_i, \hat{y}_i^{\text{oob}}\right)
  4. 平均\(\frac{1}{N}\sum_{i=1}^{N}\) 把所有样本的损失平均,得到整体袋外误差。
    1N∑i=1Nℓ(yi,y^ioob)\displaystyle \frac{1}{N}\sum_{i=1}^{N} \ell\left(y_i, \hat{y}_i^{\text{oob}}\right)

降低方差原理

十个渔夫的平均估计,为什么比单个渔夫稳?数学上,如果每个渔夫的估计都围绕真实值波动,且这些波动彼此独立,那么十个估计取平均后,波动幅度会显著缩小。

设每个基模型的预测方差为 \(\sigma^2\)。如果 M 个模型完全独立,平均预测的方差是 \(\frac{\sigma^2}{M}\),模型越多,方差越小。但 Bagging 的各个模型并不完全独立——它们共享同一份训练数据来源、使用相同的算法。引入相关系数 \(\rho\) 后,方差会打折,但整体仍低于单模型。

渔夫们虽然能各自下网,但都站在同一片水域、看着同一片天,他们的估计不可能完全独立——这就是 \(\rho\) 的含义。但只要不是完全复读机,集成平均依旧能把波动压下去。

Var⁡(1M∑i=1Mfi(x))=ρσ2+1−ρMσ2\displaystyle \operatorname{Var}\left(\frac{1}{M}\sum_{i=1}^{M} f_i(\mathbf{x})\right) = \rho\sigma^2 + \frac{1 - \rho}{M}\sigma^2
这是“人多力量大”的精确公式:当模型间相关度 \(\rho\) 越高,方差缩减效果越差;当 \(\rho\) 越低,效果越接近理想的 \(\sigma^2/M\)。
  1. 平均预测\(\frac{1}{M}\sum_{i=1}^{M} f_i(\mathbf{x})\) 表示把 M 个模型的预测取平均,这是 Bagging 的聚合方式。
    1M∑i=1Mfi(x)\displaystyle \frac{1}{M}\sum_{i=1}^{M} f_i(\mathbf{x})
  2. 完全独立时当 \(\rho = 0\),方差退化为 \(\frac{\sigma^2}{M}\),这是最理想的情况,模型越多越稳。
    ρσ2+1−ρMσ2=ρ=0σ2M\displaystyle \rho\sigma^2 + \frac{1-\rho}{M}\sigma^2 \overset{\rho=0}{=} \frac{\sigma^2}{M}
  3. 完全相关时当 \(\rho = 1\),方差等于 \(\sigma^2\),集成毫无增益——相当于请了一百个步调完全一致的渔夫。
    ρσ2+1−ρMσ2=ρ=1σ2\displaystyle \rho\sigma^2 + \frac{1-\rho}{M}\sigma^2 \overset{\rho=1}{=} \sigma^2
  4. 现实情况\(0 < \rho < 1\),整体方差介于 \(\sigma^2/M\) 和 \(\sigma^2\) 之间,仍然小于单模型的 \(\sigma^2\)。
    σ2M≤Var⁡≤σ2\displaystyle \frac{\sigma^2}{M} \le \operatorname{Var} \le \sigma^2

随机森林

如果每个渔夫捞鱼的网眼大小、下网角度都一模一样,他们的估计虽然略有不同,但也高度相似。怎么让渔夫们看到更多不同的风景?随机森林的答案是:除了每轮捞到的鱼不同,还要让每个渔夫专注于不同的“水域特征”。

随机森林(Random Forest) 是 Bagging 与随机特征选择的结合。它在有放回采样的基础上,进一步让决策树在每个节点分裂时,不是从全部特征中选最优,而是先从 \(d\) 个特征中随机挑出 \(k\) 个(通常 \(k = \sqrt{d}\)),再从这 \(k\) 个里选最优。这样一来,每棵树之间更加“风格各异”,树间相关性 \(\rho\) 大幅下降,方差被进一步压缩。

随机森林几乎不需要调参,自带 OOB 误差估计,还能输出特征重要性,因此被誉为“开箱即用的冠军算法”。

有的渔夫擅长看浅滩,有的渔夫熟悉深水——每个人掌握的信息维度各不相同,合在一起才构成对整口鱼塘的完整认知。随机森林正是通过“差异化采样 + 差异化视角”让森林里的每一棵树都独一无二。

f^(x)=majority_vote⁡(f1(x),f2(x),…,fT(x))\displaystyle \hat{f}(\mathbf{x}) = \operatorname{majority\_vote}\left(f_1(\mathbf{x}), f_2(\mathbf{x}), \ldots, f_T(\mathbf{x})\right)
随机森林的预测方式:让每棵树投票,票数最多的类别获胜。
  1. T 棵树森林中共有 \(T\) 棵决策树,每棵树都是在一个 Bootstrap 样本上训练出来的。
    T\displaystyle T
  2. 每棵树的独立预测\(f_1(\mathbf{x}), f_2(\mathbf{x}), \ldots, f_T(\mathbf{x})\) 分别表示每棵树对输入 \(\mathbf{x}\) 的预测,它们互不商量。
    f1(x),f2(x),…,fT(x)\displaystyle f_1(\mathbf{x}), f_2(\mathbf{x}), \ldots, f_T(\mathbf{x})
  3. 多数投票\(\operatorname{majority\_vote}(\cdot)\) 统计每个类别的得票数,取最高的作为最终输出;回归任务则改为取平均。
    f^(x)=argmaxc∑t=1T1(ft(x)=c)\displaystyle \hat{f}(\mathbf{x}) = \text{argmax}_c \sum_{t=1}^{T} \mathbb{1}\left(f_t(\mathbf{x}) = c\right)

偏差方差权衡

是不是渔夫请得越多越好?不一定。如果每个渔夫都有严重近视,连鱼和石头都分不清,那请一百个也白搭。Bagging 这只“集成之手”只能抚平方差,却改变不了偏差。

泛化误差可以分解为三部分:噪声、偏差的平方、方差。Bagging 通过平均降低方差,而偏差几乎不变。

理解了分解,就懂了适用边界:Bagging 最适合“低偏差、高方差”的模型,比如深度较深、容易过拟合的决策树。反过来,对于线性回归这类低方差模型,Bagging 的增益就很小。选对方法的前提是看懂问题——当你面对一群“各自有主见但不离大谱”的渔夫时,请一百个来取平均,就是最好的方案。

Err⁡(x)=σε2+Bias⁡(f^(x))2+Var⁡(f^(x))\displaystyle \operatorname{Err}(\mathbf{x}) = \sigma_{\varepsilon}^{2} + \operatorname{Bias}\left(\hat{f}(\mathbf{x})\right)^{2} + \operatorname{Var}\left(\hat{f}(\mathbf{x})\right)
偏差方差分解:总误差 = 数据自身噪声 + 模型系统性偏差 + 模型随机波动。
  1. 噪声项\(\sigma_{\varepsilon}^{2}\) 是数据内部的固有噪声,任何模型都无法消除,好比天气对捞鱼的影响。
    σε2\displaystyle \sigma_{\varepsilon}^{2}
  2. 偏差平方\(\operatorname{Bias}\left(\hat{f}(\mathbf{x})\right)^{2}\) 衡量模型系统性偏离真实规律的程度,相当于渔夫的“近视度数”。
    Bias⁡(f^(x))2\displaystyle \operatorname{Bias}\left(\hat{f}(\mathbf{x})\right)^{2}
  3. 方差项\(\operatorname{Var}\left(\hat{f}(\mathbf{x})\right)\) 衡量模型在不同训练数据上的波动,相当于渔夫受天气影响的程度。
    Var⁡(f^(x))\displaystyle \operatorname{Var}\left(\hat{f}(\mathbf{x})\right)
  4. Bagging 的作用它几乎只让第三项变小,前两项保持不变。
    Var⁡bag<Var⁡single\displaystyle \operatorname{Var}_{\text{bag}} < \operatorname{Var}_{\text{single}}

AI 应用场景

银行信贷风控

阶段:模型训练与部署

解决的问题:信用评估需要极低的误判率。传统单棵决策树容易因个别异常客户产生大幅波动,导致不同时期的审批结果不稳定,引发客户投诉和监管风险。

具体案例:某银行用随机森林替代单棵决策树做贷款违约预测。每棵树在 Bootstrap 抽样产生的客户子集上训练,并随机选择收入、负债、征信查询次数等特征子集,最后按树投票决定是否放贷。上线后模型 AUC 明显提升,更重要的是每个月重新训练时,评分波动显著减小,风控策略变得可预期。

电商用户购买预测

阶段:模型评估与调参

解决的问题:训练集有限,又想在训练时快速验证模型效果。传统做法需要专门划分验证集,浪费宝贵数据,且每轮调参都要重新训练。

具体案例:某电商平台使用 Bagging 预测用户未来 7 天购买概率。训练过程中直接读取 OOB 误差来调整树的数量和深度,省去了额外验证集的划分。最终用 OOB 误差选出的模型上线后,A/B 测试的转化率提升 5%,而整个过程没有多花一份验证数据。

医疗辅助诊断

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

解决的问题:医疗数据特征多(几百项化验指标)、样本少,单一模型极易过拟合。随机森林的特征随机和 Bootstrap 能有效降低方差,还能量化特征重要性,帮助医生理解模型判断依据。

具体案例:用随机森林做糖尿病风险筛查,模型输出糖化血红蛋白、BMI、家族史等指标的重要性排序,辅助医生快速锁定关键风险因素。多位“渔夫”(弱学习器)会诊的预测结果,比单模型更稳健,也更容易通过医疗合规审查。

Python 演示

python82 行
import numpy as npfrom collections import Counterfrom sklearn.tree import DecisionTreeClassifierfrom sklearn.datasets import load_irisfrom sklearn.model_selection import train_test_splitfrom sklearn.metrics import accuracy_score  def majority_vote(votes):    """对每一列样本取众数,返回多数投票结果。"""    votes = np.atleast_2d(votes)    n = votes.shape[1]    result = []    for j in range(n):        counter = Counter(votes[:, j])        result.append(counter.most_common(1)[0][0])    return np.array(result)  class MyBagging:    """一个极简 Bagging 分类器:Bootstrap 采样 + 决策树投票。"""     def __init__(self, n_estimators=10, max_depth=3, seed=42):        self.n_estimators = n_estimators        self.max_depth = max_depth        self.seed = seed        self.trees_ = []        self.oob_trees_ = []     def fit(self, X, y):        rng = np.random.RandomState(self.seed)        n = len(X)        self.oob_trees_ = [[] for _ in range(n)]         for _ in range(self.n_estimators):            # 有放回地抽 n 次,生成一个 bootstrap 样本集            boot_idx = rng.randint(0, n, n)            tree = DecisionTreeClassifier(                max_depth=self.max_depth, random_state=0            )            tree.fit(X[boot_idx], y[boot_idx])            self.trees_.append(tree)             # 找出本轮没被抽中的样本(袋外样本)            in_bag = np.zeros(n, dtype=bool)            in_bag[boot_idx] = True            for i in range(n):                if not in_bag[i]:                    self.oob_trees_[i].append(tree)         # 用袋外样本估计泛化误差        oob_pred = np.full(n, -1)        for i in range(n):            if self.oob_trees_[i]:                votes_i = np.array([                    t.predict(X[i:i + 1])[0] for t in self.oob_trees_[i]                ])                oob_pred[i] = majority_vote(votes_i)[0]         valid = oob_pred != -1        self.oob_error_ = 1.0 - accuracy_score(y[valid], oob_pred[valid])        return self     def predict(self, X):        votes = np.array([tree.predict(X) for tree in self.trees_])        return majority_vote(votes)  if __name__ == "__main__":    data = load_iris()    X_train, X_test, y_train, y_test = train_test_split(        data.data, data.target, test_size=0.3, random_state=42    )     bag = MyBagging(n_estimators=20, max_depth=3, seed=1)    bag.fit(X_train, y_train)     pred = bag.predict(X_test)    acc = accuracy_score(y_test, pred)    print("测试集准确率: {:.2%}".format(acc))    print("袋外误差: {:.2%}".format(bag.oob_error_))    print("基模型数量:", len(bag.trees_))
目的:从零实现一个极简 Bagging 分类器,直观展示 Bootstrap 有放回采样、袋外样本收集与多数投票,并在鸢尾花数据集上验证效果与 OOB 误差。
  1. boot_idx = rng.randint(0, n, n)有放回抽样的核心:从 0 到 n-1 随机抽 n 次,同一索引可能出现多次。
  2. tree.fit(X[boot_idx], y[boot_idx])在包含重复样本的 bootstrap 训练集上训练一棵决策树。
  3. if not in_bag[i]: self.oob_trees_[i].append(tree)把当前模型登记到它的“袋外样本”名下,供后续验证。
  4. votes = np.array([tree.predict(X) for tree in self.trees_])集成中每棵树对测试集独立预测,构成投票矩阵。
  5. self.oob_error_ = 1.0 - accuracy_score(y[valid], oob_pred[valid])袋外误差 = 1 - 袋外准确率,是免费的泛化能力估计。

常见误区

误区有放回采样会让同一个样本反复出现,相当于人为放大训练集,模型看到太多重复数据,肯定更容易过拟合。

正解Bootstrap 生成的样本总量仍是 N,并没有真正放大数据。更重要的是,每个基模型面对的是不同的 Bootstrap 子集,每个模型都“漏看”了约 37% 的样本,模型之间的差异恰恰抑制了过拟合。Bagging 的本质是降低方差、让模型更稳,而不是加剧过拟合。就好比十个渔夫各捞各的网,谁也没把全部鱼都看一遍,最后综合判断反而更全面。

为何常见:把“重复”简单理解为“数据变冗余”,忽略了不同模型使用不同子集带来的多样性。

误区每次做 Bootstrap 采样,一定正好有 63.2% 的样本被抽中,37% 被漏掉。

正解63.2% 是当样本量 N 趋于无穷大时的期望值。实际采样时,每一轮的覆盖比例都在 63.2% 附近随机波动,N 越大越接近,N 较小时偏差更明显。比如 N=10 时,某轮可能覆盖 80%,下一轮可能只覆盖 50%。可视化演示里那条 63.2% 红线是理论参考,不该要求每轮完全吻合。

为何常见:把概率论中的数学期望与单次试验的观测值混为一谈,这是只看公式、没动手模拟时的典型误解。

误区Bagging 是集成方法,效果差就多训练几个模型取平均,线性回归欠拟合也能用它救回来。

正解Bagging 只降低方差、不减少偏差。如果线性回归本身欠拟合,主要问题是偏差过大,集成一百个线性回归仍然是一百个“偏差相同”的模型,平均后照样偏离真实规律。Bagging 的真正用武之地是低偏差、高方差的模型,比如深度较大的决策树。这就好比一群“脸盲”的渔夫:请得再多,也认不出鱼塘里都有什么鱼。

为何常见:只听到“集成提升效果”的结论,不理解偏差-方差分解的机制,导致不管模型类型盲目使用。

误区有了 OOB 误差就不需要划分测试集了,训练完直接拿 OOB 数字上线。

正解OOB 误差等价于在训练集内部做“免费的交叉验证”,帮助我们在调参和选择模型时估计泛化能力,省去单独留验证集的过程。但部署前仍需要用完全没参与过训练的独立测试集做最终验收,避免任何形式的参数选择偏差。袋外样本好比平时课堂测验,测试集才是期末考试,两者各有各的用途。

为何常见:混淆了“模型选择/调参用的验证集”和“最终评估用的测试集”这两种不同职责。

误区随机森林就是多训练几棵一模一样的决策树然后投票,跟普通 Bagging 差别不大。

正解随机森林除了 Bootstrap 采样,还会在每个节点随机挑选特征子集再找最优分裂。这第二重随机让树与树之间尽量“观点不同”,相关性更低。树的相关性越低,Bagging 的方差压降效果越好。如果每棵树都一模一样,投票就失去了意义,和单棵树没什么区别。

为何常见:只看到“树 + 集成”的表面,忽略了特征随机这一关键设计,也就不明白为什么随机森林比朴素 Bagging 更强。

面试题

Q1. Bootstrap 有放回采样的核心特征是?

单选题 · easy

  • A.抽取后不放回避免重复
  • B.每次抽取后记录再放回← 正确答案
  • C.按样本标签加权抽取
  • D.只抽取从未抽中的样本

答案:B。Bootstrap 的关键是“有放回”:抽中一条样本,记录后放回,下次还能再抽到它,所以一轮中会出现重复样本。A 是普通随机子采样,C 是加权采样,D 是不放回按需抽取,都不符合 Bootstrap 的定义。

Q2. 当原始样本数 N 足够大时,某个样本在 Bootstrap 采样中至少被抽中一次的概率约为?

单选题 · easy

  • A.50%
  • B.36.8%
  • C.63.2%← 正确答案
  • D.100%

答案:C。单次抽样有 \(1-1/N\) 的概率抽不中,连续 N 次都未中趋近 \(e^{-1}\approx36.8\%\),所以至少抽中一次的概率是 \(1-e^{-1}\approx63.2\%\)。B 是“从未被抽中”的概率,D 只有在不放回时才会出现。

Q3. 关于 Bagging 的最终预测方式,分类任务通常采用?

单选题 · easy

  • A.全部模型预测值相加
  • B.少数模型预测值取中位数
  • C.所有模型预测的多数投票← 正确答案
  • D.随机挑选一个模型的结果

答案:C。分类任务中,Bagging 让每个基模型投一票,统计所有模型的预测类别,得票最多的类别获胜,即少数服从多数。相加和取中位数是回归任务的思路,随机挑选一个模型则彻底失去集成意义。

Q4. Bagging 能有效降低模型误差中的哪一部分?

单选题 · mid

  • A.偏差与系统误差
  • B.方差与随机波动← 正确答案
  • C.噪声与环境干扰
  • D.以上全部误差项

答案:B。Bagging 的核心作用是降低方差:多个模型的平均或投票平滑了训练数据随机性带来的波动。偏差由模型本身表达能力决定,噪声是数据固有属性,这两者 Bagging 都无法改变。所以正确答案是 B。

Q5. Out-of-bag 样本指的是?

单选题 · mid

  • A.测试集中未标记的样本
  • B.训练时完全没见过的未来样本
  • C.未被当前模型 bootstrap 抽中的训练样本← 正确答案
  • D.所有模型都重复使用的样本

答案:C。OOB 样本是训练集内部、但没有出现在某个基模型 Bootstrap 采样中的样本。它们对该模型来说是“没见过的”,因此适合做验证。A 属于测试集,B 是真实世界的新样本,D 是每个模型都见过的样本,都不能作为袋外样本。

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

单选题 · mid

  • A.随机森林引入了特征子集随机性← 正确答案
  • B.随机森林的基模型通常是决策树← 正确答案
  • C.Bagging 不涉及特征随机选择← 正确答案
  • D.随机森林必须使用线性模型

答案:ABC。随机森林 = Bagging + 特征随机,基模型是决策树,它额外在每个节点随机挑选特征子集再分裂;而普通 Bagging 只用 Bootstrap 样本,不使用特征随机。D 完全错误,随机森林恰恰不用线性模型。注意题目为单选时若出现多个正确项应仔细审题。

Q7. 设 M 个模型的预测方差均为 σ²,两两相关系数为 ρ,则平均预测后的方差约为?

单选题 · hard

  • A.方差降至 σ²/M
  • B.方差变为 M 倍
  • C.方差介于 σ²/M 与 σ² 之间← 正确答案
  • D.方差保持不变

答案:C。考虑相关性的方差公式是 \(\rho\sigma^2 + (1-\rho)\sigma^2/M\)。当 ρ=0(完全独立)时降为 σ²/M;当 ρ=1(完全相关)时保持 σ²;现实中 0<ρ<1,方差介于两者之间。A 只适用于独立情形,B 与 D 方向错误。

Q8. 以下哪种模型最适合使用 Bagging?

单选题 · hard

  • A.高偏差低方差的线性回归
  • B.低偏差高方差的深决策树← 正确答案
  • C.低偏差低方差的支持向量机
  • D.高偏差高方差的朴素贝叶斯

答案:B。Bagging 只降方差不改偏差,所以最适合低偏差、高方差的模型。深决策树正是典型:单棵树拟合能力强(低偏差),但换数据波动大(高方差)。线性回归偏差大,SVM 方差通常不高,朴素贝叶斯偏差也大,Bagging 对它们帮助有限。

Q9. 关于 OOB 误差与验证策略,下列说法正确的有?

单选题 · mid

  • A.OOB 误差可近似交叉验证结果← 正确答案
  • B.OOB 误差无需额外划分验证集← 正确答案
  • C.OOB 误差不能替代最终测试集评估← 正确答案
  • D.OOB 误差一定比测试误差小很多

答案:ABC。OOB 误差用训练集内没被当前模型见过的样本估计泛化能力,效果接近交叉验证,且不用额外划分验证集,A、B 正确。但它仍是训练集内部的估计,不能替代独立测试集的最终验收,C 正确。OOB 误差与测试误差大小没有必然关系,D 错误。

Q10. 关于 Bootstrap 采样的统计性质,正确说法有?

单选题 · extreme

  • A.某样本一次抽样被抽中概率 1/N← 正确答案
  • B.某样本 N 次均未被抽中概率约 1/e← 正确答案
  • C.同一轮抽样中可能出现重复样本← 正确答案
  • D.每个样本至少被抽中一次的概率约 0.632← 正确答案

答案:ABCD。四项全部正确。每次抽样等概率抽中某个样本,概率是 1/N,A 正确;由于有放回,一轮 N 次抽样中可能反复抽到同一个样本,C 正确;连续 N 次都未抽中的概率极限是 1/e≈36.8%,B 正确;反过来至少抽中一次的概率约 63.2%,D 正确。这道题完整考察了 Bootstrap 的三大统计性质。