使用 sklearn 计算宏 f1 分数
Computing macro f1 score using sklearn
我正在使用 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
如您所见,sklearn
为 macro f1
提供 0.6041666666666666
。但是,它不等于2*0.725*0.566666666/(0.725+0.566666666)
,其中0.725
和0.566666666
是由sklearn
计算得到的macro precision
和macro recall
。
计算 'macro' 和 'micro' 平均值的过程有所不同。
如 documentation of f_score 中所示:
'micro': Calculate metrics globally by counting the total true positives, false negatives and false positives.
'macro': Calculate metrics for each label, and find their unweighted mean. This does not take label imbalance into account.
在宏中,所有 类 的召回率、精度和 f1 都是单独计算的,然后返回它们的平均值。因此,您不能指望将公式 def f(p, r)
应用于它们。因为它们与您想要的不一样。
在微观上,f1 是根据最终精度和召回率计算的(所有 类 的全局组合)。所以这与您在 my_f_micro
.
中计算的分数相匹配
希望它有意义。
更多解释,您可以在这里阅读答案:-
我正在使用 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
如您所见,sklearn
为 macro f1
提供 0.6041666666666666
。但是,它不等于2*0.725*0.566666666/(0.725+0.566666666)
,其中0.725
和0.566666666
是由sklearn
计算得到的macro precision
和macro recall
。
计算 'macro' 和 'micro' 平均值的过程有所不同。
如 documentation of f_score 中所示:
'micro': Calculate metrics globally by counting the total true positives, false negatives and false positives.
'macro': Calculate metrics for each label, and find their unweighted mean. This does not take label imbalance into account.
在宏中,所有 类 的召回率、精度和 f1 都是单独计算的,然后返回它们的平均值。因此,您不能指望将公式 def f(p, r)
应用于它们。因为它们与您想要的不一样。
在微观上,f1 是根据最终精度和召回率计算的(所有 类 的全局组合)。所以这与您在 my_f_micro
.
希望它有意义。
更多解释,您可以在这里阅读答案:-