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计算过程如下

  1. from sklearn.metrics import precision_recall_fscore_support
  2. labels = [1, 1, 1, 2, 2, 2, 3, 3, 4]
  3. preds = [1, 1, 2, 0, 2, 4, 1, 3, 3]
  4. p, r, f1, true_sum = precision_recall_fscore_support(labels, preds, labels=[1, 2, 3, 4], average='micro')
  5. print('micro:', p, r, f1)
  6. p, r, f1, true_sum = precision_recall_fscore_support(labels, preds, labels=[1, 2, 3, 4], average='macro')
  7. print('macro:', p, r, f1)
  8. # micro: 0.5 0.4444444444444444 0.47058823529411764
  9. # 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的时候先按照类别计算,再取平均值或者加权平均值。