§1.2.18

Accuracy/Precision/Recall/F1/AUC/PR 的适用场景?

核心概念

分类模型的评估指标用于衡量模型预测结果的优劣。

  • Accuracy (准确率): 模型预测正确的样本占总样本的比例,是衡量整体性能最直观的指标。
  • Precision (精确率/查准率): 模型预测为正例的样本中,真正是正例的比例。它关注的是预测结果的“准确性”。
  • Recall (召回率/查全率): 所有真实正例的样本中,被模型成功预测为正例的比例。它关注的是对正例的“覆盖能力”。
  • F1-Score: Precision 和 Recall 的调和平均数,用于在两者之间寻求平衡。
  • AUC-ROC: ROC 曲线下的面积,衡量模型在所有可能阈值下区分正负样本的总体“排序能力”。它对类别不平衡不敏感。
  • AUC-PR: PR 曲线下的面积,同样衡量模型的排序能力,但在类别极度不平衡时,比 AUC-ROC 更能真实反映模型在稀有正类上的表现。

原理与推导

评估指标的计算都基于混淆矩阵(Confusion Matrix),它总结了模型在每个类别上的预测表现。对于一个二分类问题,混淆矩阵包含四个基本量:

  • TP (True Positive): 真正例,真实为正,预测也为正。
  • FP (False Positive): 假正例,真实为负,预测为正(Type I Error)。
  • TN (True Negative): 真负例,真实为负,预测也为负。
  • FN (False Negative): 假负例,真实为正,预测为负(Type II Error)。

1. Accuracy (准确率)

  • 数学公式:
Accuracy=TP+TNTP+FP+TN+FN\text{Accuracy} = \frac{TP + TN}{TP + FP + TN + FN}
  • 推导与解释:
    • 分子是所有预测正确的样本数(正例预测对 + 负例预测对)。
    • 分母是总样本数。
    • 直观解释: 模型“猜对”的概率是多少?这个指标在类别均衡的数据集上非常有效。但在类别不平衡时,它会产生误导。例如,99% 的样本是负例,模型即使把所有样本都预测为负例,也能获得 99% 的准确率,但它对正例毫无识别能力。

2. Precision (精确率)

  • 数学公式:
Precision=TPTP+FP\text{Precision} = \frac{TP}{TP + FP}
  • 推导与解释:
    • 分子是真正例。
    • 分母是所有被模型预测为正例的样本数(预测对的正例 + 预测错的正例)。
    • 直观解释: 在所有被你“揪出来”认为是“坏人”的里面,到底有多少是真“坏人”?这个指标衡量的是预测的“纯度”,越高代表模型预测的正例越可信。

3. Recall (召回率)

  • 数学公式:
Recall=TPTP+FN\text{Recall} = \frac{TP}{TP + FN}
  • 推导与解释:
    • 分子是真正例。
    • 分母是所有真实为正例的样本数(预测对的正例 + 预测漏的正例)。
    • 直观解释: 在所有真“坏人”里,你成功“揪出来”了多少?这个指标衡量的是模型的“检出能力”,越高代表模型越不容易漏掉正例。

4. F1-Score

  • 数学公式:
F1-Score=2PrecisionRecallPrecision+Recall=2TP2TP+FP+FN\text{F1-Score} = 2 \cdot \frac{\text{Precision} \cdot \text{Recall}}{\text{Precision} + \text{Recall}} = \frac{2TP}{2TP + FP + FN}
  • 推导与解释:
    • F1-Score 是 Precision 和 Recall 的调和平均数。
    • 为什么用调和平均数? 相比算术平均数,调和平均数对较低的值更敏感。如果 Precision 或 Recall 中有一个非常低,F1-Score 也会被拉得很低。这强制模型在两者之间取得较好的平衡,而不是偏袒某一方。例如,P=1.0, R=0.1,算术平均是 0.55,而调和平均(F1)只有约 0.18,更能反映出模型的短板。

