使用 sklearn 计算宏 f1 分数

Posted

技术标签:

【中文标题】使用 sklearn 计算宏 f1 分数【英文标题】:Computing macro f1 score using sklearn 【发布时间】:2017-09-11 07:10:33 【问题描述】:

我正在使用sklearn 计算macro f1 分数,我怀疑代码中是否存在任何错误。这是一个示例(标签0 被忽略):

from sklearn.metrics import f1_score, precision_recall_fscore_support

y_true = [1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4]
y_pred = [1, 1, 1, 0, 0, 2, 2, 3, 3, 3, 4, 3, 4, 3]



p_macro, r_macro, f_macro, support_macro \
    = precision_recall_fscore_support(y_true=y_true, y_pred=y_pred, labels=[1, 2, 3, 4], average='macro')

p_micro, r_micro, f_micro, support_micro\
    = precision_recall_fscore_support(y_true=y_true, y_pred=y_pred, labels=[1, 2, 3, 4], average='micro')

def f(p, r):
    return 2*p*r/(p+r)

my_f_macro = f(p_macro, r_macro)

my_f_micro = f(p_micro, r_micro)

print('my f macro '.format(my_f_macro))

print('my f micro '.format(my_f_micro))

print('macro: p , r , f1 '.format(p_macro, r_macro, f_macro))

print('micro: p , r , f1 '.format(p_micro, r_micro, f_micro))

输出:

my f macro 0.6361290322580646
my f micro 0.6153846153846153
macro: p 0.725, r 0.5666666666666667, f1 0.6041666666666666
micro: p 0.6666666666666666, r 0.5714285714285714, f1 0.6153846153846153

如您所见,sklearnmacro f1 提供0.6041666666666666。但是,它不等于2*0.725*0.566666666/(0.725+0.566666666),其中0.7250.566666666macro precisionmacro recall,由sklearn 计算得出。

【问题讨论】:

【参考方案1】:

计算“宏观”和“微观”平均值的过程有所不同。

如documentation of f_score:

'micro':通过计算真阳性、假阴性和假阳性的总数来全局计算指标。

'ma​​cro':计算每个标签的指标,并找到它们的未加权平均值。这没有考虑标签不平衡。

在宏中,所有类的召回率、精度和 f1 都是单独计算的,然后返回它们的平均值。所以你不能指望在他们身上应用你的公式def f(p, r)。因为它们和你想的不一样。

在 micro 中,f1 是根据最终精度和召回率计算的(所有类的全局组合)。所以这与您在my_f_micro 中计算的分数相匹配。

希望它有意义。

更多解释,你可以在这里阅读答案:-

How to compute precision, recall, accuracy and f1-score for the multiclass case with scikit learn?

【讨论】:

是的,宏是有道理的,但微观呢?它只能用于具有一个类别的布尔分类来“召回”并“精确”吗?什么是假阳性,什么是多个类的假阴性? @TomaszGandor 唯一的区别是计算实际精度、召回率和 f1 的时间。我们首先计算 tp, tn, fp, fn 类。在微观上,我们将所有 tp(对于所有类)求和,其他类相同,然后计算指标。在宏观上,我们首先计算每个类的指标,然后取它们的平均值。希望这能说明问题。

以上是关于使用 sklearn 计算宏 f1 分数的主要内容,如果未能解决你的问题,请参考以下文章

scikit加权f1分数计算及使用

精度、召回率、F1 分数等于 sklearn

sklearn中计算准确率召回率精确度F1值

在有监督的多类分类中,为啥使用宏 F1 分数而不是平衡精度?

『NLP学习笔记』Sklearn计算准确率精确率召回率及F1 Score

微观VS宏观VS加权F1分数[关闭]