图谱连接

草稿

召回率

衡量真实正类中有多少被模型找到了。

concept beginner machine-learningmetricsclassification

问题起点:真实 spam 抓了多少?

模型评估了 12 封邮件,你想回答的核心问题是:

在真实为 spam 的邮件里,模型抓到了多少?

从 12 封邮件到 6 封真实 spam召回率只回答“真实为正类”问题,所以分母是实际 spam 的样本。
e1

立即领取奖品

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

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

e2

项目笔记

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

actual: 非垃圾邮件(not-spam), predicted: 非垃圾邮件(not-spam) (TN: 真负例(true negative))

e3

收据已附上

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

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

e4

账户提醒

伪造提醒漏进了收件箱。

actual: 垃圾邮件(spam), predicted: 非垃圾邮件(not-spam) (FN: 假负例(false negative))

e5

限时优惠

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

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

e6

团队午餐

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

actual: 非垃圾邮件(not-spam), predicted: 非垃圾邮件(not-spam) (TN: 真负例(true negative))

e7

密码重置

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

actual: 非垃圾邮件(not-spam), predicted: 非垃圾邮件(not-spam) (TN: 真负例(true negative))

e8

紧急转账

诈骗邮件被过滤器漏掉。

actual: 垃圾邮件(spam), predicted: 非垃圾邮件(not-spam) (FN: 假负例(false negative))

e9

航班变更

有用的出行更新被误报。

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

e10

加密币奖励

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

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

e11

发票已批准

业务发票被正确接收。

actual: 非垃圾邮件(not-spam), predicted: 非垃圾邮件(not-spam) (TN: 真负例(true negative))

e12

验证钱包

钓鱼式钱包邮件被漏判。

actual: 垃圾邮件(spam), predicted: 非垃圾邮件(not-spam) (FN: 假负例(false negative))

召回率分母摘要

actual positives = TP + FN = 6

TP 标识: e1, e5, e10

FN 标识: e4, e8, e12

第一种朴素想法:仍用准确率

如果继续用总体正确率:

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

它告诉你“整体对了多少”,但不回答真实正类覆盖率。

为什么不够:漏报 (FN) 在这个问题里很关键

e4e8e12 都是 FN

  • e4: 真实是 spam,但预测 not-spam(漏报)
  • e8: 真实是 spam,但预测 not-spam(漏报)
  • e12: 真实是 spam,但预测 not-spam(漏报)

所以对召回率来说,分母是 TP + FN = 6,不是 12。

准确率与召回率对比准确率看全部 12 条,召回率只看真实为 spam 的 6 条。
准确率问题

全部 12 条预测都在分母内。

分子 = TP + TN = 7

Accuracy = 7 / 12 = 58.3%

召回率问题

仅真实正类样本在分母中。

分母 = TP + FN = 6

分子 = TP = 3

Recall = 3/6 = 0.5

召回率分母之外

真实负类(6): e3, e9, e2, e6, e7, e11

核心发明:看“真实正类”一行

矩阵约定为:

actual 行, predicted 列\text{actual 行},\ \text{predicted 列}

召回率只读真实正类行:

recall=TPTP+FN\text{recall} = \frac{TP}{TP + FN}

本例:

33+3=36=0.5\frac{3}{3 + 3} = \frac{3}{6} = 0.5
真实正类行行是真实标签,列是模型预测。召回率读真实正类行的 TP + FN。

方向约定:行是实际标签,列是预测标签。

真实正类行(按行查看)
真实 \ 预测预测为 spam预测为非垃圾
真实 spamTP (3): e1, e5, e10FN (3): e4, e8, e12

召回率读取 TP + FN = 6。

分子 / 分母拆分在该样本中,命中 spam 的数是 TP,所有真实 spam 是 TP + FN。
分子(捕获的真实 spam)

来自真实正类行的 TP。

3 (e1, e5, e10)

分母(所有真实 spam)

真实正类行里的 TP + FN。

6 (e1, e5, e10, e4, e8, e12)

结果

Recall = 3/6 = 0.500

含义:6 封真实 spam 中,抓住了 3 封。

交互演示:逐个处理真实正类

交互演示仅处理 e1, e4, e5, e8, e10, e12,按固定顺序逐步给出分子/分母和当前召回率。

真实垃圾邮件召回追踪

e1: 立即领取奖品. 真实标签 垃圾邮件(spam), 预测标签 垃圾邮件(spam). 格子: TP (真正例(true positive)). 捕获正类 1/1, 运行中召回率: 1.0.

步骤

1/6

主题

立即领取奖品

当前样本

e1

真实标签

垃圾邮件(spam)

预测标签

垃圾邮件(spam)

格子

TP (真正例(true positive))

捕获正类

1/1

运行中召回率

1.0

百分比: 100.0%

最终固定值

3/6 = 0.5