5. ROC 曲线与 AUC-ROC

  • ROC (Receiver Operating Characteristic) 曲线:
    • 横轴:假正例率 (False Positive Rate, FPR) FPR=FPFP+TN\text{FPR} = \frac{FP}{FP + TN} 它表示所有真实负例中,被错误预测为正例的比例。
    • 纵轴:真正例率 (True Positive Rate, TPR),它就是 Recall。 TPR=TPTP+FN\text{TPR} = \frac{TP}{TP + FN}
  • 生成过程:
    1. 模型的预测结果通常是一个概率值(0到1之间)。
    2. 通过从高到低(或从低到高)移动分类阈值(threshold),可以得到一系列的 (FPR, TPR) 坐标点。
    3. 阈值最高时(如1.0),模型非常“苛刻”,几乎不预测正例,(FPR, TPR) 接近 (0, 0)。
    4. 阈值最低时(如0.0),模型非常“宽松”,把所有样本都预测为正例,(FPR, TPR) 接近 (1, 1)。
    5. 将这些点连接起来,就构成了 ROC 曲线。
  • AUC (Area Under the Curve):
    • 几何解释: ROC 曲线下的面积。面积范围在 [0, 1] 之间。
      • AUC = 1: 完美分类器。
      • AUC = 0.5: 随机猜测分类器(对应图中的对角线)。
      • AUC < 0.5: 比随机猜测还差的分类器。
    • 概率解释: AUC 值有一个重要的物理意义:随机从正样本集和负样本集中各抽取一个样本,模型将正样本的预测概率排在负样本之前的概率。这个解释使得 AUC 成为衡量模型整体排序能力的黄金标准。

6. PR 曲线与 AUC-PR

  • PR (Precision-Recall) 曲线:
    • 横轴:Recall (TPR)
    • 纵轴:Precision
  • 生成过程: 与 ROC 曲线类似,通过移动分类阈值,得到一系列 (Recall, Precision) 坐标点,连接成线。
  • AUC-PR:
    • 几何解释: PR 曲线下的面积。
    • 与 AUC-ROC 的关键区别: 在类别极度不平衡的数据集中,负例数量远大于正例(TN 很大)。
      • 在 ROC 曲线中,FPR 的分母是 FP + TN。即使 FP 显著增加,只要 TN 足够大,FPR 的增长也会非常缓慢,导致 ROC 曲线“虚高”,给人一种模型效果很好的错觉。
      • PR 曲线的两个轴(Precision 和 Recall)都只关注与正例(TP, FP, FN)相关的部分,不受海量 TN 的影响。当模型在大量负例中将一些样本错误地预测为正例时,FP 会增加,Precision (TP / (TP + FP)) 会显著下降,PR 曲线会更真实地反映出模型的性能。
    • 基线 (Baseline): 随机猜测模型的 PR 曲线基线是数据集中正例的比例(P / (P+N)),而 ROC 曲线的基线恒为 0.5。

代码实现

以下代码使用 scikit-learn 演示了如何在一个不平衡数据集上计算和可视化这些指标。

