精确率与召回率:Precision、Recall、F1-score 计算与应用

好,咱们进入第三节。前两节讲了混淆矩阵——那是所有分类指标的祖宗。现在要聊的 Precision、Recall 和 F1-score,就是从混淆矩阵里蒸馏出来的三个核心指标。我刚开始做 NLP 时,老板让我看模型效果,用准确率(Accuracy)就够了。但后来遇到样本极不均衡的 case——比如信用卡欺诈检测,正样本才 0.1%。这时候 Accuracy 基本没用,必须靠 Precision 和 Recall 来把脉。

精确率(Precision)—— 宁缺毋滥

Precision 回答的是:“你模型说是正例的那些东西,到底有多少是真货?”

Precision = TP / (TP + FP)

举个例子:垃圾邮件过滤。模型标记了 100 封垃圾邮件,其中 90 封是真垃圾,10 封是普通邮件被误杀。那么 Precision = 90 / 100 = 0.9。

什么时候看重它?

  • 假阳性代价很高的场景。比如自动驾驶判“前方有障碍物”,宁可漏判也别误判。
  • 推荐系统:给用户推一堆烂商品,用户就跑了。

我曾经踩过一个坑:做医疗影像识别,病灶区域只占图像 1%。模型训练完 Precision 特别高,0.97。我一看 TP 很多,FP 很少,美滋滋。结果一查,模型几乎把整张图都判为“正常”——因为它害怕误报,索性不报。Precision 高但 Recall 极低。所以别只看一个数。

召回率(Recall)—— 宁可错杀一千

Recall 回答的是:“模型中所有真的正例,你捞回来了多少?”

Recall = TP / (TP + FN)

还是邮件过滤:训练集里有 200 封真垃圾邮件,模型只识别出 70 封,剩下 130 封混进了收件箱。那么 Recall = 70 / 200 = 0.35。

什么时候抓 Recall?

  • 漏报代价极高的场景。比如癌症筛查、金融反欺诈——宁可先拉警报,再人工复核。
  • 安全监控:倒车雷达不能漏掉一个行人。
指标 关注点 典型场景
Precision 预测为正例的样本里有多少是真的 搜索结果质量、推荐准确率
Recall 真实正例被找回来的比例 疾病筛查、欺诈检测
F1-score Precision 和 Recall 的调和平均 两者都要均衡的场景

F1-score —— 和稀泥的艺术

Precision 和 Recall 通常是此消彼长的。你提高 Recall,可能会把一堆 FP 也捞进来,Precision 就降了。反之亦然。这时候需要个综合指标——F1-score。

F1 = 2 * (Precision * Recall) / (Precision + Recall)

其实就是两者的调和平均。注意它更偏向较小的那个值。比如说 Precision=0.9, Recall=0.1,算下来 F1≈0.18,完美反映了模型偏科严重。

我个人的习惯:在分类任务里,如果没特别需求,我第一眼先看 F1。它像一张成绩单的总分,虽然不能替代单科分析,但能让你快速定调:这个模型是不是“跛脚鸭”。

手动算一遍,比看一百遍强

给你一个真实的混淆矩阵,咱们一块儿算。

混淆矩阵(二分类,阈值 0.5):

             预测正类    预测负类
真实正类       120        30
真实负类        20        230

TP=120, FN=30, FP=20, TN=230

Precision = 120 / (120 + 20) = 120 / 140 ≈ 0.857
Recall    = 120 / (120 + 30) = 120 / 150 = 0.8
F1        = 2 * (0.857 * 0.8) / (0.857 + 0.8) = 1.3712 / 1.657 ≈ 0.828

你看,Precision 和 Recall 本来差 0.057,F1 落在中间偏 Recall 一边——因为调和平均对较小的值更敏感。

代码里怎么算?

用 scikit-learn 一行搞定。但我建议你至少手写一次,理解公式。

from sklearn.metrics import precision_score, recall_score, f1_score

y_true = [1, 0, 1, 1, 0, 0]
y_pred = [1, 0, 0, 1, 0, 1]

print("Precision:", precision_score(y_true, y_pred))
print("Recall:", recall_score(y_true, y_pred))
print("F1:", f1_score(y_true, y_pred))

输出类似:Precision=0.6667, Recall=0.6667, F1=0.6667。这个例子正负例均衡,所以三个值相等。实际中很少见。

重要提醒:Precision 和 Recall 跟阈值强相关。你把分类阈值从 0.5 调到 0.3,Recall 会升,Precision 会降。调试模型时,建议画 Precision-Recall 曲线,找到最佳平衡点。

SVG 图解:从混淆矩阵到三个指标

下面这张图把三者关系串起来了。你盯着看一分钟,逻辑就很清晰了。

混淆矩阵 → 核心评估指标 TP 真正例 FN 假负例 FP 假正例 TN 真负例 TP + FP TP + FN Precision TP/(TP+FP) Recall TP/(TP+FN) F1-score 2·P·R/(P+R) 应用策略总结 • 假阳性成本高 → 盯 Precision(例如:搜索结果排序) • 假阴性成本高 → 盯 Recall(例如:癌症筛查) • 两者均衡需求 → 盯 F1(例如:通用分类任务)

怎么选?说几个场景你就懂了

场景一:搜索引擎

  • 用户搜“苹果”,你返回了 iPhone、苹果电脑、苹果水果。如果混进去一个“苹果醋”,用户觉得不精准。所以 Precision 是关键。
  • Recall 也重要吗?如果只召回 30% 的相关页面,用户搜不到想要的东西。但搜索引擎通常会先保证 Precision 够高,再通过大量结果页弥补 Recall。

场景二:反欺诈

  • 银行风控系统。漏过一笔欺诈交易可能损失几十万。所以 Recall 得极高(比如 99%),哪怕误判很多正常交易让人工复核,也划算。此时 Precision 可以低。

场景三:通用文本分类

  • 比如情感分析,正负样本差不多。这时候用 F1 最稳妥,既能反映模型是否偏科,又不受样本量影响。

一句话:别只看 Accuracy。 如果你还没把 Precision、Recall、F1 打印出来,赶紧加上。我见过太多 demo 因为只看 Accuracy 而翻车了。你想想,一个 99% 准确率的模型,放到欺诈检测里可能比瞎猜还差——因为全是负样本,全判负就 99% 准确率,但一个欺诈都没抓到。