ROC-AUC 为 0.97、精确率为 9%:基准率的数学
通过一个阳性率为 1% 的检测器,逐步把阈值转换为 ROC 和精确率-召回率点,并为 30 个告警的审核预算选择运行点。
这里有一个 ROC-AUC 为 的检测器。在一个包含 1,000 行、其中 10 行为阳性的测试集上,它的 90% 召回率阈值会发送 99 个告警。其中 9 个是真阳性,90 个是假阳性。
这两句话描述的是同一个分数排序。第一句话奖励的是:在所有阈值上,阳性示例通常排在阴性示例之上的程度。第二句话描述的是:在一个阈值下,人们实际需要审核的队列。在阳性样本稀少时,这两者可能代表截然不同的运营故事。
本课通过一个完整的合成示例来构建这种差距。你将把阈值计数转换为 ROC 和精确率-召回率坐标,计算 ROC-AUC 和平均精确率,展示患病率如何改变精确率却不改变 ROC 点,并选择一个适合 30 个告警审核预算的阈值。
一个阈值产生 99 个告警
想象一个为每一行分配 到 之间分数的模型。这个集合包含 10 个阳性和 990 个阴性,因此患病率为
在阈值 下,所有分数大于或等于 的行都会成为告警。所得混淆矩阵如下:
| 预测 | 实际为阳性 | 实际为阴性 | 总计 |
|---|---|---|---|
| 告警 | TP = 9 | FP = 90 | 99 |
| 无告警 | FN = 1 | TN = 900 | 901 |
| 总计 | 10 | 990 | 1,000 |
这个阈值捕获了 10 个阳性中的 9 个。听起来很强,直到把审核队列算进去:99 个告警中有 90 个是假阳性。模型并没有自相矛盾。召回率和精确率回答的是不同的问题。
召回率问:“在所有实际阳性中,告警系统捕获了多大比例?”精确率问:“在所有告警中,有多大比例为阳性?”在这个运行点,答案分别是 和 。
混淆矩阵提供两套坐标系
ROC 曲线绘制真阳性率(也就是召回率)与假阳性率的关系:
精确率-召回率曲线绘制精确率与召回率的关系。对于 阈值,同一个混淆矩阵给出
以及 。因此它的 ROC 坐标是 。从精确率-召回率的角度看,
与召回率 合在一起,就得到精确率-召回率坐标 。
现在在同一组排序分数中扫描六个阈值。计数是累积的:降低阈值会同时把阳性和阴性示例加入告警集合。
| 阈值 | TP | FP | 告警数 | 召回率 | FPR | 精确率 |
|---|---|---|---|---|---|---|
| ∞ | 0 | 0 | 0 | 0.0 | 0.0 | 1.000* |
| 0.95 | 4 | 1 | 5 | 0.4 | 0.0010 | 0.800 |
| 0.75 | 8 | 20 | 28 | 0.8 | 0.0202 | 0.286 |
| 0.55 | 9 | 90 | 99 | 0.9 | 0.0909 | 0.091 |
| 0.35 | 10 | 290 | 300 | 1.0 | 0.2929 | 0.033 |
| 0.10 | 10 | 990 | 1,000 | 1.0 | 1.0 | 0.010 |
没有预测为阳性的样本时,精确率没有定义。数值 1 是绘制这条曲线时采用的约定起点;它并不证明分类器有用。
scikit-learn 的精确率-召回率曲线文档使用相同的定义,并包含完整曲线的端点。它的阈值是不同的分数值;真实数据通常会提供比这个简化示例多得多的点。
橙色点在两个面板中都表示阈值 0.75。坐标发生变化,而底层混淆矩阵仍为 8 个真阳性、20 个假阳性、2 个假阴性和 970 个真阴性。
ROC 把 90 个假警报压缩成 9.1%
在阈值 下,FPR 的分母包含全部 990 个阴性。90 个假阳性最终只有 的 FPR。精确率则把同样的 90 个假阳性与审核者会看到的 9 个真阳性放在一起,得到 的精确率。
这就是算术中的基准率效应。一个非常大的阴性类别中的小比例,可能超过一个很小的阳性类别中的大多数。ROC 点是有效的,但既不包含告警纯度,也不包含队列大小。
ROC-AUC 总结的是整条 ROC 曲线,而不是某个阈值。对六个点应用梯形法则得到
scikit-learn 将 ROC-AUC 定义为根据预测分数计算的 ROC 曲线下面积。对于二元分类器,它也可以理解为:随机选出的阳性获得高于随机选出的阴性的分数的概率,并按通常方式处理平局。这种排序解释没有说明阈值、告警数和审核成本。
ICML 2006 中 Jesse Davis 和 Mark Goadrich 的分析展示了这种区别为何会在类别不平衡时更加明显。对于固定数据集,ROC 曲线和精确率-召回率曲线在数学上相关,但大的阴性分母可能让 ROC 图在视觉上显得过于乐观。他们还展示了在精确率-召回率空间中使用直线插值通常是不正确的;观测运行点之间的曲线不是装饰性的线段。
对于这次离散扫描,不插值的平均精确率为
这远高于这种患病率下无信息排序的 精确率。AP 仍然总结的是排序;人员配置决策需要一个运行点。scikit-learn 的平均精确率文档使用上面的召回率加权求和,并警告梯形插值可能过于乐观。
患病率改变精确率,却不改变 ROC 点
将患病率写作 。如果一个运行点的真阳性率为 、假阳性率为 ,那么在一个大型总体中:
- 预期的阳性告警占比为 ;
- 预期的假告警占比为 。
精确率是用阳性告警占比除以所有告警所得的结果:
使用 阈值,此时 ,。保持这些条件率不变,得到:
| 患病率 | 预期精确率 |
|---|---|
| 0.1% | 3.8% |
| 1% | 28.6% |
| 10% | 81.5% |
三个行中的 ROC 坐标都保持在 附近,因为 TPR 以阳性为条件,而 FPR 以阴性为条件。精确率坐标发生巨大变化,因为它的分母混合了真告警和假告警。
这个计算假设 TPR 和 FPR 能不变地迁移到新总体。迁移必须经过测试:分数分布、标签或数据质量的变化都可能移动这两个率。在代表预期用途的数据上估计运行点,并把阈值选择与用于最终性能报告的未触碰样本分开。在校准预测概率时,同样的人口纪律也很重要。
30 个审核名额选择一个阈值
假设团队每 1,000 行最多能审核 30 个告警,并要求至少 的召回率。决策规则现在很明确:
召回率要求是
阈值 产生 5 个告警,符合队列容量,但其 的召回率未达到要求。阈值 产生 28 个告警并达到 的召回率,因此符合条件。阈值 达到 的召回率,却产生 99 个告警,超过可用容量的三倍。
因此,对于这些行和这些约束,选定的运行点是 。它的精确率为 :审核者应该预计 28 个告警中大约有 20 个是假告警,而不是仅仅引用 ROC-AUC 所带来的安慰。
容量也可以写成假阳性限额。一旦最少真阳性数确定,预算 至多允许
当 且有 8 个真阳性时,限额是 22 个假阳性。阈值 产生 20 个。这种转换把模型指标连接到实际资源约束,而不是把普遍的重要性赋予某一条曲线。
重现扫描和预算门槛
下面的 NumPy 程序计算两条曲线、ROC-AUC、不插值的平均精确率以及符合条件的阈值。数组保存每个递减阈值下的累积计数。
import numpy as np
thresholds = np.array([np.inf, 0.95, 0.75, 0.55, 0.35, 0.10])
tp = np.array([0, 4, 8, 9, 10, 10])
fp = np.array([0, 1, 20, 90, 290, 990])
positives, negatives = 10, 990
recall = tp / positives
fpr = fp / negatives
precision = np.divide(
tp,
tp + fp,
out=np.ones_like(tp, dtype=float),
where=(tp + fp) > 0,
)
roc_auc = np.trapezoid(recall, fpr)
average_precision = np.sum(np.diff(recall) * precision[1:])
budget = 30
recall_floor = 0.75
alerts = tp + fp
eligible = (alerts <= budget) & (recall >= recall_floor)
print(f"ROC-AUC: {roc_auc:.6f}")
print(f"average precision: {average_precision:.6f}")
print("eligible thresholds:", thresholds[eligible])
输出是:
ROC-AUC: 0.970808
average precision: 0.446710
eligible thresholds: [0.75]
如果有多个阈值符合条件,就根据声明过的次要目标来选择,例如在预算内取得最高召回率,或最低预期成本,而不是选择让图表看起来最好的点。如果分数存在平局,阈值上的所有行会一起移动;容量目标可能无法精确达到。
没有阈值符合条件时
把同一个预算收紧为 25 个告警,同时要求 的召回率。阈值 捕获 8 个阳性,却产生 28 个告警。更高的阈值符合队列容量,却只能捕获 4 个阳性。扫描中的任何一行都无法同时满足两个约束。
这个结果具有可操作性。移动阈值无法创造出缺失的运行点。团队必须改善排序、增加第二阶段过滤器、提高审核容量,或接受不同的召回率要求。在真实系统中,假阳性和假阴性的成本也可能不相等,因此成本函数或决策分析可以取代简单的队列上限。
更广泛的测量原则既是当前的,也是数学上的。NIST AI 800-3强调,评估者必须选择适合目标和数据的性能量与不确定性方法;不存在适用于每次评估的单一公式。在这里,相关量并不是抽象的“AUC”,而是一个具有明确患病率和真实审核预算的阈值下的召回率、精确率和告警量。