python
1import numpy as np
2from sklearn.metrics import (
3 accuracy_score,
4 precision_score,
5 recall_score,
6 f1_score,
7 roc_curve,
8 auc,
9 precision_recall_curve,
10 average_precision_score
11)
12import matplotlib.pyplot as plt
13
14# --- 1. 准备数据 ---
15# 假设这是一个类别极不平衡的场景,例如欺诈检测
16# y_true: 真实的标签 (0: 正常, 1: 欺诈)
17# y_scores: 模型预测为类别 1 的概率/分数
18np.random.seed(42)
19y_true = np.array([0] * 950 + [1] * 50) # 95% 是负例, 5% 是正例
20# 一个还不错的模型的预测分数
21y_scores_good = np.concatenate([
22 np.random.rand(950) * 0.4, # 对大部分负例给出低分
23 np.random.rand(50) * 0.6 + 0.4 # 对大部分正例给出高分
24])
25# 一个糟糕的模型(接近随机猜测)的预测分数
26y_scores_bad = np.random.rand(1000)
27
28# 为了计算 Precision/Recall 等,需要一个确定的阈值来得到预测标签
29threshold = 0.5
30y_pred_good = (y_scores_good > threshold).astype(int)
31
32# --- 2. 计算基础指标 (Accuracy, Precision, Recall, F1) ---
33print("--- 基础指标 (基于阈值=0.5) ---")
34accuracy = accuracy_score(y_true, y_pred_good)
35precision = precision_score(y_true, y_pred_good)
36recall = recall_score(y_true, y_pred_good)
37f1 = f1_score(y_true, y_pred_good)
38
39print(f"Accuracy: {accuracy:.4f}")
40# 为什么Accuracy会产生误导?
41# 如果一个模型把所有样本都预测为0,它的Accuracy也会高达95%,但它毫无用处。
42# 我们的模型Accuracy也很高,但这并不能完全说明它对正例的识别能力。
43print(f"Precision: {precision:.4f}") # 查准率:预测为1的里面,真1的比例
44print(f"Recall: {recall:.4f}") # 查全率:所有真1里面,被找出来的比例
45print(f"F1-Score: {f1:.4f}") # P和R的调和平均
46
47# --- 3. 计算和绘制 ROC 曲线与 AUC ---
48print("\n--- AUC-ROC ---")
49# 为什么用 y_scores 而不是 y_pred?
50# 因为 ROC/PR 曲线是通过改变阈值来评估模型在所有决策点下的表现,所以需要原始的概率分数。
51fpr, tpr, thresholds_roc = roc_curve(y_true, y_scores_good)
52roc_auc = auc(fpr, tpr)
53print(f"AUC-ROC: {roc_auc:.4f}")
54
55# --- 4. 计算和绘制 PR 曲线与 AUC ---
56print("\n--- AUC-PR ---")
57prec, rec, thresholds_pr = precision_recall_curve(y_true, y_scores_good)
58# scikit-learn 中计算 AUC-PR 通常使用 average_precision_score,它在数值上更稳定
59pr_auc = average_precision_score(y_true, y_scores_good)
60print(f"AUC-PR (Average Precision): {pr_auc:.4f}")
61
62# --- 5. 可视化对比 ---
63plt.figure(figsize=(14, 6))
64plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
65plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
66
67# 绘制 ROC 曲线
68plt.subplot(1, 2, 1)
69plt.plot(fpr, tpr, color='darkorange', lw=2, label=f'ROC curve (area = {roc_auc:.2f})')
70plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--') # 随机猜测线
71plt.xlim([0.0, 1.0])
72plt.ylim([0.0, 1.05])
73plt.xlabel('False Positive Rate (FPR)')
74plt.ylabel('True Positive Rate (TPR / Recall)')
75plt.title('ROC 曲线')
76plt.legend(loc="lower right")
77
78# 绘制 PR 曲线
79plt.subplot(1, 2, 2)
80# 为什么PR曲线的基线是正样本比例?
81# 因为一个随机模型,无论召回率如何变化,其精确率都应该维持在正样本比例附近。
82baseline = np.sum(y_true) / len(y_true)
83plt.plot(rec, prec, color='darkorange', lw=2, label=f'PR curve (area = {pr_auc:.2f})')
84plt.plot([0, 1], [baseline, baseline], color='navy', lw=2, linestyle='--', label=f'Baseline (P={baseline:.2f})')
85plt.xlim([0.0, 1.0])
86plt.ylim([0.0, 1.05])
87plt.xlabel('Recall')
88plt.ylabel('Precision')
89plt.title('PR 曲线 (类别不平衡时更具信息量)')
90plt.legend(loc="lower left")
91
92plt.tight_layout()
93plt.show()

工程实践

