深度学习评估与类别不平衡
从 logits、阈值、混淆矩阵、AUC、校准和 mask 建立可靠评价。
学习目标
- 六条预测手算精确率与召回率
- 为什么不能平均每个 batch 的 F1?
- 说明:小构造例子只核对计数公式,不能替代真实分布下的置信区间与误差分析。
为什么需要这个概念
类别不平衡评估结合混淆矩阵、每类精确率召回率、F1 或 PR 曲线等指标;训练时的重采样或加权与评估时真实分布应分别处理。
学习前需要掌握
背景与问题
当正类很少时,永远预测负类也可能得到很高准确率。深度学习评估需要从业务代价、类别分布和决策阈值出发,而非只记录一个总准确率。
概念定义
类别不平衡评估结合混淆矩阵、每类精确率召回率、F1 或 PR 曲线等指标;训练时的重采样或加权与评估时真实分布应分别处理。
直观理解
模型找到多少真正的异常,以及它报警时有多少是真的,是两个不同问题,分别对应召回率与精确率。
核心原理
TP、FP、FN、TN 应跨完整评估数据累计,再计算指标。直接平均各批 F1 通常不等于全数据 F1,特别是尾批大小不同或某批没有正例时。多分类还需明确 macro、micro 和 weighted 平均。
阈值控制精确率与召回率的权衡,应按验证集和业务代价选择。使用加权损失或重采样后,输出概率的校准也可能改变,不能默认 0.5 永远合适;最终测试只使用已经锁定的规则。
序列与分割任务需排除 padding 和 ignore 标签。评估分布应尽量代表部署环境,不能为让分数好看把测试集平衡化后仍声称是原分布表现。
数学表达
核心公式
类别不平衡评估结合混淆矩阵、每类精确率召回率、F1 或 PR 曲线等指标;训练时的重采样或加权与评估时真实分布应分别处理。
变量含义
TP/FP/FN/TN混淆矩阵计数
计算步骤
- 1TP=1,FP=1,FN=1,TN=3。
- 2精确率与召回率均为 1/2。
- 3F1 为 0.5,准确率为 4/6。
代码对应位置
示例 1六条预测手算精确率与召回率的最小验证:使用完整构造输入核对六条预测手算精确率与召回率,输出只表示本例计算。
变量解释
| 变量 | 含义 |
|---|---|
TP/FP/FN/TN | 混淆矩阵计数 |
完整数值示例
六条预测手算精确率与召回率
已知条件
- 标签为 1、1、0、0、0、0
- 预测为 1、0、1、0、0、0
计算步骤
- TP=1,FP=1,FN=1,TN=3。
- 精确率与召回率均为 1/2。
- F1 为 0.5,准确率为 4/6。
计算结果
accuracy=0.6667,precision=recall=F1=0.5;指标表达的含义不同。
处理前后对比
- 小构造例子只核对计数公式,不能替代真实分布下的置信区间与误差分析。
六条预测手算精确率与召回率
同样的准确率可由不同错误结构产生。若漏掉一个正例代价远高于一次误报,就不能仅凭准确率挑模型,而要检查召回率与误报预算。
代码对分母为零显式返回 0,这是本例约定。真实报告应声明无正预测或无正例时的处理方式,并同时报告类别支持数,避免一个指标掩盖样本过少。
计算与实现步骤
- TP=1,FP=1,FN=1,TN=3。
- 精确率与召回率均为 1/2。
- F1 为 0.5,准确率为 4/6。
代码实现
示例 1
六条预测手算精确率与召回率的最小验证
example_01.py用途:使用完整构造输入核对六条预测手算精确率与召回率,输出只表示本例计算。
import torch
y = torch.tensor([1, 1, 0, 0, 0, 0])
pred = torch.tensor([1, 0, 1, 0, 0, 0])
tp = int(((pred == 1) & (y == 1)).sum())
fp = int(((pred == 1) & (y == 0)).sum())
fn = int(((pred == 0) & (y == 1)).sum())
precision = tp / (tp + fp) if tp + fp else 0.
recall = tp / (tp + fn) if tp + fn else 0.
f1 = 2 * precision * recall / (precision + recall) if precision + recall else 0.
print(f"TP={tp} FP={fp} FN={fn}")
print(f"accuracy={(pred == y).float().mean().item():.4f} precision={precision:.4f} recall={recall:.4f} F1={f1:.4f}")代码解析
解析始终位于完整代码下方,并按实际代码段逐项对应。
输入数据与任务
使用完整构造输入核对六条预测手算精确率与召回率,输出只表示本例计算。
y- 目标标签或连续目标值。
mean- 训练特征逐列均值。
Step 1 · 1–11 行
导入当前步骤需要的数值计算、预处理、模型或评价工具。依赖集中写在代码开头,便于复现。
import torch
y = torch.tensor([1, 1, 0, 0, 0, 0])
pred = torch.tensor([1, 0, 1, 0, 0, 0])
tp = int(((pred == 1) & (y == 1)).sum())
fp = int(((pred == 1) & (y == 0)).sum())
fn = int(((pred == 0) & (y == 1)).sum())
precision = tp / (tp + fp) if tp + fp else 0.
recall = tp / (tp + fn) if tp + fn else 0.
f1 = 2 * precision * recall / (precision + recall) if precision + recall else 0.
print(f"TP={tp} FP={fp} FN={fn}")
print(f"accuracy={(pred == y).float().mean().item():.4f} precision={precision:.4f} recall={recall:.4f} F1={f1:.4f}")代码与数学原理
减去训练均值并除以训练标准差,对应代码中的 mean/std 或 StandardScaler。
预期输出或运行结果
TP=1 FP=1 FN=1 accuracy=0.6667 precision=0.5000 recall=0.5000 F1=0.5000
常见错误 · 6 条
- 不要在测试集上调用 fit 或 fit_transform;测试集只能复用训练参数。
- 只 Accuracy
- 测试选阈值
- AUC 当校准
- padding 入指标
- 评估集过采样
实际应用
- 稀有异常检测的阈值选择
- 多分类与分割的每类误差分析
常见错误
- 只 Accuracy
- 测试选阈值
- AUC 当校准
- padding 入指标
- 评估集过采样
常见问题
为什么不能平均每个 batch 的 F1?
F1 是计数的非线性比值,各批分数平均会丢失支持数信息;应先汇总混淆计数,再按统一定义计算。
这个示例能说明什么边界?
小构造例子只核对计数公式,不能替代真实分布下的置信区间与误差分析。
推荐学习资料
参考库不会生成虚假资源或无效外部链接。