micro 和macro是两种不同的评价指标precision、recall、f1的计算方式,micro可以理解为不区分类别,macro按类别计算在平均(可以加权平均)。
Micro
sample index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|---|
label | 1 | 1 | 1 | 2 | 2 | 2 | 3 | 3 | 4 |
prediction | 1 | 1 | 2 | 0 | 2 | 4 | 1 | 3 | 3 |
对于如上的数据,计算混淆矩阵confusion_matrix时。就某一类来说:
- True Positive:label和prediction都为该类别。
- False Positive:label不是该类别,prediction为该类别。
- True Negative:label和prediction都不是该类别。
- False Negative:label是该类别,prediction不是该类别。
就类别1来说,TP为样本0、1,FP为样本6,TN为3、4、5、7、8,FN为2。混淆矩阵如下
类别1 | 类别2 | 类别3 | 类别4 | sum | |
---|---|---|---|---|---|
TP | 2 | 1 | 1 | 0 | 4 |
FP | 1 | 1 | 1 | 1 | 4 |
FN | 1 | 2 | 1 | 1 | 5 |
precision = 4 / (4 + 4) = 0.5
recall = 4 / (4 + 5) = 4/9
f1 = 2 0.5 4/9 / (0.5 + 4/9) = 8/17
sklearn计算过程如下
from sklearn.metrics import precision_recall_fscore_support
labels = [1, 1, 1, 2, 2, 2, 3, 3, 4]
preds = [1, 1, 2, 0, 2, 4, 1, 3, 3]
p, r, f1, true_sum = precision_recall_fscore_support(labels, preds, labels=[1, 2, 3, 4], average='micro')
print('micro:', p, r, f1)
p, r, f1, true_sum = precision_recall_fscore_support(labels, preds, labels=[1, 2, 3, 4], average='macro')
print('macro:', p, r, f1)
# micro: 0.5 0.4444444444444444 0.47058823529411764
# macro: 0.41666666666666663 0.375 0.39166666666666666
sklearn 在计算的时候遇到为除数为0的情况,会把除数变为1。
另外需要主要的是,类别0一般认为是负样本,不计算p, r, f1。precision_recall_fscore_support函数默认计算类别0,即计算所有类别。这样会计算会使precision和recall值相同。原因是,
- 对于FP和FN来说,如果某个样例a对于类别c来说是FP,那么该样例a一定是某一类别(除类别c)的FN;
- 类似的如果一个样例对于某一类来说是FN,那么它一定是其它类别的FP。
这样会导致sum(FN)=sum(FP),所以precision=recall
Macro
macro和micro的TP、FP、FN计算方式类似,只是p,r的时候先按照类别计算,再取平均值或者加权平均值。