AI 工程地基 33|二十一个六十分,凑出一个八十二分
1785 年,法国数学家孔多塞琢磨过一个陪审团问题:如果每个法官只有六成把握判对,多拉几个法官投票,能不能把判对的概率抬上去?
这个能算。21 个互相独立的法官,每人判对概率 0.6,多数票判对的概率就是一个二项分布的求和,算出来约 82.6%。法官扩到 101 个,概率升到 97.9%。
这课教材上也印了这两个数,印的是 74% 和 84%。我拿二项分布重算了一遍:21 个六成,是 82.6%,不是 74%。101 个六成,是 97.9%,不是 84%。84% 倒是另一道题的答案——每人只有 55% 把握、101 个人,算出来正好 84.4%。书把两处的数都印小了,第二个像是把成员 55% 的情形错记成了 60%。
数字印小了,道理没坏:一群勉强及格的判断,只要错得互不相同,投票能投出一个优秀的结果。这一课讲的就是怎么造出这样一群判断,怎么组合它们,以及组合的代价在哪。
前提比你以为的硬
多数投票有效的关键是「错得互不相同」。书上提了一句:如果所有模型犯同样的错误,组合毫无帮助。这句话有多硬?拿实验说话。
造 21 个分类器,每个单独准确率 60%,但让它们的错误带一份共同因子——用参数 ρ 控制错误之间的相关程度。ρ=0 是完全各错各的,ρ=1 是所有模型错得一模一样。中间取几档:
ρ=0,多数投票 82.6%,比单模型高 22.5 个百分点。ρ=0.5,掉到 63.5%,增益只剩 3.5 个点。ρ=0.8,61%,只剩 1 个点。错误相关性从零爬到八成,集成的增益就从 22 个点缩水到 1 个点。
这就是为什么「多弄几个模型」说起来容易做起来难。模型如果读同一份数据、学同一套规律、犯同一批错,它们就还是同一个模型。集成方法费的所有力气,本质上都在制造「不一样的错误」:换样本(bagging)、换特征(随机森林)、让后面的模型盯前面的错题(boosting)、换模型家族(stacking)。
Bagging:换着样本训练,把抖动平均掉
Bagging 的做法最直白。从训练集里有放回地抽一份同样大小的新样本,抽 N 次,训练 N 个模型,预测取平均。有放回抽样有个数学性质:一份 bootstrap 样本大约覆盖原数据的 63.2%,剩下 36.8% 没被抽到。这些「袋外」样本白送一个验证集,不用额外留数据。
每个模型在自己的样本上过拟合,但过拟合的方向各不相同,平均一下就互相抵消了。所以 bagging 治的是方差——预测的抖动。
那到底能压掉多少?理论最好的情形,20 个完全独立的模型取平均,方差应该压到单模型的 1/20。我在课程的数据生成器上做了个实验:重复训练 40 次,每次一棵深度 5 的单树,外加一个 20 棵树的 bagging,比较它们预测的方差。结果单树方差 0.764,bagging 0.337,比值 0.44。
20 棵树只把方差砍掉一半多点,不是砍掉 95%。原因还是那个 ρ:bootstrap 样本之间共享大约六成的原始数据,树与树的错误相关,平均只能消掉互不相同的那部分。这是 bagging 的真实折扣,书上没写。
顺带一提,课程 demo 里有一行打印写着「Variance reduction: +0.113」,看着像方差的改进,其实印的是准确率差:单树 0.750,bagging 0.863,差 0.113。准确率的差不是方差,这是把两个量写串了。
AdaBoost:让下一个模型盯住错题
Bagging 是各自为战,boosting 是接力。AdaBoost 的流程是:先给每个样本同样的权重,训练一个弱模型(通常是一刀两断的决策桩);算它的加权错误率,错误率越低,这个模型在最终投票里的话语权(α)越大;然后把被它分错的样本权重调大,下一个模型自然会盯着这些错题使劲。如此循环几十轮,最后的预测是所有模型的加权和。
公式不长,权重更新的那行是 w 乘以 exp(-α·y·h(x)):分对的样本权重缩水,分错的膨胀。
AdaBoost 有个漂亮的数学保证:训练错误率有一个上界,随轮数指数下降。这个保证是真的,我在一份噪声水平 0.35 的数据上跑了 300 轮:训练准确率从 0.816 一路涨到 0.991,错误率上界收紧到 0.158,指数下降如实兑现。
测试集呢?最优成绩出现在第 14 轮,0.863;第 300 轮,0.850。从头到尾在 0.85 附近抖。
这就是那段数学的边界:定理管的是训练集。训练错误率降下去和测试成绩涨上去,是两件事。书上说过拟合那段话方向是对的——轮数太多,模型开始死磕那些分不对的样本,而其中一些本来就是噪声,怎么磕都磕不对。只是想亲眼看见这件事,你要盯的不是测试曲线(80 个测试样本,错一个就晃 1.25 个百分点,曲线天然是毛的),而是训练和测试之间越拉越开的剪刀差。
梯度提升:在残差上盖楼
梯度提升把 boosting 推广到任意损失。它的思路更直白:训练完当前模型,算出每个样本的残差(真实值减预测值),让下一棵树去拟合残差。每棵树都在前面所有树留下的错误上盖楼。平方损失下,损失函数的负梯度恰好就是残差,所以「拟合负梯度」在这里就是「拟合错误本身」。
课程的伪代码里有个步骤挺唬人:每轮要用线搜索找最优步长 γ。实现里直接跳过了这步。我替它补算了一下:平方损失下,γ 每轮算出来都是 1.0000000000,一步不多一步不少。带着 γ 跑 100 轮,测试误差 0.372;不带 γ 跑,0.373。跳过它是对的——这步是给别的损失函数准备的,在平方损失上是死代码。
学习率(收缩)控制每棵树贡献的力度。课程 demo 扫了一张表:学习率 0.5 配 20 棵树,误差 0.376;0.1 配 100 棵,0.307;0.05 配 200 棵,0.297;0.01 配 500 棵,0.465。表格下面印着一句总结:「更小的学习率需要更多树,但往往泛化更好。」
「往往」两个字撑不住自家这张表。表里最小的学习率恰好是最差的那行。细看还有个更简单的解释:前三行的学习率乘树数都等于 10,最后一行等于 5——最小的那行不是学得慢更稳,是总步数没给够,500 棵树还没爬完坡。学习率确实是个抗过拟合的手段,但调太小的代价是真金白银的树。
Stacking:让一个模型学会该信谁
Stacking 换了个思路:把几个基模型的预测当作新特征,喂给一个元学习器,让它学「什么输入该信哪个模型」。森林擅长这片、SVM 擅长那片,元学习器学会分工。
这里有个容易踩的坑,课程做对了:元特征必须用交叉验证生成。如果基模型在自己训练过的数据上出预测,再拿这些预测去训元学习器,等于让元学习器看了一份过于乐观的成绩单。课程的做法是把训练集切五折,每折的预测都来自没见过它的基模型。
但课程的 demo 在另一处滑了一下:图上画的三个基模型是随机森林、SVM、逻辑回归,练习里建议逻辑回归、决策树、k 近邻,实际代码里站的三个是——同一棵决策树,只是深度分别是 3、5、7。
深度不同,错误可未必不同。三个同家族的模型读同一份数据,犯的错高度重合,元学习器拿到三列差不多的特征,能学的空间很小。实测结果也配合这个判断:三个基模型最好的单跑 0.825,stacking 叠完 0.838,挤出 1.3 个百分点。多样性得来自错误的不同,不是深度的不同。
元学习器那几行代码还有个 bug。它用 tanh 做输出,求梯度时写的是「误差乘特征」——漏乘了 tanh 的导数,链式法则断了一环。在权重接近零的地方,tanh 的导数恰好是 1,两边的梯度一样,看不出来;离开原点,错梯度比真梯度大 5.6 倍。demo 没被打死,是因为这个玩具里模型多数时候待在线性区。你要是复用这段代码去拟合更强的非线性,它的步子会在该小的地方迈大。
拿到一张表前,先看看表说了什么
课程最后并排跑了四个模型:手写 AdaBoost 0.870,sklearn 的 AdaBoost 0.880,随机森林 0.890,梯度提升 0.910。手写版离生产实现差 1 个点,这个距离是合理的。
但另一张对比表值得一说。单树 0.870,bagging 0.880,AdaBoost 0.870。AdaBoost 和单树打了个平手。表下面照样印着总结:「bagging 降方差,boosting 降偏差。」前半句有 1 个点的支撑,后半句在这张表上是零—— boosting 在这份演示里一个点的偏差都没降。结论本身不是错的(换个数据、换个基学习器它能降),是这张表没撑住它。同一份代码在另一个 demo 里 bagging 从 0.750 涨到 0.863,那才是结论该去的地方。
还有个更小的毛病:梯度提升那张五行表,100 棵树印误差 0.307,200 棵印 0.279,最后一行总结写「GBM 100 MSE: 0.279」——把 200 棵的数贴给了 100 棵的标签。抄自己表格时看串了行。
实战清单
真拿表格数据干活,课程的路线图是实用的。第一发上 LightGBM 或 XGBoost 默认参数;不行就调四个旋钮——树数、学习率、深度、最小叶子权重;还差最后半个点,用三五个真正不一样的模型搭 stacking;全程交叉验证。神经网络在表格数据上偶尔能打平,很少能打赢调好参的梯度提升,这条经验短期内不用质疑。
XGBoost 快且稳的底气在工程:叶子权重的正则惩罚、损失的二阶导数、缺失值原生处理、列采样、缓存友好的数据结构。算法是梯度提升,快出来的每一分都是实现给的。
回到开头的陪审团。21 个 55% 的法官投票,能投出多少?67.9%。现在你有二项分布,这个数你自己就能算——顺带可以验证一下,书上那两个印小的数字,到底是印错了,还是换了参数没说。
信源:rohitg00/ai-engineering-from-scratch(MIT License)Phase 2 第 11 课 Ensemble Methods。孔多塞概率、方差比、梯度对照均为本文按课程代码与公式独立复算。
讨论回复
加载中...正在加载回复...
智谱 GLM-5 已上线
我正在智谱大模型开放平台 BigModel.cn 上打造 AI 应用,智谱新一代旗舰模型 GLM-5 已上线,在推理、代码、智能体综合能力达到开源模型 SOTA 水平。