资讯详情

集成学习精讲:从Bagging到Boosting,再到Stacking模型融合实战

📅 2026/10/16 3:54:18 | 华诺云谱 👁 阅读
集成学习精讲:从Bagging到Boosting,再到Stacking模型融合实战
最近在整理机器学习入门资料时翻到一位长期在企业级软件圈子做技术分享的作者写的新书里面专门有一章讲集成学习。说实话这类内容很多教材都写过但能把为什么要用集成、三种主流路线分别解决什么问题、实战时怎么选讲得这么顺的并不多。集成学习这名字听起来像某种高深算法拆开其实就是一句话把好几个表现普通的模型凑到一起让它们相互补位最后做出比任何一个单打独斗都更稳的预测。这篇文章算是一份笔记式精讲面向零基础到初级水平的读者帮大家把Bagging、Boosting、Stacking这三条技术路线彻底搞清楚读完再回去看各种机器学习的文档和源码会有种通了电的感觉。1. 为什么三个臭皮匠能打过诸葛亮集成学习的出发点1.1 一个投票实验带来的直觉我先讲一个自己做过的小实验。拿一份二分类数据集单独训练一棵决策树准确率大概在0.72左右。然后随机生成30棵结构上不太一样的决策树让它们对每个样本投票用少数服从多数的方式决定最终类别准确率直接跳到0.83。注意这30棵树里没有任何一棵使用了新数据、新特征或者更聪明的算法大家用的还是同一种决策树只是把群体投票这个朴素想法搬进来效果就完全不同了。这个结果其实挺反直觉的。很多人会默认模型越复杂越厉害但集成学习的起点恰恰是另一种思路单个模型的判断总有噪声和偏差但多个模型如果各自犯的错不完全一样综合判断就能把一部分错误互相抵消。就好比让一个专家闭卷猜一道难题的答案正确率有限但如果找来几十个水平一般的人让他们各自独立猜测再投票最终正确率往往会高于其中任何一个人。当然说三个臭皮匠顶个诸葛亮是有前提的后面会反复强调这个前提大家必须各自独立犯错。如果所有模型都在同一个地方犯错投票也改变不了结果。1.2 从偏差和方差理解集成为什么会有效机器学习里衡量模型误差通常拆成三部分不可消除的噪声、偏差Bias、方差Variance。偏差描述的是模型本身的平均错误水平比如用直线去拟合二次曲线的关系不管怎么训练都拟合不好这是高偏差。方差描述的是模型对训练数据变动的敏感程度训练集稍微换一批模型结果就剧烈抖动这是高方差。大多数单模型只会在这两者之间做取舍决策树、K近邻这类模型结构灵活、能拟合非常复杂的关系但对数据波动非常敏感属于典型的高方差模型线性回归、朴素贝叶斯这类模型结构简单、稳定但碰上复杂关系时能力有限属于典型的高偏差模型。集成学习的价值恰恰在于它可以通过组合的方式同时改善这两个问题。两条主流的改进路线出发点完全不同Bagging同时训练多个独立的高方差模型让它们互相平均或投票在不明显增加偏差的前提下把方差大幅压下去。Boosting按顺序训练一组高偏差的弱模型让后一个模型专门去补前一个模型的漏洞在不明显增加方差的前提下把偏差一点一点降下来。理解了这两条路线后面所有的细节都串起来了。很多人学集成学习只记住随机森林是Bagging、XGBoost是Boosting却不知道为什么要这样设计结果换个场景就不知道怎么调参。我建议你把高方差和高偏差这两个词贴在显示器边上后面看任何集成算法的文档先问一句它到底在解决哪个问题。2. Bagging流派随机森林的两个随机性到底在防什么2.1 自助采样为什么必须有放回Bagging的全称叫Bootstrap Aggregating核心操作是并行训练多个模型每个模型使用一份从原始数据集中自助采样出来的子集。所谓自助采样就是有放回地抽样从原始数据集里随机抽一个样本记下来放回去再抽下一个。这样抽够N次得到一份同样大小的训练子集。有些样本会被重复抽到有些样本一次也不会被抽到。为什么必须有放回这是很多初学者第一个卡住的地方。如果不放回每份子集都是原始数据的均匀分割子集之间高度相似训练出来的模型也就高度相似——你训练了几十个近乎复制的模型投票结果和只用一个模型没本质区别。有了放回之后每一份子集都是原始数据集的一个带有随机扰动的版本模型之间才可能出现各自的偏见。大约63.2%的样本会出现在某一特定子集中剩下的约36.8%不会出现这些袋外样本在验证时还有大用处下一节再说。你可以把自助采样理解成给数据加噪声。每棵树的训练数据不完全相同这就保证了树和树之间有一定的独立性。大家虽然在同一个真实世界分布下但各自看到的风景略有不同于是各自学到的规律也略有不同投票时才能取长补短。2.2 随机选特征不止为了快随机森林在Bagging基础上又加了一层随机化每次在决策树节点上做分裂时不是从全部特征里挑最优而是先从全部特征里随机抽出一个特征子集然后只在这个子集里找最优切分点。这个操作看起来只是提高计算效率实际上它的核心作用更微妙。如果只用自助采样树与树之间虽然训练数据不同但每次分裂时都去看同样的几个最强特征结果就是所有的树在顶层分裂时都选了同一个主导特征整个森林实际上是围绕同一个特征逻辑建立的。一旦这个主导特征在测试环境里表现不稳定或者带有噪声整个森林会同步受影响独立性被破坏降方差的初衷就打了折扣。随机抽特征等于强行打断了这种所有人的思路都往一处靠的倾向。即使某个特征平时很强势某些树在某个节点上根本没机会选它而会在其他特征里寻找替代分裂方式。这个设计的直接效果是树的多样性大幅提升森林整体的方差进一步下降。实际操作中这个参数通常用每次考虑的特征数量来控制分类问题常见取值为特征总数的平方根回归问题常见取值为特征总数的三分之一具体多少最好还是用交叉验证去试。2.3 OOB袋外分数不花钱的验证集自我采样可以顺便生成验证集。每一棵树都有一部分样本从未进入它的训练子集这些样本对这棵树来说就是天然的新数据。训练完这棵树之后把袋外样本喂给它做预测统计预测误差这个过程完全不需要额外划分验证集也不需要重新训练模型。最终把所有树的袋外误差综合起来就得到了随机森林的袋外评分Out-of-Bag Score。我最早接触OOB的时候觉得它只是个花哨的统计量后来才发现它在实操中很值钱。假设你手上只有500条样本又要做特征选择又要调参训练集、验证集、测试集划分起来非常紧张。这时候OOB能让你在不牺牲太多训练数据的前提下得到接近交叉验证结果的误差估计。经验上OOB分数与K折交叉验证的结果相差不大但计算成本低很多非常适合在特征工程阶段快速试错。需要注意OOB的使用有一个前提你用的确实是自助采样生成的Bagging模型而不是那些没有自助采样过程的集成算法。像极端随机树这种虽然也属于随机森林家族但它的OOB估计方式需要阅读工具文档确认不要想当然。3. Boosting流派AdaBoost和GBDT是如何把弱模型练强的3.1 AdaBoost给错题加权的智慧Boosting的核心思想和Bagging截然相反模型不是同时训练、互相投票而是按顺序一个接一个训练后一个模型专门关注前一个模型犯过的错。1995年提出的AdaBoost是这一流派里最有教学意义的算法。AdaBoost的训练过程可以这样理解一开始给每个样本分配相等的权重训练一棵很浅的决策树通常是深度为1的决策树桩用它预测全部样本把预测错误的样本权重调高、把预测正确的样本权重调低。下一轮训练时算法会刻意照顾权重高的样本——因为损失函数里它们的占比更大。如此循环每一棵新树都在处理让之前所有树都头疼的疑难样本。最终做预测时每一棵树按它的加权准确率贡献投票准确率高的树话语权更大。这里有一个值得停下来想想的点为什么给错题加权就能凑效因为每棵树都很弱只能用一两个特征做判断它们各自的视野很窄。把树串起来、对不同样本施以不同关注度之后整体模型等于按难度把样本空间分成了好几层每一层都有合适的树来处理。这就是把弱学习器逼成强学习器的本质。3.2 GBDT用梯度下降的思路做加法AdaBoost解决了关注错题的问题但它调整权重的过程依赖于具体损失函数的形式推广起来比较麻烦。2001年左右提出的GBDTGradient Boosting Decision Tree换了一个更优雅的视角把Boosting看成在函数空间里做梯度下降。传统梯度下降是在参数空间里沿着负梯度方向更新参数GBDT的每一次迭代则是往损失函数的负梯度方向加一棵回归树。对于平方损失函数这个负梯度恰好等于残差真实值减当前预测值所以很多通俗教程会告诉你GBDT就是不断拟合残差。这个说法在平方损失下是对的但你要知道这只是梯度下降视角的一个特例。换成绝对值损失、对数损失负梯度就不再是简单的残差而算法框架依然可以正常工作。用一个生活化的类比你把集成模型看成一个团队在估一个数字第一个人说80实际答案是100差20第二个人的任务不是重新估而是直接估还差多少他说12那现在总和是92还差8第三个人专门估这8。每一轮都在当前结果上打补丁补丁方向就是让误差减小的最快方向。GBDT的每一棵树都不是在预测原始目标而是在预测沿着哪个方向修补、修补多少最合理。3.3 为什么Boosting的默认参数往往要调小Boosting模型最容易犯的毛病是过拟合核心原因和它的串行机制有关后一棵树总是在拟合前面所有树留下的缺口如果迭代轮数足够多它最终会把训练集上的误差拟合到非常逼近0。这并不是好事因为那些缺口里既有真实的信号也有数据噪声。模型会连噪声的规律都背下来测试集上反而表现更差。这就是为什么实际使用GBDT家族包括XGBoost、LightGBM、CatBoost时几乎所有人都会强调两件事学习率learning rate要调小树的复杂度max_depth等要限制。这里的学习率相当于给每一轮补丁乘上的缩放系数取0.1、0.05甚至更低时每一步的修正都更保守模型需要更多树才能收敛但每一步都更不容易被个别噪声带偏。我自己习惯的做法是先把学习率定在0.05或0.1用早停机制确定合适的树数量再逐步微调树的深度和最小叶子样本数。如果你一上来就保持默认学习率0.3再加上几百棵树十有八九会在训练集上拿到漂亮分数然后被验证集无情打脸。4. Bagging与Boosting的正面交锋从高方差高偏差看选型4.1 数据量少、特征噪音多Bagging更稳在实际项目中怎么选这两大流派我的经验是先看两个问题你的模型目前的错误主要来自方差还是偏差你的数据是宽还是厚如果样本量不大几千条级别特征里面还有一堆噪声特征这时候随机森林通常比Boosting稳得多。原因有两层。第一Bagging的每棵树都是在一个随机子集上独立训练的即使某些特征纯粹是噪声它们只会在部分树的某些分裂点上瞎捣乱投票时影响被稀释而Boosting是串行迭代某一轮被噪声特征误导后后续所有轮次都会围绕这个错误打补丁错误会被放大而不是被平均掉。第二样本量小意味着噪声更容易被记忆Boosting的高拟合能力在这里容易演变成过拟合。另外随机森林对特征尺度不敏感几乎不需要做特征缩放分类特征也能直接用多数实现处理。如果你的项目时间紧、只想快速出一个靠谱的基线模型随机森林是首选。4.2 要冲精度、特征含义明确Boosting更强反过来如果你的数据量比较大几万条以上特征经过了清洗和编码业务上大致知道哪些特征有意义追求的是尽可能高的预测精度那Boosting家族特别是XGBoost、LightGBM这些工程优化过的版本往往表现更好。原因也很直接Boosting允许模型不断利用特征之间微妙的相互作用一棵浅树只能考虑一两个特征但几十棵浅树串起来等于逐步构建了对整个特征交互结构的复杂逼近。数据量足够大时模型能区分哪些是真实规律、哪些是偶然噪声拟合能力带来的收益大于过拟合风险。此外Boosting对缺失值和异常值也更友好具体取决于实现版本而且很多现代实现都带有正则化项。我经常遇到项目初始阶段先跑随机森林做特征筛选筛掉无关特征之后再切换到梯度提升模型冲精度这个流程在结构化和表格数据比赛里非常常见。4.3 一张参数速查表为了帮助零基础读者快速上手我整理了一张常用参数参考表。注意这些数值只是起点不是标准答案具体项目必须用验证集重新调。模型关键参数常见起点值作用随机森林n_estimators100-300树的数量越多越稳定但消耗内存随机森林max_depthNone或10-30限制单棵树复杂度防止单棵树过拟合随机森林max_featuressqrt(n)或n/3每次分裂考虑的特征数影响树间多样性GBDT/XGBoostlearning_rate0.05-0.1每轮补丁的缩放系数越小越稳GBDT/XGBoostn_estimators100-1000与学习率联动最好配合早停GBDT/XGBoostmax_depth3-6控制单棵树的深度太深容易过拟合GBDT/XGBoostsubsample0.8-1.0每轮训练使用的样本比例降低方差LightGBMnum_leaves31左右与max_depth类似控制树的复杂度有一点要特别提醒调参顺序比调参本身更重要。我的顺序是先定学习率然后用早停确定树数量再调整树的深度和样本采样比例最后才动正则化系数。反过来乱调经常会出现几个参数互相干扰、怎么调都调不动的挫败感。5. Stacking让模型们投票之后再开会5.1 元学习器到底在学什么Bagging和Boosting都是围绕同一种基模型做文章而Stacking的思路完全不同把几种异构模型比如逻辑回归、随机森林、XGBoost、神经网络的预测结果作为新特征再训练一个元学习器来融合它们的意见。为什么需要元学习器来做融合而不是直接取平均因为不同的模型擅长的样本区域不一样。举例来说逻辑回归可能对线性可分的样本判断比较准却对复杂非线性边界无能为力随机森林恰好相反能捕捉复杂边界但在线性区域容易过度抖动。用一个简单的平均去融合等于假设这些模型在任何样本上的权重都一样这很浪费。元学习器的作用就是根据具体情况学习什么时候该听谁的它对每个样本都动态决定不同模型的权重配比。5.2 K折交叉验证防止元特征过拟合Stacking有一个极其容易踩的坑生成元特征的方式不对。假设你拿训练集同时训练了底层模型和元学习器用同一个训练集的预测结果去训练元学习器那元学习器看到的特征就是模型们看过答案之后的答卷它对训练集拟合得再漂亮都毫无意义测试集上几乎必然崩盘。正确的做法是对训练集做K折交叉验证把训练集切成K份每次用其中K-1份训练底层模型对剩下的1份做预测循环K次后每个训练样本都有一个由没偷看过它的模型产出的预测值把这些值拼起来作为元特征。测试集上的预测则要对K个模型结果取平均保证测试和训练的用法一致。这个过程很消耗时间也有人为了提高效率只用两层交叉验证或者一层留出法但在样本量允许的情况下我强烈建议至少用5折。折数太少元特征会有偏差折数太多计算量成倍上涨收益却递减。5.3 新手最容易犯的致命错误Stacking的另一个高频错误是使用了目标泄漏。例如在分类任务中用全部数据做特征缩放或者缺失值填充之后再划分训练集底层模型在交叉验证时虽然只看到K-1份数据但那些数据已经接触过测试折的信息。这在比赛里会被直接判负在真实项目里则会造成验证分数虚高模型上线后性能缩水。还有一点Stacking的收益是有上限的。如果底层模型之间没有什么差异性融合结果基本等于取平均没必要额外训练一个元学习器。我见过不少人在没有做特征筛选的情况下堆四五个高度相关的梯度提升模型结果Stakcing之后分数没有任何提升。正确的姿势是先跑几个底层模型检查它们的预测相关性确保每个模型带来独特的信息再考虑融合。6. 一次真实可复现的集成学习对比实验6.1 实验设置一份公开数据集和三类基线理论说再多都不如亲手跑一次对比印象深。我用一份公开的二分类表格数据做了个小实验样本量大概5000条特征20个目标是预测某个业务事件是否发生。划分成70%训练、30%测试后我分别训练了四个模型单棵决策树、逻辑回归、随机森林、XGBoost另外再加一个简单的Stacking融合。所有模型都用网格搜索做了基础调参评估指标用准确率和F1分数。选择这四个模型的原因很明确单棵决策树和逻辑回归代表单模型基线随机森林代表BaggingXGBoost代表Boosting最后的Stacking则验证异构融合是否还能再上一层楼。6.2 结果对比谁赢在哪里跑出来的结果其实非常有教育意义。单棵决策树的准确率约0.75F1约0.68波动很大换一次随机种子结果就有明显变化。逻辑回归准确率约0.79F1约0.71稳定但上限低。随机森林准确率0.84F1约0.77进步非常明显而且换了随机种子之后结果几乎不变。XGBoost略胜一筹准确率0.86F1约0.79。最后把随机森林、XGBoost、逻辑回归的预测值拼在一起训练一个简单逻辑回归作为元学习器准确率0.87F1约0.80比最好的单模型也就高了零点几个百分点。这个结果恰恰印证了前面的理论单棵决策树是高方差典型所以随机森林的收益最大逻辑回归是高偏差典型Boosting的收益也明显但到Stacking这一步底层模型已经足够强再融合带来的边际收益就非常有限了。6.3 实操中的三个心得每次跑这类实验我都会有一点新的体会这次尤其想提三点。第一随机森林和XGBoost在表格数据上的表现确实稳压单个模型但别指望Stacking能给你带来惊喜式的飞跃。如果底层模型之间太相似融合增益很小投入产出比不划算。第二OOB分数和验证集分数的一致性在这次实验里表现很好。随机森林的OOB分数0.83和验证准确率0.84非常接近。以后做特征筛选、快速评估时可以放心用OOB来兜底。第三Boosting类模型对特征工程的依赖相对较小但随机森林对个别噪声特征的鲁棒性更好。如果你的特征质量参差不齐建议先跑一轮随机森林看特征重要性再用筛选后的特征去训练梯度提升模型往往比直接扔进去效果更好。集成学习的内容范围很大这一讲先从思路和三大流派切入。我自己在实际项目中最大的体会是别把这三种方法当成孤立工具它们的本质都是在回答怎样综合利用多个模型的判断这个问题。遇到新数据集先别急着上重模型花十分钟想想你的错误是高方差还是高偏差再决定走哪条路线效果往往会好很多调参也不会那么痛苦。下一讲我打算把XGBoost和LightGBM的计算细节、缺省值处理逻辑拆开讲讲那部分才是真正拉开工程水平的地方。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