阶段:S6-评估验证 | 预计耗时:75-90 分钟 | 前置:S5 全部验收通过 代码:本篇代码要你自己敲成
model-learn/s6_confusion_matrix.py(不用 sklearn,手算混淆矩阵)
学习目标
- 手写 10×10 混淆矩阵,理解精确率 / 召回率 / F1 从矩阵里怎么算出来
- 亲手构造类别不平衡数据,亲眼看到"整体准确率 95% 但某类召回 0%"的骗局
- 学会按业务场景选指标:医疗筛查看召回、风控看精确、白名单看 F1
核心知识
1. 准确率为什么骗人
1000 个样本里 950 个是类 1。一个只会喊"全是 1"的废物模型准确率 95%——但对类 2~9 的召回率全是 0。类别越不平衡,准确率越没有意义。
2. 混淆矩阵:一张表看清"错成什么"
- 行=真实类别,列=预测类别;对角线=对的
- 召回率 = 对角线[i] / 行[i] 之和("这类里我抓住了多少")
- 精确率 = 对角线[i] / 列[i] 之和("我喊是这类时多少真是")
- F1 = 两者调和平均
3. 本机实验设计
- 训练集故意失衡:4000 张"1" + 其余 9 类各 250 张(≈64% 是 1)
- 评估两次:自然测试集(真实分布)+ 失衡测试子集(95% 是 1)——后者就是"95% 准确率"骗局的现场
实验任务
任务 1:写脚本(40 分钟)
# s6_confusion_matrix.py —— 手算混淆矩阵
import torch
# 1) 构造失衡训练集:label==1 取 4000 张,其余各类取 250 张(用 indices 过滤)
# 2) 快速训练(2000样本量级也行,2 epoch)
# 3) 在自然测试集上预测,手算混淆矩阵:
cm = torch.zeros(10, 10, dtype=torch.long)
for x, y in test_dl:
pred = model(x).argmax(1)
for t, p in zip(y, pred):
cm[t, p] += 1
print(cm)
# 4) 手算并打印每类 召回/精确:
# recall[i] = cm[i,i] / cm[i].sum() ; precision[i] = cm[i,i] / cm[:,i].sum()
# 5) 构造失衡测试子集(500 张"1"+其余各 6 张),再算整体准确率
任务 2:制造骗局现场(20 分钟)
在失衡测试子集上:整体准确率 = ?%(预期 90+);类 7 的召回率 = ?%(预期接近 0)。两个数字都来自同一个模型——这就是"只报准确率"的媒体标题党手法。
任务 3:指标选择三问(15 分钟)
- 癌症筛查宁可误报不可漏报——看哪个指标?(召回)
- 风控拦截宁可放过不可错杀好客户——看哪个?(精确)
- 你的失衡模型要修复,至少三个手段?(补数据/加权损失/过采样——说出两个即可)
验收标准
衔接下一阶段
指标会看了 → S6-02 交叉验证:评估结果本身也有运气成分。