| 指标 | 适用场景 | 经验法则与权衡 | | :--- | :--- | :--- | | Accuracy | 类别分布均衡的数据集,且所有类别的预测错误代价相近。例如,CIFAR-10 图像分类。 | - 优点: 直观,易于理解。 <br> - 缺点: 在类别不平衡时极具误导性。一个预测所有样本为多数类的“惰性”模型可以获得很高的准确率。 | | Precision | 对假正例 (FP) 惩罚很高的场景,即“宁可放过,不可杀错”。 | - 场景: 垃圾邮件过滤(将重要邮件误判为垃圾的代价很高)、股票预测(错误预测上涨导致买入的代价很高)。 <br> - 权衡: 提高 Precision 往往以牺牲 Recall 为代价。可以通过提高分类阈值来实现,但这会漏掉更多正例。 | | Recall | 对假负例 (FN) 惩罚很高的场景,即“宁可杀错,不可放过”。 | - 场景: 传染病筛查(漏诊一个病人的社会代价很高)、金融欺诈检测(漏掉一笔欺诈交易的损失很大)。 <br> - 权衡: 提高 Recall 往往以牺牲 Precision 为代价。可以通过降低分类阈值来实现,但这会引入更多误报。 | | F1-Score | 需要在 Precision 和 Recall 之间取得平衡的场景,特别是类别不平衡时。 | - 场景: 大多数需要综合考虑 P 和 R 的业务场景,如产品推荐、文本分类等。 <br> - 变体: F-beta score (Fβ=(1+β2)PR(β2P)+RF_\beta = (1+\beta^2) \frac{P \cdot R}{(\beta^2 \cdot P) + R}),当 β>1\beta > 1 时更看重 Recall,当 β<1\beta < 1 时更看重 Precision。 | | AUC-ROC | 不关心具体的决策阈值,只关心模型整体的排序能力。适合作为模型对比和调参的主要指标。 | - 优点: 阈值无关,对类别不平衡不敏感(见误区),表现稳定。 <br> - 缺点: 在极度不平衡数据下,其“不敏感”的特性可能掩盖模型在少数类上的表现不佳问题,显得过于乐观。 | | AUC-PR | 类别极度不平衡,且更关注正例(少数类)的识别效果。 | - 场景: 广告点击率预测 (CTR)、搜索引擎查询相关性、基因序列分析。在这些场景,正例非常稀疏,我们更关心模型能否在海量负例中准确找出少数正例。 <br> - 优点: 在类别不平衡时比 AUC-ROC 更具信息量和区分度。 |

选择决策阈值: 在实际应用中,我们不能只交付一个模型,还需要一个决策阈值。这个阈值可以根据 ROC 或 PR 曲线来选择。例如,业务方要求 Recall 必须达到 90% 以上,我们就可以在 PR 曲线上找到满足 Recall > 0.9 的所有点中,Precision 最高的那个点对应的阈值作为最终决策点。

常见误区与边界情况

  1. Accuracy 陷阱: 这是最常见的误区。在任何不平衡数据集上,都不要孤立地使用 Accuracy 来评估模型。务必结合 Precision, Recall, F1 或 AUC-PR 来综合判断。
  2. AUC-ROC 对类别不平衡“免疫”的误解: AUC-ROC 对类别不平衡“不敏感”,而不是“免疫”。它的不敏感是因为 FPR 的分母包含海量的 TN,使得 FPR 增长缓慢,导致 AUC 值虚高。这在评估上是“钝感”的,可能掩盖问题,而 AUC-PR 在这种情况下更“敏感”,更能暴露模型在正例上的性能短板。
  3. AUC 值高不代表模型一定好用: AUC 衡量的是整体排序能力,但在特定应用场景下,我们可能只关心曲线的某个特定部分。例如,在要求高 Precision 的场景,一个模型可能总体 AUC 稍低,但在高 Precision 区间(PR 曲线的左侧部分)表现更好,那么它可能是一个更优的选择。
  4. 混淆多分类中的 Micro vs. Macro Average:
    • Macro-Average (宏平均): 对每个类别独立计算指标,然后取算术平均。它平等对待所有类别,无论类别样本量多少。如果小类别性能很重要,应关注此指标。
    • Micro-Average (微平均): 将所有类别的 TP, FP, FN 汇总后,再计算一次指标。它受样本量大的类别主导。在多分类问题中,Micro-Precision, Micro-Recall, Micro-F1 和 Accuracy 的值是完全相等的。
    • Weighted-Average (加权平均): 类似宏平均,但在平均时根据每个类别的样本数量进行加权。是 Macro 和 Micro 的折衷。
  5. PR 曲线的形状: PR 曲线通常不是平滑下降的,可能出现“锯齿”或“波浪”。这是因为随着阈值降低,Recall 增加,但 Precision 可能会因为某个样本的预测翻转而时升时降。这是正常现象。
相关题目