图谱连接

草稿

精确率

衡量模型预测为正类时,有多少次是真的。

concept beginner machine-learningmetricsclassification

问题起点:报警该不该信?

你的模型给 12 封邮件打标签,spam 是告警。你关心的是:模型把一封邮件标成 spam 时,能信几成?

垃圾邮件告警漏斗先经过 12 封邮件,只有 5 封会进入“预测为 spam”告警口。

全部 12 封评估邮件

每封邮件都保留真实标签和模型预测。

e1

立即领取奖品

明显的中奖诱饵,被过滤器拦下。

actual: 垃圾邮件(spam), predicted: 垃圾邮件(spam), TP: 真正例(true positive)

e2

项目笔记

普通工作邮件,被留在收件箱。

actual: 非垃圾邮件(not-spam), predicted: 非垃圾邮件(not-spam)

e3

收据已附上

真实收据被错误标成垃圾邮件。

actual: 非垃圾邮件(not-spam), predicted: 垃圾邮件(spam), FP: 假正例(false positive)

e4

账户提醒

伪造提醒漏进了收件箱。

actual: 垃圾邮件(spam), predicted: 非垃圾邮件(not-spam)

e5

限时优惠

促销垃圾邮件被正确拦截。

actual: 垃圾邮件(spam), predicted: 垃圾邮件(spam), TP: 真正例(true positive)

e6

团队午餐

团队日常邮件被正确保留。

actual: 非垃圾邮件(not-spam), predicted: 非垃圾邮件(not-spam)

e7

密码重置

用户请求的重置邮件正常送达。

actual: 非垃圾邮件(not-spam), predicted: 非垃圾邮件(not-spam)

e8

紧急转账

诈骗邮件被过滤器漏掉。

actual: 垃圾邮件(spam), predicted: 非垃圾邮件(not-spam)

e9

航班变更

有用的出行更新被误报。

actual: 非垃圾邮件(not-spam), predicted: 垃圾邮件(spam), FP: 假正例(false positive)

e10

加密币奖励

可疑奖励垃圾邮件被正确拦截。

actual: 垃圾邮件(spam), predicted: 垃圾邮件(spam), TP: 真正例(true positive)

e11

发票已批准

业务发票被正确接收。

actual: 非垃圾邮件(not-spam), predicted: 非垃圾邮件(not-spam)

e12

验证钱包

钓鱼式钱包邮件被漏判。

actual: 垃圾邮件(spam), predicted: 非垃圾邮件(not-spam)

仅“预测为 spam”告警(5 条)

这 5 封邮件进入精确率分母:e1, e3, e5, e9, e10。

e1

立即领取奖品

明显的中奖诱饵,被过滤器拦下。

actual: 垃圾邮件(spam), predicted: 垃圾邮件(spam), TP: 真正例(true positive)

e3

收据已附上

真实收据被错误标成垃圾邮件。

actual: 非垃圾邮件(not-spam), predicted: 垃圾邮件(spam), FP: 假正例(false positive)

e5

限时优惠

促销垃圾邮件被正确拦截。

actual: 垃圾邮件(spam), predicted: 垃圾邮件(spam), TP: 真正例(true positive)

e9

航班变更

有用的出行更新被误报。

actual: 非垃圾邮件(not-spam), predicted: 垃圾邮件(spam), FP: 假正例(false positive)

e10

加密币奖励

可疑奖励垃圾邮件被正确拦截。

actual: 垃圾邮件(spam), predicted: 垃圾邮件(spam), TP: 真正例(true positive)

先算全局正确率看起来是:

TP+TNTP+FP+TN+FN=3+412=712\frac{TP + TN}{TP + FP + TN + FN} = \frac{3 + 4}{12} = \frac{7}{12}

这是 58.3%,但它混合了两类问题:

  • 全部 12 封邮件有多少是对的?
  • 所有被报告为 spam 的告警有多少是真的?

第一个朴素想法:沿用全局分母

如果仍然用全局分母,非告警样本会和告警样本一起入账:

准确率与精确率对比准确率使用所有预测;精确率只看“预测为正类”的邮件。
准确率(accuracy)

问题: 全部邮件里有多少是对的?

(7 / 12 = 58.3%)

精确率(precision)

问题: 有多少个“spam 预警”是对的?

(3 / 5 = 0.6)

它为什么会疼

e3e4 都是错例,但影响不同:

  • e3:真实是非垃圾邮件却被报为 spam (FP),直接降低告警可信度;
  • e4:真实是垃圾邮件却被放过 (FN),更接近“召回率损失”,不是“告警错误”。

核心发明:只看正类预测这一列

精确率的问题是:预测为正类(spam)里,有多少是正确的

precision=TPTP+FP\text{precision} = \frac{TP}{TP + FP}

所以这个固定样本得到:

33+2=35=0.6\frac{3}{3 + 2} = \frac{3}{5} = 0.6

互动演示:逐个处理告警

这个节点只处理预测为 spam 的五条邮件,顺序固定:

