AI 工程地基 07|检测 99% 准确,你却只有 1% 可能生病:贝叶斯改口术

「AI 工程地基」系列第七篇。啃的是 GitHub 58k star 的开源课 ai-engineering-from-scratch,Rohit Ghumare 写的,一课一课来。今天第 07 课:贝叶斯定理,Build 型,75 分钟。前六课攒了矩阵、梯度、概率三门手艺,这一课回答一个更老的问题:拿到证据之后,怎…

「AI 工程地基」系列第七篇。啃的是 GitHub 58k star 的开源课 ai-engineering-from-scratch,Rohit Ghumare 写的,一课一课来。今天第 07 课:贝叶斯定理,Build 型,75 分钟。前六课攒了矩阵、梯度、概率三门手艺,这一课回答一个更老的问题:拿到证据之后,怎么改口。

场景是这样。你去做个体检,报告上一个加号。医生说这个检测 99% 准。多数人心里当场就定了:那基本就是中招了。真账算出来吓人一跳——如果这种病一万人里才有一个患者,你拿到阳性之后,真的生病的概率不到 1%。剩下那 99% 的阳性,全是健康人贡献的误报。不是检测不行,是病人太稀有,误报的池子比病人的池子大一百倍。

道理就一条公式。贝叶斯定理可以从条件概率的定义两步推出来,四个量一个等式:先验,看证据之前你怎么押;似然,假设为真时这个证据有多常见;证据,所有可能世界里看到这个信号的总概率;后验,改完口的新押注。医疗例子代进去:先验 0.0001(万分之一的人有病),似然 0.99(病人几乎都测出阳性),分母把健康人的误报全算进去,最后后验 0.98%。同一套公式换个场景照样好使:一封含「lottery」的邮件,垃圾概率从 30% 被一个词推到 95.5%。

然后课程带你把它写成代码。朴素贝叶斯分类器,垃圾邮件版:训练集 12 句话,5 句垃圾 7 句正常,学出每个词在两类里的概率,新消息来了就把词概率连乘,谁分高归谁。「朴素」是指它假设词和词互相独立——这假设明明是错的(「New」和「York」总是搭伙出现),但实践中出奇地好用,因为分类只要排序,不用概率校准。有个坑必须埋:一个训练时没见过的词,概率是零,连乘直接归零。解法叫拉普拉斯平滑,每个词的计数一律加一,谁也不许是零。连乘还有个老朋友——下溢,上一课 0.01 连乘 50 次变成 10⁻¹⁰⁰ 的那个病——解法也是老药:搬进对数里,连乘变累加。

这课还有两块硬货。一块是 MAP,最大后验估计:MLE 只管让数据最开心,MAP 在参数上先押一个信念(「参数应该小」),再让数据说话。押高斯先验就是 L2 正则化,押拉普拉斯先验就是 L1——你每天在 loss 里加的正则项,翻译成贝叶斯方言全是先验。另一块是共轭先验:Beta 先验配伯努利数据,后验还是 Beta,更新规则简单到只是加法——先验 Beta(a,b),看到 s 次成功 f 次失败,后验 Beta(a+s, b+f)。今天的后验是明天的先验,这就是在线学习的原型:硬币第一天 7 正 3 反,均值 0.667;第二天又 5 正 5 反,后验 Beta(13,9),均值拉回 0.591。证据攒着攒着,信念自己走。A/B 测试也在这套语言里:两个变体各挂一个 Beta 后验,蒙特卡洛各抽十万个样本,数一数 B 压过 A 的占比,就是「B 更好」的概率。

过一遍海关。数字先说结论:干净。医疗例 0.98%、lottery 例 95.5%、Beta 序列 0.667 和 0.591、A/B 两个后验均值 0.051 和 0.066,手算和实测全部吻合。代码也全跑通:四条测试消息的预测,和 sklearn 的 MultinomialNB 逐条一致。

但有一个数字没跟自己的数据对账。课程在 A/B 一节的结尾说,贝叶斯给你一句直接陈述:「B 更好的概率是 97%」。这组数据实测不是 97%,是 92.5%。十万次蒙特卡洛抽样,B 压过 A 的占比 0.9252。这个差距要命的地方在于课程自己的决策规则:P(B>A) 超过 0.95 才上变体 B。92.5% 不过线,按它自己的规则这组数据判的是「继续收集」,不是「出货 B」。97% 是一句借来的示例话术,不是这组数据算出来的账。

第二处,「同一个算法」要打个星号。from-scratch 版用 split() 分词,词表 44 个词;CountVectorizer 默认的正则只收两个字符以上的词,词表 43 个——被吃掉的是「a」,测试句「you won a free prize」在两边收到的证据集根本不同。分类结果碰巧一致,因为「a」这条证据近乎中性。但 tokenizer 不在算法里,在接口里,接口里藏着决策:今天被吃的是人畜无害的冠词,明天被吃的未必。

第三处,正文说 smoothing=0 时一个未见词「杀死整个连乘」,课程自己的代码在 log 空间里跑,实际死法不一样:math.log(0) 当场抛 ValueError,直接指到那个词。乘法里是静默归零,log 里是响亮崩溃。失败方式本身是诚实的——上一课 Value 类的指数运算也是这个脾气,错就错在明处。

口径上还有个习惯值得点名。贝叶斯 A/B 的优点清单里有句口号:「随时查看结果而不推高误报率,没有偷看问题」。这句话的条件写在同一节隔壁的表格里——「给定选得好的先验和正确设定的模型」。条件真实存在,先验选歪、模型设错时偷看照样出事,但口号句里咽了。同一形态还有一处:「只需更新两个数」的完整版是「只要共轭才这么便宜,一般后验要 MCMC」,课程自己三段之后也承认了。口号先行,条件后置,读这门课得习惯自己补限定词。

练习 1 值得现在就算:两次独立阳性之后,生病概率是多少?不是 0.98% 的平方,也不是 99%。把第一次的 0.98% 当先验再过一遍公式,实测 49.5%——第一次检测把你从万里挑一拉到百分之一,第二次直接拉到掷硬币。练习 4 也在桌上:10 次抛硬币 7 次正面,Beta(2,2) 先验下 MAP 估计 0.667,MLE 是 0.7。先验把你的估计往 0.5 拉了三厘米。就停在这两个数上。

暂无表态

想参与讨论或点赞?登录后使用完整功能

讨论回复(0)

暂无回复,登录后可参与讨论
合作

智谱 GLM-5 已上线

在智谱开放平台 BigModel.cn 打造 AI 应用。新一代旗舰模型 GLM-5 在推理、代码、智能体综合能力达到开源模型 SOTA。

领取 2000万 Tokens