AI 工程地基 31|95% 准确率的模型可能什么都没做

这是这门课的演示里一个模型的准确率。三百个样本,二百八十七个负类,十三个正类。这个模型做的事情只有一件:永远猜负。二百八十七次全对,十三次全错,300 次里对 287 次,95.67%。它什么都没学,什么都不知道,但它的准确率比很多认真训练的模型还好看。

95.67%。

这是这门课的演示里一个模型的准确率。三百个样本,二百八十七个负类,十三个正类。这个模型做的事情只有一件:永远猜负。二百八十七次全对,十三次全错,300 次里对 287 次,95.67%。它什么都没学,什么都不知道,但它的准确率比很多认真训练的模型还好看。

这就是模型评估这堂课要处理的问题。分数本身不说谎。会说谎的是你读分数的方式。

三份数据,三种用途

先把一件事说清楚:同一个数据集,要被切成三份,各干各的。

训练集是课本,模型从它学。验证集是模拟考,你调超参数、在几个候选模型里挑人,看的是它。测试集是高考,只在最后碰一次,用来看最终成绩。课程里有句话说得很重:如果你看了测试成绩,然后回去改了模型,那它就不再是测试集了——它变成了第二次模拟考。你已经把高考当练习做了一次,下次再来这个分数就不能信了。

三份的常见比例是六成、两成、两成。

四个格子

分类模型的所有指标,都从一张四个格子的表里来。

模型预测正或负,实际也是正或负,交叉出四格:预测正实际正(真阳)、预测负实际负(真阴)、预测负实际正(漏报)、预测正实际负(误报)。就这四格。

准确率是四个格子加起来算的:对的比例。它在类别均衡时是好东西,在 287:13 这种数据上就是刚才那个 95.67% 的把戏。

精确率只看两格:模型报为正的里面,有多少是真的。误报代价高的场景用它——比如垃圾邮件过滤器把客户的重要邮件错杀了。

召回率看另外两格:真正的正例里面,抓住了多少。漏报代价高的场景用它——比如癌症筛查漏了一个肿瘤。

F1 是这两个的调和平均,两边都不想牺牲的时候用。

演示里认真训练的模型在测试集上的成绩:真阳 24,真阴 25,误报 3,漏报 8。精确率 24/27 = 0.8889,召回 24/32 = 0.75。同一个模型,两个数字,看你更怕哪种错。

还有一个不看阈值的指标叫 AUC。前面那些指标都要先定一条线(概率大于 0.5 算正),AUC 把所有可能的线都扫一遍,量的是模型的排序能力:随机抽一个正例一个负例,正例的分数排在负例前面的概率。0.5 是瞎猜,1.0 是完美分开。演示里这个模型 AUC 0.9408——排序能力远好于它的 0.8167 准确率,因为阈值那条线卡在了损失信息的位置。

轮着来

数据小的时候,单切一份验证集太浪费。于是有了交叉验证:切五份,轮流每次留一份当验证、其余四份训练,五轮下来取平均。每个数据点恰好被验证一次,平均分比任何单次切分都稳。

课程在这一节安排了对比:普通五折对分层五折。分层的意思是每一折里类别比例跟全量一致,专门服务不平衡数据。

但对比跑在了 152:148 的均衡数据上。结果:普通五折平均 0.8733,分层五折平均 0.8762,差 0.3 个百分点;折间波动反倒从 0.036 涨到 0.061。在不需要分层的数据上分层,什么都看不出来。真正能看出价值的是那份 287:13 的数据——我在它上面补跑了对比:随机切分下,五个验证折里的正例数是 1、4、3、2、3;分层之后是 2、2、2、2、5。前者有的折里正例只有 1 个,评估一个折等于掷一枚硬币。这才是分层要解决的问题,只是演示没在它该出现的地方出现。

分层自己也有边界。少数类的数量比折数还少的时候——比如 3 个正例、5 折——这个课里的实现会把 3 个正例全部塞进最后一折。前四个折的验证集里一个正例都没有:拿 F1 当指标的话,四折全是 0.0,不是模型差,是没得数。第五折更惨:它的训练集里一个正例都没有,训出来一个只会猜负的模型。整轮交叉验证安静地给出一个没有意义的结果。sklearn 遇到同样场景会明着警告你。每个折至少要分到一个正例,这是分层抽样没写在参数表上的前提。