e1, e3, e5, e9, e10

预测 spam 告警精确率

e1 → TP:立即领取奖品。真实 垃圾邮件(spam),预测 垃圾邮件(spam),格子:TP(真正例(true positive))。运行中精确率:1/1 = 1.0。

主题

立即领取奖品

当前步骤

1/5

可信告警

1/1

运行中精确率

1.0

百分比: 100.0%

最终值(固定样本)

3/5 = 0.6

精确率追踪账本(仅预测为 spam)
步骤邮件真实预测格子可信告警全部告警精确率
1e1垃圾邮件(spam)垃圾邮件(spam)tp (TP)111/1 = 1.0
2e3非垃圾邮件(not-spam)垃圾邮件(spam)fp (FP)121/2 = 0.5
3e5垃圾邮件(spam)垃圾邮件(spam)tp (TP)232/3 = 0.667
4e9非垃圾邮件(not-spam)垃圾邮件(spam)fp (FP)242/4 = 0.5
5e10垃圾邮件(spam)垃圾邮件(spam)tp (TP)353/5 = 0.6

无 JS 时,页面下方账本仍然可直接读取:

精确率追踪账本(无 JS 回退)
步骤邮件主题真实预测格子可信告警全部告警当前值
1e1立即领取奖品spamspamTP111/1 = 1
2e3收据已附上not-spamspamFP121/2 = 0.5
3e5限时优惠spamspamTP232/3 = 0.667
4e9航班变更not-spamspamFP242/4 = 0.5
5e10加密币奖励spamspamTP353/5 = 0.6

正确性直觉

对每个被处理的告警而言,结果只可能是 TPFP,所以 TP + FP 就是“所有告警”的计数。

不进入精确率分母的样本是:

  • TN + FN 在外:e2, e4, e6, e7, e8, e11, e12
  • 漏报的真实垃圾邮件在外:e4, e8, e12

到末尾:

  • TP = 3
  • FP = 2
  • precision = 3 / 5 = 0.6

实现思路

interface Counts {
  tp: number;
  fp: number;
}

function precisionFromCounts(counts: Counts) {
  const denominator = counts.tp + counts.fp;
  if (denominator === 0) {
    return { numerator: counts.tp, denominator, value: null };
  }
  return { numerator: counts.tp, denominator, value: counts.tp / denominator };
}

复杂度

如果你已经有 tp/fp 计数:

  • O(1) 即可给出精确率;
  • 先扫描一次再统计时是 O(n) 时间、额外 O(1) 空间。

常见误区

  • 精确率不是准确率,准确率看全部 12 封。
  • 精确率不是召回率,召回率看实际为 spam 的覆盖率。
  • 精确率高不代表漏报少:e4e8e12 在分母外,仍会被模型漏掉。
常见误区高精确率不等于不漏报,而“漏报率”属于另一类问题。
分母边界检查
示例为何精确率仍是 3/5
e3误报(FP)— 会降低信心。
e4漏报(FN)— 不在分母内。
e8漏报(FN)— 同样在分母之外。
e12漏报(FN)— 仍在分母之外。
分母外的漏报(spam)

e4, e8, e12

零分母展示

不可用

零分母约定

若模型完全没报警(tp = 0, fp = 0):

  • 分母 tp + fp = 0
  • 内部返回 null
  • 文案渲染为 不可用(英文显示为 not available
预测正类列该列只包含“真正例”和“假正例”。
TP (3)

预测为 spam 且真实为 spam(对告警)。

e1

立即领取奖品

明显的中奖诱饵,被过滤器拦下。

actual: 垃圾邮件(spam), predicted: 垃圾邮件(spam), TP: 真正例(true positive)

e5

限时优惠

促销垃圾邮件被正确拦截。

actual: 垃圾邮件(spam), predicted: 垃圾邮件(spam), TP: 真正例(true positive)

e10

加密币奖励

可疑奖励垃圾邮件被正确拦截。

actual: 垃圾邮件(spam), predicted: 垃圾邮件(spam), TP: 真正例(true positive)

FP (2)

预测为 spam 但真实为 not-spam(误报)。

e3

收据已附上

真实收据被错误标成垃圾邮件。

actual: 非垃圾邮件(not-spam), predicted: 垃圾邮件(spam), FP: 假正例(false positive)

e9

航班变更

有用的出行更新被误报。

actual: 非垃圾邮件(not-spam), predicted: 垃圾邮件(spam), FP: 假正例(false positive)

精确率分母中不计入

TN + FN 在分母之外 (7)

e2, e4, e6, e7, e8, e11, e12

图谱连接

图谱走向精确率是混淆矩阵的后续,且问题只限于二分类正例预测。
confusion-matrix

已实现

precision

已实现

练习

  1. 为什么准确率和精确率分母不同?
  2. e1 -> e3 计算前两步精确率。
  3. precision = null 的场景里不应该显示哪个值?
  4. 哪类案例会进入精确率分母,哪类不会?

图谱连接 : 精确率