一个退款分类器在一百条请求中答对了九十五条,看起来很好。如果其中九十五条本来就不应该退款,而分类器永远回答“不退款”,这个数字几乎没有反映识别有效申请的能力。
准确率没有算错,错的是我们用它回答了一个它无法独立回答的问题。理解指标要从分子、分母和业务代价开始。
从四种结果推导指标
把“符合退款条件”定义为正类。假设真实符合条件的十条中识别出八条、漏掉两条;真实不符合条件的九十条中误放三条、正确拦截八十七条。
| 实际符合 | 实际不符合 | |
|---|---|---|
| 预测符合 | TP = 8 | FP = 3 |
| 预测不符合 | FN = 2 | TN = 87 |
准确率是 (8 + 87) / 100 = 95%。Precision 是 8 / (8 + 3) ≈ 72.7%,回答“放行的申请有多少真符合”;Recall 是 8 / (8 + 2) = 80%,回答“符合的申请找到了多少”。这些名称的标准定义可对照 scikit-learn 指标文档。这里“正类”必须固定;如果下一份报告把风险请求当正类,Precision 的业务含义就会反过来。
F1 是 Precision 和 Recall 的调和平均,也可以写成 2TP / (2TP + FP + FN)。上例为 16 / 21 ≈ 76.2%。调和平均会惩罚一高一低,但并没有表达误退款和多一次人工审核的经济差别。业务代价不对称时,应另报误放数量和损失,不能只追求 F1。
# 显式保留“不可计算”,避免无正例时返回一个虚假的满分。
def divide(numerator: int, denominator: int):
return numerator / denominator if denominator else None
TP, FP, FN, TN = 8, 3, 2, 87
metrics = {
"accuracy": divide(TP + TN, TP + FP + FN + TN),
"precision": divide(TP, TP + FP),
"recall": divide(TP, TP + FN),
"f1": divide(2 * TP, 2 * TP + FP + FN),
}
print(metrics) # 0.95、约 0.727、0.8、约 0.762
当系统一次也没预测正类时,Precision 分母为零。不同库会使用零、警告或其他约定,报告必须写清。返回 None 并显示有效样本数,可以提醒读者这里缺少信息。
多类别平均会改变我们重视谁
客服请求可能有查询、退款、投诉三类。宏平均先计算每类指标,再等权平均,因此稀少的投诉和大量查询有同样权重。微平均先汇总所有类别的 TP、FP、FN,再计算,更受常见类影响。在单标签多分类且包含所有类别时,微平均 Precision、Recall、F1 与准确率相等。
例如查询有九百条、退款有九十条、投诉有十条。只提升查询就可能显著提高微平均,但投诉仍然全错。我们应该同时展示整体指标和各类样本量,不用一个平均数隐藏产品的重要边界。
按线上占比加权,可以估计某种目标流量分布下的表现;按风险加权,则表达业务偏好。权重来源必须明确。对一个人为构造的困难集使用自然流量的解释,会给读者造成错误印象。
拒答使问题多了一个维度
模型如果只回答最简单的十道题,十道全对,回答准确率就是 100%。但另外九十道被拒答。我们要同时计算覆盖率 已回答 / 全部可处理请求 和已回答部分的错误率。
提高拒答阈值往往降低覆盖率并减少错误,两者应成对比较。如果拒绝本身是正确动作,例如无权访问他人订单,它应进入权限案例的成功判定;如果只是没把握回答一个可解问题,则属于未完成。这两个“拒绝”不能混成一类。
一张覆盖率—错误率曲线比一个准确率更容易看出系统取舍。阈值必须在验证集上选,在独立测试集上报告,避免挑选最有利结果。
超时和未知不能从分母消失
一百个任务,九十个有结果,其中八十一个成功,十个超时。只看有结果部分是 90%;按提交任务计算自动成功率是 81%。如果产品承诺每个请求都提供服务,后者更接近用户经历。
另有五条是评分器超时,这不是 Agent 的五次失败,也不是五次成功。应报告八十一条已确认成功、十四条已确认未成功、五条未知,以及 95% 的评分覆盖率;全样本成功率只能确定在 81% 到 86% 之间。正式发布可以要求未知项完成复核,不能删掉它们假装报告完整。
平均延迟和每次成功成本
九十九个请求一秒完成,一个请求等了一百秒,平均约两秒,却掩盖了极差体验。P95 表示至少约 95% 样本不超过该值,P99 更关注尾部,但小样本的高分位估计很不稳定。报告样本量、计时起点和是否包含重试,比单独展示小数更重要。
“每次成功成本”应使用实验总成本除以成功任务数,把失败尝试和重试花费算进去。十次任务共花五元、完成五次,每次成功成本是一元,而不是只统计成功那五次的调用费用。分母为零时不能显示零成本。
检索、排序、编辑距离和配对比较的完整实现见 metrics.py下载。
最终报告是一组有明确解释的指标:任务成功、风险失败、评分覆盖、延迟和成本。它们之间存在取舍,评测的职责是把取舍呈现出来。
继续阅读与配套材料
完整示例、运行方式和验证边界见评测实验指南下载。本系列的订单、政策、金额和实验数据均为教学示例。