一、二分类
real\predict | Positive | Negative |
---|---|---|
True | TP | FN |
False | FP | TN |
(注意:True和Negative交叉处应为FN而非TN,因为是错误地预测为反例,False和Positive交叉处同理)
- TP、TN、FP、FN 中的第二个字母(列标首字母)是机器学习算法或模型预测的结果(正例:P、反例:N)
- TP、TN、FP、FN 中的第一个字母(行标首字母)是根据真实情况判断预测结果是否正确(正确:T、错误:F)
即:
- 正确地预测为正例:TP
- 正确地预测为反例:TN
- 错误地预测为正例:FP
- 错误地预测为反例:FN
准确率Accuracy:被预测正确的比例
a
c
c
u
r
a
c
y
=
T
P
+
T
N
T
P
+
F
P
+
F
N
+
T
N
accuracy = \frac{TP+TN }{TP + FP + FN + TN}
accuracy=TP+FP+FN+TNTP+TN
精确率(查准率) Precision :"正确被预测为正(TP)"占所有"实际被预测为正的(TP+FP)"的比例(混淆矩阵中除以所在的那一列之和)
p r e c i s i o n = T P T P + F P precision = \frac{TP }{TP + FP} precision=TP+FPTP
召回率(查全率) Recall:"正确被预测为正(TP)"占所有"应该被预测为正(TP+FN)"的比例(混淆矩阵中除以所在的那一行之和)
r e c a l l = T P T P + F N recall = \frac{TP }{TP + FN} recall=TP+FNTP
F-measure:
F − m e a s u r e = ( a 2 + 1 ) ∗ P ∗ R a 2 ( P + R ) F- measure = \frac{(a^2 + 1 )*P*R}{a^2(P+R)} F−measure=a2(P+R)(a2+1)∗P∗R
如果A取1,那么F-measure实际上就是precison和recall的调和平均值, 此时的F-measure就称为F1值。
F − 1 = 2 P R P + R F- 1 = \frac{2PR}{P+R} F−1=P+R2PR
二、多分类
real\predict | 类1 | 类2 | 类3 |
---|---|---|---|
类1 | 43 | 5 | 2 |
类2 | 2 | 45 | 3 |
类3 | 0 | 1 | 49 |
每一行之和为50,表示50个样本。
第一行说明类1的50个样本有43个分类正确,5个错分为类2,2个错分为类3。
类似于二分类,多类分类问题中,分类结果一般有4种情况:
- 属于类C的样本被正确分类到类C,记这一类样本数为 TP
- 不属于类C的样本(可能是A也可能是B…)被错误分类到类C,记这一类样本数为 FP
- 属于类别C的样本被错误分类到类C的其他类,记这一类样本数为 FN
- 不属于类别C的样本被正确分类到了类别C的其他类,记这一类样本数为 TN
宏平均 Macro-average
Macro F1:将n分类的评价拆成n个二分类的评价,计算每个二分类的F1 score,n个F1 score的平均值即为Macro F1。
微平均Micro-average
Micro F1:将n分类的评价拆成n个二分类的评价,将n个二分类评价的TP、FP、TN、FN对应相加,计算评价准确率和召回率,由这2个准确率和召回率计算的F1 score即为Micro F1。
(TP + FP) / (TP + TN + FP + FN),实际上就是accuracy,分母就是输入分类器的预测样本个数,分子就是预测正确的样本个数(无论类别)。
一般来讲,Macro F1、Micro F1高的分类效果好。Macro F1受样本数量少的类别影响大。
宏平均比微平均更合理,但也不是说微平均一无是处,具体使用哪种评测机制,还是要取决于数据集中样本分布。
例:
考虑现在输入分类器的样本有10个,他们属于类别A B C。
假设这10个样本的真实类标为(有序)和分类器预测的类标分别是:
真实:A A A C B C A B B C
预测:A A C B A C A C B C
precision(A) = 3(正确预测为A类的样本个数为3) / 4(预测为A类的样本数为4) = 0.75 recall(A) = 3 / 4(真实A类样本有4个) = 0.75
precision(B) = 1 / 2 = 0.5 recall(B) = 1 / 3 = 0.3333
precision(C) = 2 / 3 = 0.6667 recall(C) = 2 / 3 = 0.6667
F值计算出来之后,取算术平均就是Macro-average
Micro-average = 6(预测正确的样本个数) / 10 = 0.6
三、ROC曲线和AUC
ROC
ROC的全名叫做Receiver Operating Characteristic,即受试者工作特征曲线。
ROC关注两个指标:
True Positive Rate ( TPR ) = TP / [ TP + FN] ,TPR真阳性率,即判断为正例且实际为正例的个数占全部正例的比例,即recall
False Positive Rate( FPR ) = FP / [ FP + TN] ,FPR假阳性率,即判断为正例但实际为负例的比例
ROC曲线只对二分类问题有效。而尤其当正负样本不平衡时,这种评价比起准确率更有效(只要想想把垃圾邮件分类器如果把所有邮件都识别为不是垃圾邮件,也可以得到90%以上的准确率,但这没有任何意义)。
在ROC 空间中,每个点的横坐标是FPR,纵坐标是TPR,这也就描绘了分类器在TP(真正的正例)和FP(错误的正例)间的trade-off。ROC的主要分析工具是一个画在ROC空间的曲线——ROC curve。
我们知道,对于二值分类问题,实例的值往往是连续值,我们通过设定一个阈值,将实例分类到正类或者负类(比如大于阈值划分为正类)。因此我们可以变化阈值,根据不同的阈值进行分类,根据分类结果计算得到ROC空间中相应的点,连接这些点就形成ROC curve。
ROC curve经过(0,0)(1,1),实际上(0, 0)和(1, 1)连线形成的ROC curve实际上代表的是一个随机分类器。一般情况下,这个曲线都应该处于(0, 0)和(1, 1)连线的上方。
(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),分类器实际上预测所有的样本都为正样本。
对于ROC曲线,我们可以这样理解,对于二分类问题,曲线的每一个点都代表一个阈值,分类器给每个样本一个得分,得分大于阈值的我们认为是正样本,小于阈值的我们认为是负样本。
若学习器A的ROC曲线将另外一个学习器B的曲线完全包住,则A的性能一定比B好,否则若二者曲线有交叉,则可以较为合理的认为ROC曲线越接近左上角,也就是AUC值越大,整个分类器的性能越好。
AUC
用ROC curve来表示分类器的performance很直观好用。可是,人们总是希望能有一个数值来标志分类器的好坏。
于是Area Under roc Curve(AUC) 就出现了。AUC(Area Under Curves)指的是ROC曲线下的面积,该指标能较好的概括不平衡样本分类器的性能而成为很多数据挖掘竞赛的判定标准。
AUC的计算
由于仅有有限个样本,无论训练样本还是测试样本,因此无法获得最精确的ROC曲线,从而无法精确计算AUC。在实际计算中,使用类似微积分的方法,用梯形面积的和去近似。通常,AUC的值介于0.5到1.0之间,较大的AUC代表了较好的Performance。
关于实际编程中的计算,知乎中有一个回答是这样说的:
AUC的物理意义
假设分类器的输出是样本属于正类的socre(置信度),则AUC的物理意义为,任取一对(正、负)样本,正样本的score大于负样本的score的概率。从而我们能够理解对于AUC而言,并不关心具体预测的结果是标签或者概率,也不需要卡什么阈值,只要在预测结果之间有排序即可。
如果分别在两份数据上计算出AUC为AUC_1和AUC_2,问整体数据的AUC是多少?
答案其实是无法得到,因为从局部的有序无法直接退出全局的有序,这个题目其实还是考查对于AUC这个指标的理解深度。
四、P/R曲线
P-R曲线刻画查准率和查全率之间的关系,查准率指的是在所有预测为正例的数据中,真正例所占的比例,查全率是指预测为真正例的数据占所有正例数据的比例。
即:
查准率(Precision) P=TP/(TP + FP)
查全率(Recall) R=TP/(TP+FN)
在很多情况下,我们可以根据学习器的预测结果对样例进行排序,排在前面的是学习器认为最可能是正例的样本,排在后面的是学习器认为最不可能是正例的样本,按此顺序逐个把样本作为正例进行预测,则每次可计算当前的查全率和查准率,以查准率为y轴,以查全率为x轴,可以画出下面的P-R曲线。平衡点(BEP)是查准率=查全率时的取值,如果这个值较大,则说明学习器的性能较好。
P/R和ROC如何选择?
- P/R和ROC是两个不同的评价指标和计算方式,一般情况下,检索用前者,分类、识别等用后者。
- 在很多实际问题中,正负样本数量往往很不均衡。比如,计算广告领域经常涉及转化率模型,正样本的数量往往是负样本数量的1/1000,甚至1/10000。若选择不同的测试集,P-R曲线的变化就会非常大,而ROC曲线则能够更加稳定地反映模型本身的好坏。所以,ROC曲线的适用场景更多,被广泛用于排序、推荐、广告等领域。
- 但需要注意的是,选择P-R曲线还是ROC曲线是因实际问题而异的,如果研究者希望更多地看到模型在特定数据集上的表现,P-R曲线则能够更直观地反映其性能。
- PR曲线比ROC曲线更加关注正样本,而ROC则兼顾了两者。
- AUC越大,反映出正样本的预测结果更加靠前。(推荐的样本更能符合用户的喜好)
- 当正负样本比例失调时,比如正样本1个,负样本100个,则ROC曲线变化不大,此时用PR曲线更加能反映出分类器性能的好坏。这个时候指的是两个分类器,因为只有一个正样本,所以在画auc的时候变化可能不太大;但是在画PR曲线的时候,因为要召回这一个正样本,看哪个分类器同时召回了更少的负样本,差的分类器就会召回更多的负样本,这样precision必然大幅下降,这样分类器性能对比就出来了。
五、mAP
mAP,即mean Average Precision,也就是平均的平均精确度(没错,就是两个平均),首先是一个类别内,求平均精确度(Average Precision),然后对所有类别的平均精确度再求平均(mean Average Precision)。
mAP常用于目标检测,多个类别物体检测中,每一个类别都可以根据recall和precision绘制一条PR曲线,AP就是该曲线下的面积,mAP是多个类别AP的平均值。
计算不同Recall值下的Precision的平均值,就得到了所谓的Average Precision。对不同的Recall值,可以有不同的取值方法,其中PASCAL VOC 2007和PASCAL VOC 2012 中采取的是如下两种不同的方式。
PASCAL VOC 2007的AP
对于上面的PR曲线,取(0.0, 0.1, 0.2 …… 1.0)共11个Recall值,计算Precision的平均值。考虑到在样本有限的情况下,有可能出现如下图这样的抖动,即Recall值较大时,Precision反而比Recall较小时的值更大。因此,还需采取一定的平滑措施,计算方式如下。
A
P
=
1
11
∑
r
∈
{
0
,
0.1
,
…
,
1.0
}
ρ
interp
(
r
)
ρ
interp
(
r
)
=
max
r
^
:
r
^
⩾
r
(
r
^
)
\begin{aligned} A P=\frac{1}{11} \sum_{r \in\{0,0.1, \ldots, 1.0\}} & \rho_{\text {interp}}(r) \\ \rho_{\text {interp}}(r)=& \max _{\hat{r}: \hat{r} \geqslant r}(\hat{r}) \end{aligned}
AP=111r∈{0,0.1,…,1.0}∑ρinterp(r)=ρinterp(r)r^:r^⩾rmax(r^)
实际上就是对于每个Recall值下的Precision,取所有比当前值大的Recall对应的Precision的最大值作为当前Recall值下的Precision,对应上图,就是取当前recall值右侧的最大Precision作为当前的Precision。平滑后,得到的就是如上面红色虚线所示的值。
上面的计算过程,可以看成是把横坐标分成11个bin,每个bin的宽度就是
1
11
\frac{1}{11}
111,高度就是Precision值,AP值就是这11个bin的面积和。如上图的计算过程如下
A
P
=
1
11
(
1
+
0.6666
+
0.4285
+
0.4285
+
0.4285
+
0
+
0
+
0
+
0
+
0
+
0
)
=
0.2684
AP = \frac{1}{11}(1 + 0.6666 + 0.4285 + 0.4285 + 0.4285 + 0 + 0 + 0 + 0 + 0 + 0) \\=0.2684
AP=111(1+0.6666+0.4285+0.4285+0.4285+0+0+0+0+0+0)=0.2684
PASCAL VOC 2012 的AP
PASCAL VOC 2012 中(貌似是从VOC2010开始的),针对每一个不同的Recall值(包括0和1),选取其大于等于这些Recall值时的Precision最大值,然后计算PR曲线下面积作为AP值。平滑的结果还是上面那个曲线,只不过计算平均值的点更多了。
这样取均值的结果,就可以看成是计算平滑后的PR曲线(上图红色虚线)的AUC(Area Under Curve)。
如上图所示,AP值实际上就等于四个方框的面积和。
A
P
=
A
1
+
A
2
+
A
3
+
A
4
AP=A1+A2+A3+A4
AP=A1+A2+A3+A4
例如上图中
A
1
=
(
0.0666
−
0
)
∗
1
=
0.0666
A
2
=
(
0.1333
−
0.0666
)
∗
0.0666
=
0.0444
A
3
=
(
0.4
−
0.1333
)
∗
0.4285
=
0.1142
A
4
=
(
0.4666
−
0.4
)
∗
0.3043
=
0.0202
A
P
=
0.0666
+
0.0444
+
0.1142
+
0.0202
=
0.2456
\begin{array}{l} A 1=(0.0666-0) * 1=0.0666 \\ A 2=(0.1333-0.0666) * 0.0666=0.0444 \\ A 3=(0.4-0.1333) * 0.4285=0.1142 \\ A 4=(0.4666-0.4) * 0.3043=0.0202 \\ A P=0.0666+0.0444+0.1142+0.0202=0.2456 \end{array}
A1=(0.0666−0)∗1=0.0666A2=(0.1333−0.0666)∗0.0666=0.0444A3=(0.4−0.1333)∗0.4285=0.1142A4=(0.4666−0.4)∗0.3043=0.0202AP=0.0666+0.0444+0.1142+0.0202=0.2456
实际计算时,可能是用两个Recall的间隔作为bin的宽度,以平滑后的Precision作为高,求和后与上面的过程是一样的。
AP衡量的是学出来的模型在给定类别上的好坏,而mAP衡量的是学出的模型在所有类别上的好坏,得到AP后mAP的计算就变得很简单了,就是取所有AP的平均值。
六、python 计算混淆矩阵和accuracy、precision、recall、f1-score
一些机器学习库封装了计算评价指标的库,pytorch只能自己计算。
confusion_matrix1 = np.array([[0 for _ in range(len(tag2idx))] for _ in range(len(tag2idx))])
n1 = len(confusion_matrix1)
with torch.no_grad():
for bidx, batch in enumerate(testset_loader):
......
predict_tags = model(seq, mask)
pre_tag = torch.argmax(predict_tags, dim=1) # 预测值
tag = tag.view(-1) # 真实值
for i in range(len(tag)):
confusion_matrix1[tag[i]][pre_tag[i]] += 1
for i in range(len(punctag)):
confusion_matrix2[punctag[i]][pre_punctag[i]] += 1
for i in range(n1):
rowsum, colsum = sum(confusion_matrix1[i]), sum(confusion_matrix1[r][i] for r in range(n1))
try:
precision.append(confusion_matrix1[i][i] / float(colsum))
recall.append(confusion_matrix1[i][i] / float(rowsum))
f1score.append(
2 * precision[i] * recall[i] / (precision[i] + recall[i]) if (precision[i] + recall[i]) > 0 else 0)
print(
"precision: {:.4f} recall: {:.4f} f1: {:.4f} ".format(precision[i], recall[i], f1score[i]))
except ZeroDivisionError:
precision.append(0)
recall.append(0)
f1score.append(0)
print(
"precision: {} recall: {} f1: {} ".format(0, 0, 0))
correct1 = [confusion_matrix1[i][i] for i in range(len(tag2idx))]
total_acc1 = sum(correct1) / sum(map(sum, confusion_matrix1))
print("total accuracy: {:.4} ".format(total_acc1))
参考网址:
多类分类(Multi-label classification)性能评价之宏平均(macro-average)与微平均(micro-average)
二分类与多分类评估(混淆矩阵,准确率,召回率,F1,mAP)
对多分类数据的模型比较选择,应该参考什么指标?
理解AUC的意义
P-R曲线及与ROC曲线区别
AUC的计算方法
性能指标(模型评估)之mAP
目标检测测评指标——mAP