本文使用以下样例来计算混淆矩阵、precision、recall和F1分数
真实值:[0, 1, 0, 0, 1, 2]
预测值:[0, 2, 1, 0, 0, 2]
混淆矩阵将分类结果进行了四种情况的区分,如下图
首先,不管是二分类还是多分类问题,混淆矩阵是针对其中某一类别的;如对苹果、香蕉、葡萄进行分类,建立苹果类的混淆矩阵时,苹果是正类(positive),其他类即香蕉、葡萄都是负类(negative)。
TP、FN、FP、TN的第一个字母全称为True或False,代表预测值与真实值是否相同,第二个字母全称为Positive或negative,代表预测值是正类还是负类。如:
得到预测结果后,对每个类别的这四种情况进行计数,则得到了混淆矩阵。
在样例中类别0的混淆矩阵为
类别0 | Positive | Negative |
---|---|---|
Positive | 2 | 1 |
Negative | 1 | 2 |
在样例中类别1的混淆矩阵为
类别0 | Positive | Negative |
---|---|---|
Positive | 0 | 2 |
Negative | 1 | 3 |
在样例中类别2的混淆矩阵为
类别0 | Positive | Negative |
---|---|---|
Positive | 1 | 0 |
Negative | 1 | 4 |
多分类合到一起的混淆矩阵为
类别 | 0 | 1 | 2 |
---|---|---|---|
0 | 2 | 1 | 0 |
1 | 1 | 0 | 1 |
2 | 0 | 0 | 1 |
from sklearn.metrics import confusion_matrix
y_true = [0, 1, 0, 0, 1, 2]
y_pred = [0, 2, 1, 0, 0, 2]
print('confusion_matrix:\n', confusion_matrix(y_true, y_pred))
p r e c i s i o n = 类别 n 预测正确的个数 预测值中类别 n 的个数 = T P T P + F P precision = \frac{类别n预测正确的个数}{预测值中类别n的个数}=\frac{TP}{TP+FP} precision=预测值中类别n的个数类别n预测正确的个数=TP+FPTP
r e c a l l = 类别 n 预测正确的个数 真实值中类别 n 的个数 = T P T P + F N recall = \frac{类别n预测正确的个数}{真实值中类别n的个数}=\frac{TP}{TP+FN} recall=真实值中类别n的个数类别n预测正确的个数=TP+FNTP
F 1 = 2 ∗ p r e c i s i o n ∗ r e c a l l p r e c i s i o n + r e c a l l F1 = 2*\frac{precision * recall}{precision + recall} F1=2∗precision+recallprecision∗recall
样例中每个类别的precision、recall、F1分数为
类别/评价指标 | precision | recall | F1-score |
---|---|---|---|
类别0 | 2/3 | 2/3 | 2/3 |
类别1 | 0 | 0 | 0 |
类别2 | 1/2 | 1 | 2/3 |
在多分类任务中,每一个类别都有一组precision、recall、F1分数,如何平衡各类别的分数得到全局的评价指标呢?有三种方法macro、micro、weighted,也就是多类别中共有3 * 3 = 9组指标。
macro precision: ( 2 3 + 0 + 1 2 ) / 3 = 7 18 (\frac{2}{3} + 0 + \frac{1}{2}) / 3 = \frac{7}{18} (32+0+21)/3=187
macro recall: ( 2 3 + 0 + 1 ) / 3 = 5 9 (\frac{2}{3} + 0 + 1) / 3 = \frac{5}{9} (32+0+1)/3=95
macro F1: ( 2 3 + 0 + 2 3 ) / 3 = 4 9 (\frac{2}{3} + 0 + \frac{2}{3}) / 3 = \frac{4}{9} (32+0+32)/3=94
micro precision: 3 6 = 0.5 \frac{3}{6} = 0.5 63=0.5
解释:3为各个类别预测正确的个数之和,6为各个类别预测值的总个数
micro recall: 3 6 = 0.5 \frac{3}{6} = 0.5 63=0.5
解释:3为各个类别预测正确的个数之和,6为各个类别真实值的总个数,与精确率相等
micro F1: 2 ∗ 0.5 ∗ 0.5 0.5 + 0.5 = 0.5 2 *\frac{0.5 * 0.5}{0.5 + 0.5} = 0.5 2∗0.5+0.50.5∗0.5=0.5
解释:上面的precision和recall求的F1分数
weighted precision: 2 3 ∗ 1 2 + 0 ∗ 1 3 + 1 2 ∗ 1 6 = 5 12 \frac{2}{3} * \frac{1}{2} + 0 * \frac{1}{3} + \frac{1}{2} * \frac{1}{6} = \frac{5}{12} 32∗21+0∗31+21∗61=125
解释:真实值中有3个0、2个1、1个2,所占比例分别为1/2、1/3、1/6
weighted recall: 2 3 ∗ 1 2 + 0 ∗ 1 3 + 1 ∗ 1 6 = 1 2 \frac{2}{3} * \frac{1}{2} + 0 * \frac{1}{3} + 1 * \frac{1}{6} = \frac{1}{2} 32∗21+0∗31+1∗61=21
weighted F1: 2 3 ∗ 1 2 + 0 ∗ 1 3 + 2 3 ∗ 1 6 = 4 9 \frac{2}{3} * \frac{1}{2} + 0 * \frac{1}{3} + \frac{2}{3} * \frac{1}{6} = \frac{4}{9} 32∗21+0∗31+32∗61=94
from sklearn.metrics import f1_score, recall_score, precision_score
y_true = [0, 1, 0, 0, 1, 2]
y_pred = [0, 2, 1, 0, 0, 2]
average = 'macro'
print('\nmacro precision:',precision_score(y_true, y_pred, average=average),
'\nmacro recall:', recall_score(y_true, y_pred, average=average),
'\nmacro f1_score:', f1_score(y_true, y_pred, average=average))
average = 'micro'
print('\nmicro precision:',precision_score(y_true, y_pred, average=average),
'\nmicro recall:', recall_score(y_true, y_pred, average=average),
'\nmicro f1_score:', f1_score(y_true, y_pred, average=average))
average = 'weighted'
print('\nweighted precision:',precision_score(y_true, y_pred, average=average),
'\nweighted recall:', recall_score(y_true, y_pred, average=average),
'\nweighted f1_score:', f1_score(y_true, y_pred, average=average))