为什么要用精确率和召回率
有这样一个训练集,1000个人参加了结直肠癌CRC的检测,实际有0.5%的人得了CRC(即5个人)。用神经网络算法得到检测这样一个训练集能达到99%的准确率。从数值上判断该算法是不错的,因为只有1%的误差。那么我们是否能应用该算法进行实际生产呢?这是不能的。因为如果误判一个人,对该人造成的影响是巨大的。如果不使用算法,直接预测这1000个人全没有得CRC,发现只有0.5的误差,比神经网络算法还好,这显然说明使用准确率在偏斜类样本集中判断算法好坏是不靠谱的。这时候,就需要使用精确率和召回率来判断了。
ps:偏斜类是指某类样品数量明显大于另一类样品
精确率和召回率
TP(True Positive): 实际为正类,预测为正类
TN(True Negative): 实际为正类,预测为负类
FP(False Positive): 实际为负类,预测为正类
FN(False Negative): 实际为正类,预测为负类
记忆 :T读成正确,F读成错误,P读成正类,F读成负类。例如,TP :正确的预测成正类,那么说明他实际也为正类
从混淆矩阵中得出对应的召回率和精确率在上例中代表的意思:
召回率(recall)为实际有CRC肿瘤的病人中,成功预测有CRC肿瘤的百分比,数值越大越好
精确率(precision)为预测的所有肿瘤病人中,实际上有肿瘤的病人,数值越大越好
这样,对于上面误差为1%的神经网络算法。TP∈ \in∈ [0,1,2,3,4,5] ,取最好的情况,假设5个病人全都预测出,即TP=5;因为1%的误差,则FP=10,FN=0,那么precision=5/(5+10)≈ \approx≈ 0.333…,说明该算法不好。
对于我们刚才那个总是预测病人没有CRC的方法,TP=0,召回率和精准率都是 0,直接排除。
F1值的由来
sklearn中P/R/F1的micro,macro及weighted的算法
from sklearn.metrics import precision_score, recall_score, f1_score, confusion_matrix
1.构建数据集
y_pred = [ 0, 0, 0,1, 1, 1, 1, 1, 2, 2, 2 ]
y_true = [ 0, 1, 0, 1, 1, 2, 2, 2, 1, 0, 2 ]
2.数据集的混淆矩阵
confusion_matrix(y_true, y_pred )
array([[2, 0, 1],
[1, 2, 1],
[0, 3, 1]])
3.数据集的详细报告
print(classification_report(y_true, y_pred))
4.报告中的micro avg:计算总体的TP, FN, FP
p1 = precision(5, 6)
r1 = recall(5, 6)
f1 = F1(p1, r1)
p1, r1, f1
(0.45454545454545453, 0.45454545454545453, 0.45454545454545453)
p1 = precision(5, 6)
r1 = recall(5, 6)
f1 = F1(p1, r1)
p1, r1, f1
(0.45454545454545453, 0.45454545454545453, 0.45454545454545453)
5.对应sklearn
precision_score(y_true, y_pred, average='micro')
recall_score(y_true, y_pred, average='micro')
f1_score(y_true, y_pred, average='micro')
0.45454545454545453
6.报告中的macro avg:各类的precision,recall,f1加和求平均
p0 = precision(2, 1) # 0 类精确率,TP表示实际为0类预测也为0类,从混淆矩阵中得值为2;
# FP表示实际为别类但是却错误的预测成了0类,从混淆矩阵中得值为1。
p1 = precision(2, 3)
p2 = precision(1, 2)
avg_p = (p0 + p1 + p2) / 3
r0 = recall(2, 1)
r1 = recall(2, 2)
r2 = recall(1, 3)
avg_r = (r0 + r1 + r2) / 3
f0 = F1(p0, r0)
f1 = F1(p1, r1)
f2 = F1(p2, r2)
avg_f = (f0 + f1 + f2) / 3
avg_p, avg_r, avg_f
(0.4666666666666666, 0.47222222222222215, 0.46560846560846564)
7.报告中weighted avg :对每一类别的f1_score进行加权平均,权重为各类别数在y_true中所占比例
# y_true中 0类有3个,1类有4个,2类有4个
avg_p = 3/11 *p0 + 4/11*p1 + 4/11*p2
avg_r = 3/11*r0 + 4/11*r1 + 4/11* r2
avg_f = 3/11*f0 +4/11*f1 + 4/11*f2
avg_p, avg_r, avg_f
(0.4484848484848485, 0.4545454545454546, 0.44733044733044736)
8.precision_score,recall_score,f1_score中average='binary’的计算
只适用于二分类,用正类的y=1的TP,FP,FN来计算precision,recall,f1
y_pre = [ 0, 0, 0, 1, 1, 1, 1, 1 ]
y_tru = [ 0, 1, 0, 1, 1, 0, 0, 1 ]
precision_score(y_tru, y_pre, average='binary')
0.6
confusion_matrix(y_tru, y_pre)
array([[2, 2], [1, 3]])
precision(3, 2)
0.6
9.precision和recall的关系
转载链接: https://blog.csdn.net/qq_34964399/article/details/102723241