使用scikit-learn的评估指标评估二元分类器的正确方法是什么?
给定y_test和y_pred作为真实和预测的标签,classification_report输出的F1分数不应该与f1_score生成的相同吗?
这是我做的操作:
print(classification_report(y_test, y_pred))
给出以下表格:
精确度 召回率 f1分数 支持数 0 0.49 0.18 0.26 204 1 0.83 0.96 0.89 877平均 / 总计 0.77 0.81 0.77 1081
然而,
print(f1_score(y_test, y_pred))
给出F1分数 = 0.89
现在,根据上述输出,这个模型的表现是F1分数 = 0.89,还是0.77?
回答:
简而言之,在你的情况下,f1分数是0.89,而加权平均f1分数是0.77。
查看sklearn.metrics.f1_score
的文档字符串:
F1分数可以解释为精确度和召回率的加权平均值,其中F1分数在1时达到最佳值,在0时达到最差值。精确度和召回率对F1分数的相对贡献是相等的。F1分数的公式为:: F1 = 2 * (精确度 * 召回率) / (精确度 + 召回率)在多类别和多标签的情况下,这是每个类别F1分数的加权平均值。
关键在于最后一句。如果你要查找每个类别的加权平均f1分数,那么你不应该将0/1二元分类输入到函数中。因此,例如,你可以这样做
f1_score(y_test + 1, y_pred + 1)# 0.77
如果类别标签不是0/1,那么它会被视为多类别指标(你关心所有精确度/召回率得分),而不是二元指标(你只关心正样本的精确度/召回率)。我同意这可能有点令人惊讶,但一般来说,0/1类别被视为二元分类的标记。
编辑:这里列出的一些行为自Scikit-learn 0.16起已被废弃——特别是关于二元与非二元分类的令人困惑的隐式假设。详见这个github讨论。