测试集里只有三个病人

回到那份不平衡数据。十三个正例随机撒进三百个样本,按六二二切开之后,测试集分到 3 个正例。

训练出来的模型在这 3 个正例上:召回 3/3 = 1.0,精确率 3/4 = 0.75(抓全了,但多误报一个)。这两个数字看起来体面,其实分辨率极低:测试集每漏掉一个正例,召回率掉 33%;每多一个误报,精确率掉 15 到 25 个百分点。讲「评估要可靠」的这堂课,自己的评估建立在 3 个样本上。而分层切分本可以让每一份稳定分到 2 到 3 个正例——课程在错误清单里写了「不用分层切分」这一条,只是没在这个正需要它的地方用上。

曲线要怎么看

学习曲线:把训练分和验证分画成训练集大小的函数。训练分高、验证分低、缺口大,是过拟合,加数据该有帮助;两条线一起趴在低分上,是欠拟合,加数据没用,要换更复杂的模型。

演示跑出来的曲线:训练分从 24 个样本时的 1.0000 一路降到 240 个时的 0.8792,验证分在 0.8167 到 0.85 之间徘徊。缺口从 0.15 缩到 0.03——这个方向是可靠的,说明过拟合在退。但验证分那三四个百分点的起伏别当真:验证集只有 60 个样本,每猜错一个就是 1.67 个百分点,光抽样的运气成分就有正负 4 个百分点。这份数据的理论上限约 0.892(生成时往两个特征的和里掺了 0.5 的噪声,任何模型都越不过去),演示里从 0.82 到 0.87 的所有分数都还趴在这个噪声带里。读曲线的纪律:缺口的方向可以信,验证分的绝对水平别抠。

顺序错了,错得很小

这堂课排第一位的错误叫数据泄漏:测试集的信息在训练时就被模型知道了。最典型的样子,课程原话是「切分前就在全量数据上拟合标准化器」,后面补了一句操作准则——先切分,再预处理。

然后演示自己上场:两百个回归样本,先对全量算均值方差做标准化,再切分。

顺序反了。我实测了正确顺序(先切分、只用训练集的统计量做标准化):R 方 0.9567,课程顺序 0.9560,差 0.0006。均匀分布的数据上,这点泄漏几乎不疼。但同样的顺序换到偏态分布、换到信息量大的预处理上,就不是小数了——标准化器在切分前「见过」测试集,等于考前看过考卷的统计摘要,只是这份考卷出得太对称,看不出占便宜。这堂课的技能清单文件里自己写着「Split before any preprocessing」,正文、技能文件、示例代码,三处里有两处是对的。

t 值等于零的比较

演示的最后一节是统计比较:配对 t 检验,比较两个模型。模型 A 训练 100 轮,模型 B 训练 500 轮,同样的数据同样的五折。

t = 0.0000。

不是「差异不显著」,是根本没有差异可检。这两个模型在这份数据上收敛到了同一个点:权重写到小数点后七位是 3.4088268 对 3.4088270,五折的预测逐个样本完全一致。t 检验的工序完整跑了一遍,但拿去做比较的是同一个东西的两份拷贝。想让这个工具有事可做,得拿真有差异的模型来——比如 5 轮对 2000 轮的训练,那才有差异可算,t 值 -1.00,离 2.78 的显著线还远,结论照样是「分不出来」,但至少是一道真题。

顺带一个小地方:代码里算标准差除的是 5(折数),配对 t 检验的教科书做法除 4(自由度)。这让 t 的绝对值被放大 1.118 倍,方向上更容易误判显著。演示里 t 正好是零,看不出来,但凡换个真有差异的对比,这个数就悄悄偏了。

练习

课程留的三道练习里,第三道最值得做:置换检验。把标签随机打乱,重新训练,测一次成绩;重复一百次,得到一个「模型其实什么都没学到」的成绩分布。然后看你模型的真实成绩落在这个分布的什么位置。它把「这个模型是不是真在学」从一句判断变成一个可以数出来的数字——和这堂课的起点正好接上:那个 95.67% 的模型,标签打乱一百次,它大概每次都能考出这个分数。

暂无表态

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

讨论回复(0)

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

智谱 GLM-5 已上线

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

领取 2000万 Tokens