图像异常检测评估指标
混淆矩阵
![混淆矩阵](https://raw.githubusercontent.com/ValoraY/blog-imgs/main/img/202406241938192.png)
混淆矩阵包括4个用于衡量分类算法性能的基本数值
四个字母代表的含义是:P(Positive)
代表算法将样本预测为正类,N(Negative)
代表算法将样本预测为负类;T(True)
代表算法对该样本的预测正确(即该样本的预测类别和实际类别一致),F(False)
代表算法对该样本的预测错误(即该样本的预测类别和实际类别相反)
TP (True Positive)
:预测为正类,实际也为正类的样本数TN (True Negative)
:预测为负类,实际也为负类的样本数FP (False Positive)
:预测为正类,实际为负类的样本数FN (False Negative)
:预测为负类,实际为正类的样本数
评估单一阈值下算法的分类性能
首先利用训练集拟合好分类算法,然后在验证集上推理得到上述的TP, TN, FP
和
FN
,进而可以计算该分类算法的性能评估指标——准确率(accuracy
)、精确率(precision
)、召回率(recall
)和
F1-Score
accuracy
指标名称:准确率
定义:正确分类的样本(
TP
)占所有样本(TP+TN+FP+FN
)的比例(本文所有这些评估指标都是根据验证集进行计算的)公式:
\[ Accuracy=\frac{(TP+TN)}{(TP+FP+FN+TN)} \]
用准确率来评估可能存在一些问题:
类别不平衡问题:当数据集中的类别分布不均衡时,准确率可能会产生误导。例如,如果一个数据集中99%的样本属于一个类别,1%的样本属于另一个类别,那么一个简单的总是预测为多数类别的模型也会有99%的准确率,但实际上这个模型对于少数类别的预测效果非常差。
忽视错误分类的不同重要性:准确率无法区分不同类型的错误分类,
accuracy
的分子代表正确预测的样本数,包括TP
和TN
,与之相对应的错误率是error = 1-accuracy
,它的分子就包括FP
和FN
,在医学诊断中,FP
和FN
分别代表误诊和漏诊,而误诊和漏诊的影响可能完全不同,但准确率不会反映出这些错误分类的不同重要性。
1 | import numpy as np |
针对正负样本不平衡的数据,可以引入平均准确率进行更合理的评估。
average accuracy
- 指标名称:平均准确率
- 定义:对各个类别分别计算准确率,然后求平均
- 公式:
- 类别
i
的准确率
\[ \text{Accuracy}_i=\frac{\text{True Positives}_i+\text{True Negatives}_i}{\text{Total Samples}_i} \]
- True Positives\(_i\) 是 category \(i\) 预测正确的正例数量
- True Negatives\(_i\) 是 category \(i\) 预测正确的负例数量
- Total Samples\(_i\) 是 category \(i\) 的总样本数(包含正例和负例)
- 计算平均准确率
\[ averageAccuracy=\frac{\sum accuracy_i}n \]
1 | # 平均准确率 |
precision
指标名称:精确率、查准率
定义:正确分类的正样本(
TP
)占所有预测正样本(TP+FP
)的比例公式:
\[ Precision=\frac{TP}{TP+FP} \]
- 意义:==衡量模型在正类预测上的准确率==(注意是预测正类的准确率!!!),如在垃圾邮件过滤中,精确率高(
FP小
)意味着很少将正常邮件误判为垃圾邮件。
1 | # 精确率 |
recall
- 指标名称:召回率、查全率、真正率(
TPR
) - 定义:正确分类的正样本(
TP
)占所有实际正样本(TP+FN
)的比例 - 公式:
\[ \mathrm{Re}call=\frac{TP}{TP+FN} \]
- 意义:召回率衡量的是模型在检测所有实际为正类的样本时的有效性,==或者说对正类样本的查全率==(注意是正类样本的查全率!!!)。高召回率意味着模型能够识别大多数的正类样本,漏检情况很少。
1 | # 召回率 |
==Precision
和
Recall
都适合用于类别不平衡的验证集,因为在二者的公式中都没有考虑True Negatives (TN)
,只专注于正确判断正样本,因此,就算验证集中负样本的数目远大于正样本,Recall
及 Precision
仍是有效的参考指标。反之,FPR
则会受到影响,当我们负样本很多,模型若全部预测为负样本,会得到FPR = 0
,但这样的模型并非好的模型,所以ROC curve
比较容易受到不平衡的验证集影响。==
![precision和recall的定义](https://raw.githubusercontent.com/ValoraY/blog-imgs/main/img/202406251045981.png)
F1 score
- 定义:针对特定某个门槛值的
Recall
及Precision
所计算出来的调和平均数(precision
和recall
的重要程度相同) - 公式:
\[ F1Score=\frac{2^*precision^*recall}{precision+recall} \]
PR Curve
指标全称:
Precision Recall Curve
定义:纵坐标为精准率
Precision
,横坐标为召回率Recall
意义:
PR
曲线是在不同阈值下绘制的,和下文的ROC
曲线类似,都用于反映模型在不同阈值下的整体表现,PR
曲线越往右上角凸起,则代表整体更好的模型表现,因为,反之越平则代表模型性能越差。==如何选取最优阈值?==
==PR曲线是通过在各个阈值下计算精确率(
Precision
)和召回率(Recall
)来绘制的,要确定最佳阈值,可以:==- ==法一:计算不同阈值下的
F1 Score
,选择使F1 Score
最大的阈值。== - ==法二:==
- ==根据实际应用对Precision和Recall的不同重视程度,赋予二者不同的权重,计算
Fβ-score
,选择使Fβ-score
最大的阈值。== - ==Fβ-score是准确Precision和Recall的加权调和平均值,该
β
参数表示召回率重要性与精确度重要性的比率,β>1
会给recall
更多的权重,β<1
会给precision
更多的权重。例如β=2
代表recall
的重要性是precision
的2倍,β=0.5
则刚好相反。==
- ==根据实际应用对Precision和Recall的不同重视程度,赋予二者不同的权重,计算
- ==法一:计算不同阈值下的
1 | # Precision-Recall曲线和AU-PR |
1 | # F1 Score和F-beta Score最佳阈值 |
AU-PR
- 指标全称:
Area under the Precision-Recall Curve
PR
曲线的AUC
面积计算公式为:
\[ \sum_n(R_n-R_{n-1})P_n \]
1 | au_pr = auc(recalls, precisions) |
AP
- 指标名称:Average Precision
- 定义:各阈值下精确率的加权平均值,权重是召回率的变化
- 公式:
\[ \mathrm{AP}=\sum_n(R_n-R_{n-1})P_n \]
\(P_n{:}\)Precision at the nth threshold
\(R_n{:}\) Recall at the nth threshold
- 意义:将precision-recall curve 总结成各阈值下精确率的加权平均,更关注模型的精确率
AR
- 指标名称:Average Recall
- 定义:各阈值下召回率的加权平均值,权重是精确率的变化
- 意义:这是和AP对称的公式,不常用,适用于强调召回率的场景
- 公式:
\[ \text{AR}=\sum_n(P_n-P_{n-1})R_n \]
评估不同阈值下算法的分类性能
![TPR和FPR的定义](https://raw.githubusercontent.com/ValoraY/blog-imgs/main/img/202406251045347.png)
TPR
- 指标名称:真正率,
True Positive Rate
,召回率、查全率,Sensitivity
- 定义:所有真实类别为1的样本中,预测类别为1的比例
- 公式(TP除以其所在的列和):
\[ TPR=\frac{TP}{TP+FN} \]
FPR
指标名称:假正率,
False Positive Rate
,误诊率,(1-Specificity
)定义:所有真实类别为0的样本中,预测类别为1的比例
公式(
FP
除以其所在的列和): \[ FPR=\frac{FP}{FP+TN} \]
FNR
- 指标名称:
False Negative Rate
,漏诊率 - 定义:所有真实类别为1的样本中,预测类别为0的比例
- 公式:
\[ FNR=\frac{FN}{TP+FN} \]
ROC Curve
指标名称:
Receiver Operating Characteristic Curve
定义:纵坐标是真正率TPR,横坐标是假正率
FPR
如何画ROC曲线?
二分类模型的输出是预测样本为正例的概率,而
ROC
曲线正是通过不断移动分类器的“阈值”来生成曲线上的一组关键点的。ROC曲线的绘制步骤如下:
- 假设已经得出一系列样本被划分为正类的概率
Score
值,按照大小排序。 - 从高到低,依次将“
Score
”值作为阈值threshold
,当测试样本属于正样本的概率大于或等于这个threshold
时,我们认为它为正样本,否则为负样本。举例来说,对于某个样本,其“Score
”值为0.6,那么“Score
”值大于等于0.6的样本都被认为是正样本,而其他样本则都认为是负样本。 - 每次选取一个不同的
threshold
,得到一组FPR
和TPR
,以FPR
值为横坐标和TPR
值为纵坐标,即ROC
曲线上的一点。 - 根据3中的每个坐标点,画图。
举例如下:
假设验证集样本的预测结果如下表,图中共有20个验证集样本,“
Class
”一栏表示每个验证集样本真正的标签(p
表示正样本,n
表示负样本),“Score
”表示每个验证集样本属于正样本的概率。接下来,我们从高到低,依次将“
Score
”值作为阈值threshold
,当测试样本属于正样本的概率大于或等于这个threshold
时,我们认为它为正样本,否则为负样本。从第一个样本开始,设该样本的Score
值为阈值,则该样本及之后的样本(均比该样本概率值小)判为负样本,即所有样本判为全负,计算得TPR=FPR=0
,即ROC
曲线(0,0)点;再选择第二个样本点的Score
作为阈值,大于等于该阈值的样本(在该样本之前)判为正样本,小于该阈值的判为负样本,计算TPR
和FRP
,可在ROC
图画出该点。举例来说,对于图中的第4个样本,其“
Score
”值为0.6,那么样本1,2,3,4都被认为是正样本,因为它们的“Score
”值都大于等于0.6,而其他样本则都认为是负样本。每次选取一个不同的threshold,我们就可以得到一组FPR
和TPR
,即ROC
曲线上的一点。这样一来,我们一共得到了20组FPR
和TPR
的值,将它们画在ROC
曲线的结果如下图:1
2
3
4
5
6
7
8
9
10
11
12# ROC曲线和AUC
fpr, tpr, roc_thresholds = roc_curve(y_true, y_scores)
plt.figure()
plt.plot(fpr, tpr, label='ROC Curve')
plt.plot([0, 1], [0, 1], 'k--', label='Random Classifier')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC Curve')
plt.legend()
plt.show()
roc_auc = auc(fpr, tpr)
print(f'AUC: {roc_auc:.2f}')- 假设已经得出一系列样本被划分为正类的概率
意义:(1) 利用
ROC
曲线比较不同模型,进而选择最佳模型首先,了解一下
ROC
曲线图上很重要的四个点:( 0 , 1 )
,即FPR=0, TPR=1
,这意味着FN(False Negative)=0,并且FP(False Positive)=0
。代表这是一个完美的分类器,它将所有的样本都正确分类。( 1 , 0 )
,即FPR=1,TPR=0
,意味着这是一个最糟糕的分类器,因为它成功避开了所有的正确答案。( 0 , 0 )
,即FPR=TPR=0
,即FP(False Positive)=TP(True Positive)=0
,代表该分类器预测所有的样本都为负样本(Negative
)。( 1 , 1 )
,即FPR=TPR=1
,代表分类器预测所有的样本都为正样本。
从上面给出的四个点可以发现:
ROC
曲线图中,越靠近(0,1)的点对应的模型分类性能越好- 此外,注意同一条
ROC
曲线图中的点对应的模型,它们的不同之处仅仅是在分类时选用的阈值(Threshold
)不同,这里的阈值代表样本被预测为正类的概率值。
其次,如何在不同模型之间选择最优模型?=>基于
AUC
值不同模型对应的
ROC
曲线中,AUC
值大的模型性能相对较好。当
AUC
值近似相等时,并不代表两个模型的分类性能也相等。有两种情况:第一种是ROC
曲线之间没有交点;第二种是ROC
曲线之间存在交点。(1)
ROC
曲线之间没有交点如下图所示,A,B,C三个模型对应的
ROC
曲线之间交点,且AUC
值是不相等的,此时明显更靠近( 0 , 1 )
点的A模型的分类性能会更好。(2)
ROC
曲线之间存在交点如下图所示,模型A、B对应的
ROC
曲线相交却AUC
值相等,此时就需要具体问题具体分析:当需要高TPR
值时,A模型好过B;当需要低FPR
值时,B模型好过A。
==意义:(2) 同一模型中如何选择最优阈值?==
==已知:在同一条ROC曲线上,越靠近( 0 , 1 ) 的坐标点对应的模型性能越好,因为此时模型具有较高的真正率和较低的假正率。那么我们如何定量地从一条ROC曲线上找到这个最优的点呢?==
==
Youden's J
统计量:==Youden index
(又称Youden's J statistic
)经常应用于ROC
曲线的分析。ROC
曲线上的每个点根据不同阈值会各自算出这项指标,然后我们把Youden Index
数值最大的那个点视为最佳阈值。Youden index
(以J
表示)的计算公式如下: \[ J=\frac{\mathrm{true~positives}}{\mathrm{true~positives}+\mathrm{false~negatives}}+\frac{\mathrm{true~negatives}}{\mathrm{true~negatives}+\mathrm{false~positives}}-1 \] 用ROC
曲线上的指标来呈现的话,正是Y 轴
减去X 轴
数据: \[ J = Sensitivity+Specificity−1 = TPR - FPR \]Youden Index
亦存在图形上的意义,它代表从ROC
上某一点到45 度完全乱猜线
之间的垂直距离,这个垂直距离最大的点,可以视为ROC
曲线的最佳阈值。如下图示,由于45 度线代表TPR = FPR
,所以45 度线到ROC
线上某点的垂直距离可以用TPR - FPR
计算,此数值也正是Youden index
:1
2
3
4
5
6# Youden's J统计量最佳阈值
J = tpr - fpr
best_J_index = np.argmax(J)
best_J_threshold = roc_thresholds[best_J_index]
print(f'Best Youden\'s J Threshold: {best_J_threshold:.2f}')
print(f'Best Youden\'s J Statistic: {J[best_J_index]:.2f}')优点
兼顾正例和负例的权衡。因为
TPR
聚焦于正例,FPR
聚焦于与负例,使其成为一个比较均衡的评估方法。==
ROC
曲线选用的两个指标,\(TPR=\frac{TP}{P}=\frac{TP}{TP+FN},FPR=\frac{FP}{N}=\frac{FP}{FP+TN}\),都不依赖于具体的类别分布(类别分布: 正负类的数量比例)。因为TPR
用到的TP
和FN
同属P
列,FPR
用到的FP
和TN
同属N
列,所以即使P
或N
的整体数量发生了改变,也不会影响到另一列。也就是说,即使正例与负例的比例发生了很大变化,ROC
曲线也不会产生大的变化,而像Precision
使用的TP
和FP
就分属两列,则易受类别分布改变的影响。==参考文献[1]中举了个例子,负例增加了10倍,ROC
曲线没有改变,而PR
曲线则变了很多。作者认为这是ROC
曲线的优点,即具有鲁棒性,在类别分布发生明显改变的情况下依然能客观地识别出较好的分类器。
缺点
- 上文提到
ROC
曲线的优点是不会随着类别分布的改变而改变,但这在某种程度上也是其缺点。因为负例N
增加了很多,而曲线却没变,这等于产生了大量FP
。如果特定应用主要关注正类预测的准确率,也就是Precision
的话,这就不可接受了。 - ==在类别不平衡的背景下,负例的数目众多致使FPR的增长不明显,导致ROC曲线呈现一个过分乐观的效果估计==。
ROC
曲线的横轴采用FPR
,根据\(FPR=\frac{FP}N=\frac{FP}{FP+TN}\),即使FP
大量增长,如果负例过多(N
过大),也可能导致FPR
增长不明显,导致ROC
曲线显得过分乐观。举个例子,假设一个数据集有正例20,负例10000,开始时有20个负例被错判,\(FPR=\frac{20}{20+9980}=0.002\),接着又有20个负例错判,\(FPR_{2}=\frac{40}{40+9960}=0.004\),在ROC曲线上这个变化是很细微的。而与此同时Precision
则从原来的0.5下降到了0.33,在PR
曲线上将会是一个大幅下降。
- 上文提到
AUC
指标名称:
AUC-ROC
,Area Under the ROC Curve
定义:
AUC
表示ROC
曲线下的面积,主要用于衡量模型的泛化性能,即分类效果的好坏。AUC
是衡量二分类模型优劣的一种评价指标,表示正例排在负例前面的概率。一般在分类模型中,预测结果都是以概率的形式表现,如果要计算准确率,通常都会手动设置一个阈值来将对应的概率转化成类别,这个阈值也就很大程度上影响了模型准确率的计算。之所以采用AUC
来评价,主要还是考虑到ROC
曲线本身并不能直观的说明一个分类器性能的好坏,而AUC
值作为一个数量值,具有可比较性,可以进行定量的比较。==意义:随机从正样本和负样本中各选一个,分类器对于该正样本打分大于该负样本打分的概率。==
AUC值对模型性能的判断标准:
AUC = 1
,是完美分类器,采用这个预测模型时,存在至少一个阈值能得出完美预测。绝大多数预测的场合,不存在完美分类器。0.5 < AUC < 1
,优于随机猜测。这个分类器妥善设定阈值的话,能有预测价值。AUC = 0.5
,跟随机猜测一样,模型没有预测价值。AUC < 0.5
,比随机猜测还差;但只要总是反预测而行,就优于随机猜测。利用
AUC
来粗略衡量模型整体表现,可以参考以下范围:AUC= 0.5
(无鉴别力)0.7≤AUC≤ 0.80
(可接受的鉴别力)0.8≤AUC≤ 0.90
(优良的鉴别力)0.9≤AUC≤ 1.00
(极佳的鉴别力)
问题:
AUROC
将整条ROC curve 归纳到一个单一的值上,忽略了不同系统之间的Tradeoff
(不同threshold
值)
对比
PR Curve v.s. ROC Curve
区别
- 关注的指标不同:
ROC
曲线:ROC
曲线描绘的是真正率(True Positive Rate, TPR
)与假正率(False Positive Rate, FPR
)之间的关系。它显示的是模型在不同阈值下,如何在正类和负类样本中进行区分。PR
曲线:PR曲线描绘的是精确率(Precision
)与召回率(Recall
)之间的关系。它特别关注模型在正类样本中的表现。
- ==适用场景不同:==
- ==
ROC
曲线:适用于类别平衡的验证集以及需要评估整体分类性能的场景。在类别不平衡的数据集上,由于假正率(FPR
)的值往往较小,ROC
曲线可能会显得过于乐观。== - ==
PR
曲线:适用于类别不平衡的验证集,特别是在关注正类样本时。因为PR
曲线直接关注精确率和召回率,能够更好地反映模型在少数类上的表现。==
- ==
- 曲线的解读方式不同:
ROC
曲线:曲线下方的面积(AUC
)越大,模型的总体表现越好。完美的分类器会有一条经过左上角的曲线(AUC=1
)。PR
曲线:曲线下方的面积(AU-PR
)越大,模型在正类样本上的表现越好。完美的分类器会有一条经过右上角的曲线(AU-PR=1
)。
联系
- 基于阈值变化:两者都基于改变决策阈值来绘制曲线,通过观察在不同阈值下模型性能的变化来评估模型。
- 面积衡量性能:两者都通过计算曲线下方的面积(
AUC
和AU-PR
)来衡量模型的整体性能。
AU-PR v.s. AUC
区别
- 评估指标不同:
AUC(Area Under the ROC Curve)
:衡量ROC
曲线下的面积,反映模型在区分正类和负类样本上的能力。AU-PR(Area Under the Precision-Recall Curve)
:衡量PR
曲线下的面积,反映模型在正类样本上的精确度和召回率的综合表现。
- 适用数据集不同:
AUC
:在类别平衡或近似平衡的验证数据集上,AUC
是一个很好的评估指标。AU-PR
:在类别不平衡的验证数据集上,AU-PR
更能反映模型在少数类上的性能。
联系
- 用于模型评估:两者都是用于评估分类模型性能的指标,通过曲线下的面积提供一个综合的性能评估。
- 基于阈值变化:两者都依赖于通过改变决策阈值来评估模型在不同条件下的表现。
结论
ROC
曲线兼顾正例与负例,因此适用于评估分类器整体的效能,而PR
曲线则专注于正例- 若在类别平衡且正例及负例的判断都重要的情况下,选择
ROC
曲线更合理 - 由于
ROC
曲线的X轴使用到了FPR
,在类别不平衡的情况下(负样本较多),使得FPR
的增长会被稀释,进而导致ROC
曲线呈现出过度乐观的结果,因此在类别不平衡的情况下,PR
曲线是较好的选择 - 总结:类别不平衡问题中由于主要关心正例,所以在此情况下
PR
曲线被广泛认为优于ROC
曲线。
- 若在类别平衡且正例及负例的判断都重要的情况下,选择
- 如果有多份数据且存在不同的类别分布,比如信用卡欺诈问题中每个月正例和负例的比例可能都不相同,这时候如果只想单纯地比较分类器的性能且剔除类别分布改变的影响,则
ROC
曲线比较适合,因为类别分布改变可能使得PR曲线发生变化时好时坏,这种时候难以进行模型比较;反之,如果想测试不同类别分布下对分类器的性能的影响,则PR
曲线比较适合。 - 如果想要评估在相同的类别分布下正例的预测情况,则宜选
PR
曲线。 - 最后可以根据具体的应用,在曲线上找到最优的点,得到相对应的
precision,recall,f1 score
等指标,去调整模型的阈值,从而得到一个符合具体应用的模型。
参考资料
- https://blog.csdn.net/qq_30992103/article/details/99730059
- https://tsupei.github.io/nlp/2019/12/30/prcurve.html
- https://www.cnblogs.com/massquantity/p/8592091.html
- https://blog.csdn.net/universsky2015/article/details/137303932
- https://blog.csdn.net/u013230291/article/details/108555329
- https://www.cnblogs.com/pythonfl/p/12286742.html
- https://blog.csdn.net/weixin_42267615/article/details/107834639
- https://blog.csdn.net/Jasminexjf/article/details/88681444
- https://blog.csdn.net/whether_you/article/details/80571485
- https://blog.csdn.net/KANG157/article/details/130674038
- https://blog.csdn.net/qq_41804812/article/details/125255346
- https://blog.csdn.net/taotiezhengfeng/article/details/80456110
- https://blog.csdn.net/w1301100424/article/details/84546194
- https://microstrong.blog.csdn.net/article/details/79946787
- https://www.zybuluo.com/frank-shaw/note/152851
- https://www.zhihu.com/question/39840928?from=profile_question_card
- https://www.dataschool.io/roc-curves-and-auc-explained/
- https://blog.csdn.net/m0_55434618/article/details/133971872
- https://blog.csdn.net/weixin_44609958/article/details/136739187
- https://blog.csdn.net/hjxu2016/article/details/131789657
- https://github.com/openvinotoolkit/anomalib
- https://blog.csdn.net/weixin_42010722/article/details/133924723