翻到Week 7的笔记这大概是整门《机器学习技法》公开课里最让人耳目一新的一章。前面六周我们一直在跟“单一模型”较劲线性模型、支持向量机、核方法、决策树每一个都研究得很深但谁都避免不了一个尴尬——换个数据分布模型表现就可能波动很大。Week 7的“Blending and Bagging”直接换了一个思路不再纠结于选哪个模型而是把多个模型组合起来让群体的判断代替单个模型的判断。这篇笔记会把这周的核心概念、课程里最关键的数学推导、以及我在课下做的验证实验完整记录下来适合正学到这一周的同学也适合想系统理解集成学习入门逻辑的读者。1. 从单一模型走向群体决策课程为什么在这个节点讲聚合1.1 前半程课程留下的“稳定性”难题课堂进入第七周之前我们已经看了很多威力强大的算法SVM可以把非线性边界分离得干干净净决策树能通过不断分裂拟合复杂模式。但这些模型的“强”往往是建立在特定参数设置和特定训练样本之上。换一组样本决策边界就可能抖动得厉害参数差一点模型的泛化误差可能大幅上升。这是单一模型在有限数据下很难绕开的“方差困境”。课程正是从这里切入如果我们手里不只有一个候选模型而是有一组模型能不能用某种方式把它们的判断整合起来得到一个比其中任何一个都更稳健的最终模型我的理解是这周的定位非常巧妙。前面几周教的是“单点突破”把线性模型、SVM、决策树每个都打磨到足够强这周开始教“协同作战”不再假设一个模型能搞定所有问题而是假设很多普通模型凑在一起能够互相纠正彼此的偏差。这种思路上的转折正是“技法”两个字想表达的深层含义。1.2 聚合的两个关键问题多样性与组合规则把多个模型组合起来听起来简单实际上要回答两个问题。第一怎么得到一组有差异的模型如果训练了十个完全一样的模型再怎么组合也还是同一个模型。第二组合规则怎么定是简单投票还是学习一个权重Week 7的核心就是把这两个问题拆开讲Blending系列方法解决“组合规则”的问题Bagging解决“制造多样性”的问题。课程里强调聚合要想超过单一模型需要同时满足“多样性”和“准确性”。一堆胡言乱语的模型投票不会得到正确结论只有每个模型都有一定正确率、同时彼此犯错模式还不一样群体决策才可能变强。这就像开会讨论。如果所有人都是同一个思路多开几场会也讨论不出新东西如果大家角度各异但都基于事实讨论结果往往比一个人拍脑袋可靠。但在实际训练中“角度各异”不是天然存在的需要专门设计数据采样或模型扰动来制造。课程后面所有集成方法本质上都在做这两件事制造差异、聚合判断。1.3 多数表决的思想实验弱而不同的模型才有价值我自己觉得这周最精彩的地方是一个概率思想实验假设我们有若干正确率略高于随机猜测的小模型每个模型的正确率是 (p0.6)错误率是 (0.4)如果只用其中一个模型正确率就是0.6。但如果用11个这样的模型做多数表决并且假设它们犯错彼此独立表决正确的概率会变成[ \sum_{k6}^{11} \binom{11}{k} (0.6)^k (0.4)^{11-k} ]算下来大约是0.75比单个模型的0.6高出一截。如果把模型数量增加到21个这个概率还会继续上升。这个思想实验直观地说明模型可以弱但只要不是瞎猜并且彼此独立地犯错多数表决就能把正确率“拔”上去。反过来如果这11个模型完全一样或者它们总是在同样的样本上犯错那表决结果不会有任何改善。这正是课程反复强调的“弱但不同”的模型组合才有价值。理解这一点后面看Bagging的设计思路就会很顺畅——Bagging的核心目标不是把模型变得更准而是让一组模型变得更不同。2. 三种Blending方式由浅入深的“组合模型”操作路径2.1 Uniform Blending投票、平均和那个平方误差不等式最简单的一种组合方式就是给每个 (g_t) 相同的地位。分类问题中做多数表决回归问题中做算术平均。课程给出了一个很有用的推导对于回归如果用平方误差来衡量令 (G(x)) 为一组 (g_t(x)) 的平均值那么对任意一个样本 (x)有[ (G(x) - y)^2 \leq \frac{1}{T} \sum_{t1}^{T} (g_t(x) - y)^2 ]也就是说平均模型在每个点的误差不会比所有基模型在该点误差的平均值更大。这个结论可以从代数上直接写出来。看下面的展开式e_t (g_t - y)^2 (g_t - G G - y)^2 (g_t - G)^2 (G - y)^2 2(g_t - G)(G - y)对所有 (t) 取平均第三项的求和部分是 (2(G - y) \cdot \frac{1}{T}\sum_t (g_t - G))。因为 (G) 本身就是 (g_t) 的平均值所以 (\sum_t(g_t - G)0)这一整项就消失了。剩下来的两项中((g_t - G)^2 \ge 0)于是自然得到上面的不等式。理解这个不等式的含义很重要Uniform Blending并不保证新模型一定好于“最好的那个基模型”它保证的是新模型不会比所有基模型“平均水平”更差。换句话说如果你手里有几个说得过去的模型把它们平均一下至少不会吃大亏。这是一种非常稳健的兜底策略。2.2 Linear Blending让数据帮我们决定权重均匀投票虽然稳但把“老专家”和“新手”平等对待显然不太合理。Linear Blending的做法是把每个模型 (g_t) 的输出当作新的特征然后在验证集上学习一组权重 (\alpha_t)使得组合后的打分 (\sum_t \alpha_t g_t(x)) 在验证集上误差最小。课程特别提醒学习权重时用的是验证集而不是训练集。这个细节非常关键基模型本来就在训练集上表现好再基于训练集学权重会放大过拟合模型的贡献。只有在验证集上才能公平地看到每个模型对新数据的预测能力权重才可信。这一层可以类比成“评委打分”每个基模型是选手线性权重是评委对选手的信任度。如果评委只看选手训练时的成绩很容易被“刷题家”骗了只有看新题成绩才能选出真正靠谱的选手。Linear Blending还把负权重也纳入考虑范围这相当于允许评委说“这个选手的答案有系统偏差要从总分里扣掉一部分”是一种比硬投票灵活得多的机制。2.3 Stacking把组合层变成可学习的模型如果把Linear Blending中的线性回归换成更复杂的模型就得到Stacking。课程中把这种结构描述为“将基模型的输出作为新的特征再用一个学习算法来融合它们”。从操作上看它是在验证集上构造一个新数据集新数据集的每一列来自一个基模型的预测值然后在这个数据集上训练一个上层模型。Stacking的好处是融合层可以捕捉到基模型输出之间的非线性关系。比如基模型A在样本A类区域更准基模型B在样本B类区域更准上层模型可以学到“在不同区域分别信任不同模型”的复杂规则而不只是给它们一个固定权重。坏处也明显融合层的自由度变大更容易过拟合。业界在竞赛里经常用两层结构但实际工程里要格外小心。所有基模型必须在训练集和验证集上分别产出输出融合层只在验证集的输出上训练最后再用完整训练数据重新训练基模型或者直接使用交叉验证来稳定融合结果。课程虽然点到为止但这个思想几乎贯穿后续所有集成学习实践。3. Bagging用数据的“重复采样”制造差异性3.1 为什么必须用有放回抽样Blending假设我们已经有一组训练好的模型但现实中我们往往只有一个数据集。怎么造出一组足够不同的模型这周的Bagging给了一个经典思路对原始数据集做有放回抽样得到T份大小相同但内容略有差异的新数据集再分别训练T个模型。之所以必须“有放回”是为了让每次抽样都更像一次独立的“重新采样”。如果无放回地把样本分成T份每份样本量只有原来的1/T且样本之间不重叠模型的数据基础会弱很多而有放回抽样允许同一批样本重复出现每次产生的数据集都带着近似原始分布但又有细微变化的信息。这相当于模拟了“从真实分布里重新采一份新数据”的过程。我们虽然没有能力真的拿到多份独立样本但通过有放回抽样可以在原始数据范围内制造出很多份“看起来像是重新采样”的数据集。每份数据集训练出的模型就会在决策边界上产生差异。差异正是Bagging的燃料。3.2 Bagging的完整流程与袋外样本Bagging的算法流程可以写成下面这样的伪代码输入训练集 D基学习算法 A模型数量 T for t 1 to T: 从 D 中有放回地抽取 n 个样本得到 D_t 用算法 A 在 D_t 上训练得到模型 g_t 输出G(x) 多数表决分类或算术平均回归这里的核心参数是 (T)。课程没给一个“最优轮数”因为它取决于具体问题和基模型。通常几十轮到几百轮都能看到明显效果再增加轮数收益会逐渐饱和。有一个小细节值得专门提一下在每一轮有放回抽样中一个样本在 (n) 次抽样里都没被抽到的概率约为 ((1 - 1/n)^n \approx e^{-1} \approx 0.368)。也就是说每次训练大约有36.8%的样本没有参与该轮训练这些样本被称为“袋外样本”。袋外样本是个免费的好东西。它们没有被某个基模型见过天然适合用来估计这个模型的泛化误差不需要额外划分验证集。课程没有展开细讲但这是我后来做实验时觉得特别实用的部分尤其在数据量不大时能省下很多样本。3.3 从方差角度看Bagging为什么有效假设T个 (g_t) 相互独立且每个 (g_t) 的方差都是 (\sigma^2)那么对 (G) 求平均后方差变成 (\sigma^2 / T)。模型数量的增加会让组合结果的波动迅速下降。当然实际训练出的 (g_t) 来自同一个原始数据集彼此之间高度相关方差削减效果没有这么理想但方向上确实把“单模型方差太大”的问题缓解了。这里要特别提一个课程里的重要结论Bagging适合搭配那些“对数据敏感、容易过拟合”的基模型比如决策树。如果基模型本身是线性回归这类低方差模型Bagging带来的收益很有限平均几个长得差不多的线性模型结果还是线性模型。这也是为什么后续课程讲随机森林时会在“决策树 Bagging”的基础上再加一个“特征随机选择”。特征随机选择的目的就是进一步增大树与树之间的差异性让树们不那么“相似”从而把相关性的影响压下去。理解了这一层再看随机森林的设计就不是记结构而是顺着需求推出来了。4. 与前后课程的知识衔接这周的真正位置4.1 从SVM到Bagging两条稳定的路线前几周的SVM通过间隔最大化来提升稳定性软间隔又允许少量误分点本质上是在“一个模型内部”加上正则约束。而Bagging走的是另一条路不修改基模型内部结构通过重复训练和组合来降低不确定性。两种思路并不冲突甚至经常会在同一个系统里同时出现。路线核心手段适用范围典型代表单模型 正则限制模型复杂度提高泛化性数据量适中、模型容易过拟合时软间隔SVM、带L2惩罚的逻辑回归多模型 组合制造差异降低预测方差基模型本身不稳定、数据扰动大时Bagging、随机森林这张对比表是我自己整理笔记时画的。考试和面试里经常会把这两种思路放在一起问本质上就是考察你是否理解“正则化是在模型内部做文章集成是在模型外部做文章”。4.2 Kernel Ridge Regression 与 Linear Blending 的共通思想课程早期讲Kernel Ridge Regression时我们已经知道“高维空间里的线性模型往往比原始空间里的线性模型强得多”。Linear Blending做的事情其实异曲同工把多个低维模型的输出映射成一个新的特征向量然后在这个新特征空间里做线性加权。区别在于Kernel方法是把原始特征映射到隐式高维空间Linear Blending则是把“模型预测结果”映射成度量特征。但二者都遵循同一个原则先变换再线性学习。这种相似性带来的好处是以前学的正则化、交叉验证经验可以直接迁移到集成模型上。组合层权重过大时可以加L2惩罚基模型数量太多时可以用交叉验证选择哪些模型最终参与组合。课程还提到在组合时加入常数项做截距等价于允许一个固定的偏置模型这在实践里有时会带来稳定提升。4.3 为什么下一周马上要讲AdaBoostBagging通过并行地重采样制造多样性但每个模型之间没有信息交流遇到特别难分的样本依然可能集体犯错。下一周引入的AdaBoost换了一种策略串行地调整样本权重让后一个模型更关注前一个模型犯错的样本。这样模型之间就有了明确的协作关系而不是单纯的并行。Week 7把blending和bagging讲透其实是为后面的“串行式”集成做一个脚手架。如果这周“权重学习”和“重采样制造多样性”两个概念没有吃透下周看AdaBoost会非常吃力。我自己在复习时会把这周当成一个分水岭前面全是“单模型时代”从这周开始进入“集成学习时代”。后面出现的随机森林、AdaBoost、Gradient Boosting全都是从这周的两个基本问题出发在“怎么制造差异”和“怎么组合模型”上做文章的变体。5. 一个可以马上上手的验证实验Bagging稳定性测试5.1 实验设置与基模型选择学完理论我忍不住做了个小实验。实验设定是两个类别的二维模拟数据样本量600个带0.35的高噪声保证单模型很容易过拟合。基模型选择不剪枝的决策树因为它方差大、对样本扰动敏感最适合展示Bagging的效果。实验中直接比较三种配置单棵决策树、Bagging 10棵树、Bagging 50棵树都用测试集错误率来评估。为了公平所有配置使用同一个随机种子划分训练集和测试集。5.2 核心代码实现实现本身不复杂用一个常见的机器学习库就够了。下面是参考代码import numpy as np from sklearn.tree import DecisionTreeClassifier from sklearn.ensemble import BaggingClassifier from sklearn.model_selection import train_test_split from sklearn.datasets import make_moons X, y make_moons(n_samples600, noise0.35, random_state7) X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.3, random_state42 ) base DecisionTreeClassifier(random_state0) base.fit(X_train, y_train) print(single tree error:, round(1 - base.score(X_test, y_test), 4)) for n in [10, 50]: bag BaggingClassifier( base_estimatorbase, n_estimatorsn, random_state0 ) bag.fit(X_train, y_train) error 1 - bag.score(X_test, y_test) print(fbagging ({n}) error:, round(error, 4))代码里最关键的一点是base_estimator传进去的是同一个决策树配置但BaggingClassifier会把它自动克隆成多份每份用不同的自助采样数据集去训练。默认情况下这就是有放回抽样。5.3 结果解读与扩展观察在我的模拟运行中单棵决策树错误率在0.25附近波动Bagging 10棵树降到0.20左右Bagging 50棵树进一步降到0.18附近。这个例子直观地展示了方差下降单棵决策树会因为某些噪声样本画出完全不同的边界而Bagging通过平均多个边界把边界“磨平”了。我也试过用线性模型作为基模型做同样的Bagging结果错误率几乎不变正好印证了课程里“低方差模型对Bagging不敏感”的结论。另外还有一个观察随着基模型数量增加Bagging的错误率会先快速下降然后进入平台期这时候再加更多树意义不大。实际工程里我会先用几十棵树看看趋势再决定要不要加到几百棵。这个实验还提醒了我一个细节基模型的多样性不只由抽样次数决定还受数据噪声水平和模型复杂度的共同影响。如果数据本身太干净、模型过于稳定重复抽样带来的多样性就很小Bagging的效果自然也有限。6. 学习时最容易踩的坑与几点答疑6.1 Blending和Bagging到底怎么区分这是Week 7最容易被问住的问题。简单记Blending关心“怎么组合已经训练好的模型”Bagging关心“怎么从一份数据中生成多个有差异的模型”。二者可以配合使用先用Bagging生成一组模型再用Blending比如Linear Blending决定它们的权重。把它们混为一谈后面看随机森林的源码就会觉得别扭。随机森林是Bagging的典型应用但它内部使用的组合规则通常是简单的投票或平均并没有单独的“融合层学习”。所以随机森林本质上是Bagging而不是Blending。6.2 均匀平均的误差不等式说明了什么很多人把那个平方误差不等式理解成“平均后一定比最好的模型好”这是不对的。不等式证明的只是“平均模型不比各基模型的平均差”。在具体数据集上最好的单一模型仍然可能赢过平均模型。这个细节在多个讨论里都是个坑。比如有人说“Bagging保证能提升模型”这句话就不够严谨。Bagging真正稳定改善的是稳定性是降低预测对训练样本波动的敏感度而不是保证每一次都超过最优单模型。课程后面用大量实验说明聚合的实际价值通常在小波动、多模型场景下最明显。6.3 负权重与组合层的正则化Linear Blending学出来的权重可能是负的。有些人觉得投票权重不该为负但线性组合里负权重是有意义的它相当于在组合中减去某个模型的“错误直觉”可以作为对其他模型偏差的修正。当然权重没有约束时也可能变得很大或很小。课程建议在组合层使用正则化比如对权重加L2惩罚这在样本量不足时尤其重要。否则组合层很容易为了在验证集上压误差而记住噪声。6.4 袋外样本的隐藏用途Bagging的“余数”其实很有用。一个样本在T轮训练中平均有约36.8%的轮次没有参与训练这些未使用的数据天然可以作为验证集来估计每个 (g_t) 的表现。工程上随机森林等算法甚至可以直接根据袋外误差调整参数省去单独划分验证集的麻烦。比如在调参时先看袋外错误率随树数量的变化曲线就能大致判断多少棵树足够。这是我后来做项目时最常用到的一个隐藏技巧。6.5 一点个人学习的体会如果时间有限优先把Week 7的两个核心图搞懂一个是“模型输出做特征”的流程图对应Blending一个是“有放回抽样训练多个模型”的示意图对应Bagging。我在学习时最大的体会是这周的内容少而精不需要背结论最好亲自跑一遍Bagging实验观察单模型稳定性和组合模型稳定性之间的差异。把实验做一遍以后再看后面的Boosting、随机森林、Stacking等扩展内容会轻松非常多。尤其是当我亲手看到一棵不剪枝决策树的边界在土里土气的数据上飘来飘去而50棵树的平均边界稳稳地把分界控制在合理位置时才真正理解“群体决策”这四个字的分量。