真实正类召回追踪账本(无 JS 回退)
步骤邮件主题格子已捕获真实正类已见运行中召回率真实预测
1e1立即领取奖品TP (真正例(true positive))111/1 = 1.0垃圾邮件(spam)垃圾邮件(spam)
2e4账户提醒FN (假负例(false negative))121/2 = 0.5垃圾邮件(spam)非垃圾邮件(not-spam)
3e5限时优惠TP (真正例(true positive))232/3 = 0.667垃圾邮件(spam)垃圾邮件(spam)
4e8紧急转账FN (假负例(false negative))242/4 = 0.5垃圾邮件(spam)非垃圾邮件(not-spam)
5e10加密币奖励TP (真正例(true positive))353/5 = 0.6垃圾邮件(spam)垃圾邮件(spam)
6e12验证钱包FN (假负例(false negative))363/6 = 0.5垃圾邮件(spam)非垃圾邮件(not-spam)

无 JS 时的账本(与交互一致):

真实 spam 召回追踪账本(无 JS 回退)
步骤邮件主题真实预测格子已捕获正类真实正类已见当前值
1e1立即领取奖品spamspamTP111/1 = 1
2e4账户提醒spamnot-spamFN121/2 = 0.5
3e5限时优惠spamspamTP232/3 = 0.667
4e8紧急转账spamnot-spamFN242/4 = 0.5
5e10加密币奖励spamspamTP353/5 = 0.6
6e12验证钱包spamnot-spamFN363/6 = 0.5

漏报疼点

召回率直接把漏报放进“真实正类”分母,因此会暴露覆盖损失。

漏报带来的压力假负例(FN)是漏报,计入 actual-positive 分母。
e4

账户提醒

伪造提醒漏进了收件箱。

actual: 垃圾邮件(spam), predicted: 非垃圾邮件(not-spam) (FN: 假负例(false negative))

e8

紧急转账

诈骗邮件被过滤器漏掉。

actual: 垃圾邮件(spam), predicted: 非垃圾邮件(not-spam) (FN: 假负例(false negative))

e12

验证钱包

钓鱼式钱包邮件被漏判。

actual: 垃圾邮件(spam), predicted: 非垃圾邮件(not-spam) (FN: 假负例(false negative))

为什么受影响

这些都是真实垃圾邮件但没有被捕获。

漏报数量:3

召回率分母核验

每个漏报仍然计入分母(FN)。

公式:TP + FN。

零分母约定

当评估集里没有真实正例时:

  • TP = 0
  • FN = 0
  • TP + FN = 0
  • 内部值:null
  • 渲染结果:不可用
零分母边界情况如果没有真实正类样本,召回率未定义,应显示不可用。
零分母约定对照表
情形TPFN分母(TP + FN)内部值渲染值
没有真实正类000null不可用

实现思路

interface RecallCounts {
  tp: number;
  fn: number;
}

function recallFromCounts(counts: RecallCounts) {
  const denominator = counts.tp + counts.fn;
  if (denominator === 0) {
    return { numerator: counts.tp, denominator, value: null };
  }
  return { numerator: counts.tp, denominator, value: counts.tp / denominator };
}
实现分支表先得到 TP/FN 计数,再在分母为零时分支,最后再格式化输出。
召回率实现分支表
步骤分子 (tp)分母 (tp + fn)分支结果
1tptp + fn若分母==0null
2tptp + fn否则tp / (tp + fn)

正确性直觉

真实正类里只有两种情况,且互斥:

  • TP: 真实 spam 且预测 spam(被抓)
  • FN: 真实 spam 且预测 not-spam(漏报)

所以 TP + FN 一定等于真实 spam 的数量,当前为 6。

复杂度

  • 已有 tp/fn 计数时:O(1)
  • 从示例扫描统计时:O(n) 时间、O(1) 额外空间
常见误区召回率衡量真实正类覆盖率,不是告警可信度。
不是准确率

准确率会计入 TN,而召回率不计 TN/FP。

不是原始计数

仅报‘命中了3个’不完整,必须除以全部真实 spam。

与精确率对照

精确率问:‘预测为正的有多少对?’

召回率问:‘真实正类有多少被抓到?’

图谱连接

召回率从混淆矩阵的真实正类行派生,可与精确率做边界对照。

图谱走向召回率由混淆矩阵派生,后续可与精确率进行边界对比。
混淆矩阵

已实现

召回率

已实现

精确率(对照)

对照读取不同分母

练习

  1. 为什么 7/12 不是召回率?
  2. 在本例里召回率分母是多少,为什么是这个集合?
  3. 计算 e8 后的运行值。
  4. TP + FN = 0 时应如何渲染?
  5. 列出 TPFN 各是什么,分别发生在哪些样本。
最终参考
TP + FN = 3 + 3 = 6, 召回率 3 / 6 = 0.5(50%)。
真实正类样本
e1, e4, e5, e8, e10, e12

图谱连接 : 召回率