2017-04-15 93 views
0

我使用sklearn来计算macro f1得分,我怀疑代码中是否有任何错误。下面是一个例子(标签0被忽略):使用sklearn计算宏f1得分

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 

正如你所看到的,sklearn0.6041666666666666macro f1。然而,它不等于2*0.725*0.566666666/(0.725+0.566666666),其中0.7250.566666666macro precisionmacro recallsklearn计算。

回答

1

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

documentation of f_score给出:

”:通过计数总真阳性,假阴性和假阳性全局计算指标。

'':计算每个标签的度量标准,并找到它们的未加权平均值。这不考虑标签不平衡。

在宏中,所有类的召回率,精度和f1分别计算,然后返回它们的平均值。所以你不能期望对他们应用你的公式def f(p, r)。因为他们不是你想要的。

在微观上,f1是根据最终的精度和召回率(所有类别的全局组合)来计算的。因此,这与您在my_f_micro中计算的分数相符。

希望它是有道理的。

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