假如你想知道新开张的餐厅值不值得推荐,你有两种选择:请一位美食评论家,还是请十位普通食客?评论家再专业,也有自己的口味偏好和判断失误的那一天;而十位食客虽然每个人单独看都算不上完美,但只要大家的喜好不是同一个模子刻出来的,“少数服从多数”的结论往往出奇地稳。集成学习就是这个思路:与其赌一个模型,不如养一群“半吊子”模型,让它们各自表态,最后投票定案。Bagging 是其中最有代表性的一招,全称 Bootstrap Aggregation——自助采样聚合。它的做法像一个自助餐机制:每次从原始数据中有放回地抓一把样本,喂给一个基学习器;重复 T 次,得到 T 个“各吃各的”模型;预测时让大家投票。你会发现,每个模型单独看准确率只有七八成,但合在一起能逼近 99%。“人多反而更准”的背后,是方差被平均掉的数学原理——也是本文要一层层拆开的故事。
掌握 Bagging 是学习随机森林、理解整套集成方法的基石。风控、推荐、信贷评分等工业级项目几乎都会用到 Bagging 家族,理解它能让你在模型泛化调优时直击要害,不再只做“调参侠”。
可视化演示
动态演示Bagging的核心机制,通过开始/执行/监控/完成四种模式展示关键概念与交互流程。
本节配有交互动效(进入视口后自动加载,约 3KB)。
Bagging:Bagg Bagging核心思想与集成学 Bootstrap采样原理与有 核心机制可视化 Bagging整体架构与关键组件
集成学习思想
一位食客再资深,也有口味偏爱和心情起伏。十位“普通”食客分桌而坐、独立打分,反而更接近餐厅的真实水平——因为每个人的偏好和误判会在汇总时相互抵消。这就是集成学习的直觉:不追求打造一个完美模型,而是训练多个“基学习器”(base learner,相当于普通食客),把它们的预测组合起来。每个基学习器只要比瞎猜强一点——错误率低于 0.5——组合起来就可能比任何单一模型都好。
在机器学习里,这个思路叫“集成学习”(Ensemble Learning),Bagging 是其中最重要的成员。为什么“多票”能胜“独断”?做一个思想实验:假设每个基学习器独立判断,出错概率是 ε,只有当超过一半的学习器同时答错时,集成才会出错。用组合数可以算出,集成出错的概率随学习器数量 T 的增大而指数下降。这正是“三个臭皮匠,顶个诸葛亮”的数学版本。
1. 错误率:每个基学习器独立地犯错,错误概率记为 ε,并假设 ε < 0.5(比抛硬币略强)。
2. 失败条件:T 票中出错的学习器达到一半以上(k ≥ ⌈T/2⌉),多数投票才会失败。
3. 恰好 k 个出错:k 个错误且 T−k 个正确同时发生,组合方式有 C(T,k) 种。
4. 失败区间累加:把 k 从半数到 T 全部加起来,就是集成的出错概率。
就像 21 位食客投票,只要他们不是被同一份“美食攻略”洗脑(独立性),错误的口味很难形成多数。这也预告了 Bagging 的两大支柱:让每位“食客”口味有差异,再让投票定输赢。
Bootstrap采样
自助餐的取菜规则是:你端着盘子从几十道菜里挑,每挑一次,菜还在那里——同一道菜可以反复取。Bagging 的“自助”二字正来自这个动作:原始数据有 m 个样本,每次从中有放回地抽一个,抽 m 次,得到一份和原始数据一样大的新训练集。重复 T 次,就有了 T 份“菜盘”,喂给 T 个模型。
这个看似简单的抽样办法有一个绝妙结论:某个样本在 m 次抽取中一次都没有被抽中的概率,约等于 36.8%。也就是说,每份自助样本大约覆盖原始数据的 63.2%,其余位置是重复出现的样本。没被抽中的那 36.8%,被称为“袋外数据”(Out-of-Bag,简称 OOB)——它免费为模型提供了一份验证集。
1. 单次落选概率:在 m 个样本里抽一次,某个特定样本没被抽中的概率。
2. 连续 m 次落选:有放回地抽 m 次,每次都轮不上它。
3. 极限逼近:当 m 足够大,此式趋近自然常数 e 的倒数。
4. 反面即覆盖率:被抽中的概率约 63.2%,也就是自助样本的“新鲜样本覆盖率”。
食客没尝过的那 36.8% 的菜,并不是浪费——它正好用来检验这位食客的味觉是否可靠。这就是后面要讲的 OOB 验证:谁没吃过这道菜,谁就有资格给这道菜“挑刺”。
并行化训练
食客们要分桌而坐、互不通气:如果允许互相参考,先点的会带动后点的,十个人的评分就会高度雷同,投票就失去了意义。Bagging 在算法上做到了真正的“隔离”——T 份自助样本彼此独立,T 个模型各自训练、互不通信。因此它天然支持并行计算:把 T 个训练任务丢到多核 CPU 或多台机器上同时跑,训练总时长接近训练单个模型的时间。
这种并行背后有一组值得咀嚼的性质:每份训练集都是从同一个数据分布中抽样得到的,所以模型的“底子”相似(同分布);但抽到的样本又各不相同,所以模型“各有特色”(有差异)。这种“和而不同”正是平均化能够奏效的前提。假如 T 个模型完全独立、每个的预测方差都是 σ²,那么把它们取平均后,方差会缩小到原来的 1/T。
1. 单个模型方差:每个基学习器预测值围绕其期望的波动幅度记为 σ²。
2. 常数的平方:对平均操作求方差时,常数 1/T 提出后要平方。
3. 独立则相加:模型互不相关时协方差为 0,方差直接累加。
4. 代入得结论:平均之后方差变为原来的 1/T。
十个食客都生活在同一座城市(同分布),口味会有共性;但各自私藏的小馆子不同(样本差异),合起来反而比单打独斗稳定得多。并行训练则保证了这种“多样性”不被互相干扰。
多数投票
每位食客最后要表态:推荐,还是不推荐?一张票而已。更细心的评审团会让每人打 1~5 星,最后求平均分——分数比“是/否”保留了更多信息。Bagging 也是这样:分类问题用“多数投票”,数一数哪个类别得到的票最多;回归问题用“取平均”,把 T 个模型的数值预测加起来除以 T。
硬投票只管最终类别,软投票则更进一步:让每个模型先输出各类别的概率,再对所有模型的概率取平均。这样,那些“犹豫不决”的模型也能把不确定性表达出来,通常能带来微小但稳定的提升。实践中,Bagging 最常搭配决策树这种天然能输出概率或类别的模型。
1. 指示函数即一张票:第 t 个模型输出类别 y 时记 1,否则记 0。
2. 逐类计票:把 T 个模型的投票按类别累加,得到每个类别的总票数。
3. 取票数最多者:argmax 返回得票最多的类别作为最终输出。
就像大众点评上“推荐”与“不推荐”的百分比是硬投票,星级均分是软投票——后台其实都是这么聚合众人口味的。投票规则虽朴素,却是 Bagging 把“群意”变成“决断”的最后一公里。
偏差与方差
食客对同一道菜的评价为何不一致?一种原因是某位食客天生偏甜或偏咸,这是“偏差”(bias);另一种原因是今天饿与不饿造成的状态波动,这是“方差”(variance)。一个靠谱的评审团,既要压低系统性偏差,也要压住随机波动。机器学习中的偏差-方差分解把模型误差拆成三部分:不可消除的噪声、偏差的平方、方差。
偏差衡量模型对真实规律的系统性偏离——比如用直线去硬拟合一条曲线;方差衡量模型对不同训练集的敏感程度——比如一棵深度决策树,换一批数据决策边界就剧烈变化。Bagging 的奇妙之处在于:它不改变单个模型的偏差(平均的仍然是同一类模型),却能把方差压到原来的约 1/T。因此它对“低偏差、高方差”的模型(典型如深决策树)提升立竿见影,对“高偏差”模型(如欠拟合的线性模型)几乎帮不上忙。
1. 噪声项:数据生成过程中的固有随机波动,任何模型都无法消除。
2. 偏差平方:模型在众多训练集上的平均预测与真实规律的偏离程度。
3. 方差项:模型预测围绕其期望的波动幅度,正是 Bagging 着力压制的对象。
如果食客们全都“只会说好吃”(系统性偏差),投票再多也还是两个字;但如果只是“时好时坏”(方差),一桌人平均下来就是稳定发挥。偏差与方差的这场博弈,决定了 Bagging 什么时候是神药、什么时候是安慰剂。
Bagging对比Boosting
两种团建方式:一种是“自助评审团”——大家各吃各的,最后投票;另一种是“闯关训练营”——第二个人专挑第一个人评错的菜再评,后面的人依次踩在前人的肩膀上。前者是 Bagging,并行、等权、主降方差;后者是 Boosting,串行、加权、主降偏差。AdaBoost、GBDT、XGBoost 都属于 Boosting 家族。
从数学形式上看,两者都可以写成“基学习器加权求和后取符号”的加性模型。区别在于权重怎么来:Bagging 对每个模型一视同仁,权重恒为 1;Boosting 则给每个模型分配一个权重 α_t,准确率越高的模型权重越大,并且每次迭代都会加大对上一轮错分样本的关注。一个靠“自助”制造差异,一个靠“纠错”步步紧逼。
1. 统一视角:两者都是“基学习器加权求和后取符号”的加性模型。
2. Bagging 的等权:所有模型权重相同 w_t = 1,纯靠票数说话。
3. Boosting 的加权:权重 α_t 由该模型的加权错误率 ε_t 决定,错得越少权重越大。
4. 一句话差异:Bagging 求“稳”,Boosting 求“准”——分别对应方差与偏差。
想要多家医院独立会诊得结论,选 Bagging;想让徒弟快速出师、专攻师父的错题,选 Boosting。两者没有绝对的优劣,只有是否匹配你的误差来源。
随机森林扩展
食客团有个隐患:如果大家私下都刷了同一份美食排行榜,口味会严重“撞车”——投票就退化成一个人投了十票。怎么办?没收攻略,每人只发菜单的一页:有人只看前菜,有人只看主菜,有人只看甜点。随机森林正是这个思路的系统化:在 Bagging 基础上加入“特征随机选择”。
随机森林(Random Forest)= Bagging + CART 决策树 + 特征随机选择。每棵树在分裂时,不是从所有 d 个特征里挑最优,而是先从特征全集里随机抽 k 个(常用 k = log₂(d) 或 √d),再在这 k 个里选最优。这强制让不同树的“关注点”错开,树与树之间的相关性大幅降低,方差压缩效果比朴素 Bagging 更好。它还附带两个赠品:OOB 误差免费做验证,以及基于 Gini 不纯度下降量计算的特征重要性。
1. 类别占比:数据集 D 中第 k 类样本所占比例记为 p_k。
2. 占比平方和:平方和越大,说明样本越集中在少数类别,节点越“纯”。
3. 补成不纯度:1 减去平方和得到 Gini 不纯度,值越小越好;CART 分裂时选择使 Gini 下降最多的特征。
“没收美食榜、随机发菜单”,让每位食客的偏见不再同步,投票质量反而更高。随机森林也因此被许多人视为 Bagging 家族最成熟、最实用的成员。
流程与实战
把整套食客评审写成标准手册:筹备组(确定模型数量 T)→ 发菜单(自助采样)→ 隔离试吃(并行训练)→ 收评分(汇总预测)→ 复盘(OOB 检验)。Bagging 的算法流程同样清晰:对 t = 1 到 T,先从原始数据有放回地抽 m 次得到自助训练集,再在每份训练集上独立训练一个基学习器;预测时,分类用多数投票、回归用平均。
实战中最重要的参数是 T(基学习器数量)和基学习器的容量。T 越大结果越稳,但边际收益递减,一般 100~500 足够;基学习器建议选“高方差”模型(如不剪枝的深决策树),否则 Bagging 收益有限。另一个高频技巧是用 OOB 误差代替交叉验证——它几乎零成本,却与测试误差高度相关。
1. 袋外成员集合:对样本 i,收集所有未把它纳入训练集的基学习器,记为集合 T(i)。
2. 袋外投票:只用这些“没见过 i”的学习器对 i 做多数投票,得到 OOB 预测。
3. 平均错误率:对所有样本的错误指示取平均,得到泛化误差的估计值。
手册写完了,餐厅也要开业了。Bagging 就是那种“平凡但可靠”的招数:没有花哨的聪明,却能在风控、推荐、医疗等场景里稳稳坐镇 C 位。
AI 应用场景
信贷风控中的反欺诈识别
阶段:模型训练与评估
解决的问题:交易数据维度高、噪声大、正负样本极不平衡,单棵决策树对个别异常商户过拟合,线上 AUC 波动明显。Bagging 通过自助采样 + 多树投票显著压低方差,让欺诈识别更稳定。
具体案例:某支付平台对 24 小时内的交易做实时风控,用 500 棵树的随机森林为每笔交易输出“欺诈概率”,并借助 OOB 误差免去额外切分验证集。模型上线后,误报率下降了约 18%,深夜大额交易识别召回率提升 12%。
电商销量预测与库存备货
阶段:预测建模与上线监控
解决的问题:销量序列受促销、天气、节假日多重因素干扰,单模型预测方差大,常导致缺货或积压。Bagging 回归把“一锤子买卖”变成“全体表决”,预测曲线大幅平滑。
具体案例:某零售企业用 Bagging 回归(基学习器为深回归树)预测 SKU 日销量,相比单棵 CART,RMSE 下降 12%;且训练过程天然并行,全量 2000 万条数据仅需 40 分钟即可完成重训。
医疗辅助诊断的特征重要性排序
阶段:特征工程与可解释性分析
解决的问题:医生需要知道哪些指标(年龄、血压、某项化验值)对诊断最关键,传统逻辑回归系数不稳定且难以解释。随机森林基于 Gini 下降量输出特征重要性排序,成为沟通医生与算法的“翻译官”。
具体案例:某医疗 AI 团队用随机森林从 80 项体检指标中筛出与糖尿病强相关的 12 项,生成重要性条形图辅助医生解读,并作为后续深度模型的特征白名单,模型可解释性与性能同时提升。
Python 演示
"""从零实现 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)
idx = np.random.choice(n, n, replace=True)核心的“有放回抽样”,产出与原始数据等大的自助样本,正是自助餐式取菜weak.fit(X[idx], y[idx])每个弱学习器只在各自的自助样本上训练,互不通信,对应“分桌试吃”self.models.append(weak)T 个模型各练各的,最后统一汇总,体现并行化的思想votes[np.arange(len(X)), m.predict(X)] += 1对每个测试样本按模型预测的类别累加票数,实现多数投票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 中,每个基学习器的训练数据是如何得到的?
- A.直接使用全量原始数据
- B.有放回的自助采样← 正确答案
- C.无放回的均匀抽样
- D.按特征重要性加权抽样
答案:B。Bagging 对原始 m 条样本做“有放回地抽 m 次”,得到与原始数据同大小、约含 63.2% 不同样本的训练集。A 是普通训练,没有多样性;C 是无放回抽样(对应 pasting);D 是特征层面的操作。就像食客从菜单上有放回地取菜。
Q2. Bootstrap 采样中,某个样本在一次抽样中从未被抽中的概率约为多少?
- 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 个基学习器互不相关、方差均为 σ²,则取平均后的方差约为多少?
- A.σ²
- B.σ²/T← 正确答案
- C.Tσ²
- D.σ/T
答案:B。Var((1/T)Σh_t) = (1/T²)·Tσ² = σ²/T,这是“平均化降低方差”的数学依据。注意现实中模型间有正相关,实际收益小于该理想值;Tσ² 是错误地把方差相加当结论。
Q4. Bagging 主要能降低机器学习误差中的哪一项?
- A.噪声
- B.偏差
- C.方差← 正确答案
- D.数据缺失
答案:C。Bagging 通过重采样与组合,把多个模型的预测平均化,核心作用是压缩方差项;它不改变单个模型的系统性偏差,对噪声也基本无能为力。这正是它与 Boosting(主降偏差)的本质分工。
Q5. 下列哪种基学习器最适合发挥 Bagging 的优势?
- A.线性回归
- B.深决策树← 正确答案
- C.逻辑回归
- D.朴素贝叶斯
答案:B。深决策树是典型“低偏差、高方差”模型——换一批数据决策边界就剧烈变化,Bagging 恰好吃这一口,把抖动边界平均得平滑稳定。线性模型和逻辑回归偏差主导,集成收益有限。
Q6. 关于随机森林,下列说法正确的有哪些?
- A.是 Bagging 加决策树的组合← 正确答案
- B.同时随机选择特征子集← 正确答案
- C.只能用于回归问题
- D.可以用 OOB 误差做验证← 正确答案
答案:ABD。随机森林 = Bagging + CART 决策树 + 特征随机选择(A、B 正确),并天然提供 OOB 验证(D)。C 错误:随机森林分类、回归都支持。特征随机化的目的是降低树间相关性,防止投票变成“重复表态”。
Q7. 随机森林中“特征随机选择”最主要的目的在于?
- A.加快模型收敛的速度
- B.降低树与树的相关性← 正确答案
- C.减少参与训练的特征数
- D.提升单棵树的预测精度
答案:B。如果所有树都优先用最强的那个特征分裂,树之间会高度相似,投票等于一个人投了十票。随机选特征子集强制每棵树“各有侧重”,压低相关系数,让 Bagging 的方差压缩更有效。C 是伴随现象而不是目的;D 反而可能因特征受限而下降。
Q8. 关于 Bagging 的预测输出方式,下列说法正确的有哪些?
- A.分类任务用多数投票← 正确答案
- B.回归任务取模型平均← 正确答案
- C.分类任务一定用平均
- D.回归任务一定用中位数
答案:AB。分类用“少数服从多数”(众数),回归用“取平均”,这是 Bagging 的标准输出。C 和 D 张冠李戴;此外还有软投票——先平均概率再取类别,往往略优于硬投票。
Q9. 与 Boosting 相比,Bagging 的特点包括哪些?
- A.各基学习器可并行训练← 正确答案
- B.主要降低偏差而非方差
- C.各模型以等权方式组合← 正确答案
- D.对高方差模型更友好← 正确答案
答案:ACD。Bagging 各样本集独立、可并行(A),模型等权投票(C),主打降方差、对高方差模型友好(D)。B 说反了——“主要降低偏差”是 Boosting 的特征:串行训练、聚焦上一轮错分样本、按准确率加权。
Q10. sklearn 中用于直接构建 Bagging 分类器的类是哪个?
- A.AdaBoostClassifier
- B.BaggingClassifier← 正确答案
- C.GradientBoostingRegressor
- D.LogisticRegression
答案:B。BaggingClassifier 是通用 Bagging 封装,可指定基学习器(如决策树)。A 和 C 属于 Boosting 家族;D 是单模型。工程上也可直接用 RandomForestClassifier,它等价于“Bagging + 决策树 + 特征随机选择”。