F1 小于 Scikit-learn 中的精度和召回率

Posted

技术标签:

【中文标题】F1 小于 Scikit-learn 中的精度和召回率【英文标题】:F1 smaller than both precision and recall in Scikit-learn 【发布时间】:2012-01-07 05:45:33 【问题描述】:

我正在做多类分类,类别不平衡。

我注意到 f1 总是小于准确率和召回率的直接调和平均值,在某些情况下,f1 甚至小于准确率和召回率。

仅供参考,我打电话给metrics.precision_score(y,pred) 询问精度等等。

我知道微观/宏观平均值的差异,并使用precision_recall_fscore_support()的类别结果测试它们不是微观的。

不确定是使用了宏观平均还是其他原因?


更新详细结果如下:

n_samples:75,n_features:250

多项式NB(alpha=0.01, fit_prior=True)

2 倍简历:

第一次运行:

F1:        0.706029106029
Precision: 0.731531531532
Recall:    0.702702702703

         precision    recall  f1-score   support

      0       0.44      0.67      0.53         6
      1       0.80      0.50      0.62         8
      2       0.78      0.78      0.78        23

avg / total       0.73      0.70      0.71        37

第二次运行:

F1:        0.787944219523
Precision: 0.841165413534
Recall:    0.815789473684

         precision    recall  f1-score   support

      0       1.00      0.29      0.44         7
      1       0.75      0.86      0.80         7
      2       0.82      0.96      0.88        24

avg / total       0.84      0.82      0.79        38

总体:

Overall f1-score:   0.74699 (+/- 0.02)
Overall precision:  0.78635 (+/- 0.03)
Overall recall:     0.75925 (+/- 0.03)

来自Scholarpedia的关于微观/宏观平均的定义:

在多标签分类中,计算一个最简单的方法 跨类别的总分是对所有类别的分数进行平均 二进制任务。结果分数称为宏观平均召回率, 精度、F1 等。另一种平均方法是对 TP、FP、 首先对所有类别进行TN、FN和N,然后计算每个类别 上述指标。结果分数称为微平均。 宏观平均对每个类别赋予相同的权重,并且通常 由系统在稀有类别( 多数)在类似幂律的分布中。微平均给出了一个 每个文档的权重相等,并且通常由系统的 在最常见的类别上表现出色。


它是 Github 中的当前open issue,#83。


以下示例演示了微观、宏观和加权(当前在 Scikit-learn 中)平均可能有何不同:

y    = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2]
pred = [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 2, 0, 1, 2, 2, 2, 2]

混淆矩阵:

[[9 3 0]
 [3 5 1]
 [1 1 4]]

Wei Pre: 0.670655270655
Wei Rec: 0.666666666667
Wei F1 : 0.666801346801
Wei F5 : 0.668625356125

Mic Pre: 0.666666666667
Mic Rec: 0.666666666667
Mic F1 : 0.666666666667
Mic F5 : 0.666666666667

Mac Pre: 0.682621082621
Mac Rec: 0.657407407407
Mac F1 : 0.669777037588
Mac F5 : 0.677424801371

上面的F5是F0.5的简写...

【问题讨论】:

如果我们是macro-averaging,意思是对每个观察值计算precision、recall和F1-score,然后计算所有precision值、recall值和F1-score的平均值返回值。所以最终准确率和最终召回率的调和平均值肯定不会等同于最终的 F1-score 【参考方案1】:

您能否使用以下输出更新您的问题:

>>> from sklearn.metrics import classification_report
>>> print classification_report(y_true, y_predicted)

这将显示每个单独类别的精度和召回率以及支持,从而帮助我们了解平均的工作原理并确定这是否是适当的行为。

【讨论】:

检查了结果。似乎既没有使用微观也没有使用宏。并且在第二次运行中出现了小于精度和召回率的奇怪行为 F1,并且刚刚意识到,这也部分是由调和平均数的性质引起的,其中 Harmonic(1.00,0.29)=0.44 与我的直接直觉相反,但确实如此。但是,非微观/宏观的方法也可能是另一个原因。 实际的 scikit-learn 实现是跨类的加权平均,其中权重是支持(每个类中的样本数)。所以对我来说,这听起来像是微平均,但我还没有计算出细节,所以它可能根本不等价。如果您想使用跨类平均的 TP、FP、TN、FN 贡献微平均的真正实现,请随时发送拉取请求。 我会更仔细地研究代码并弄清楚。 :) 我对 Python 很陌生,所以,看看将来是否会发生这种情况。无论如何,我对你们在 Scikit-learn 中所做的工作非常感兴趣并高度赞赏。 发现此问题跟踪github.com/scikit-learn/scikit-learn/issues/83。我尝试了一个例子,对于 n>2,当前的计算确实既不是宏观的也不是微观的。带来的棘手行为是 f1 确实我忘记了这个问题。我的记忆不再持续超过几个月。我猜这要怪 twitter 引起的注意力障碍......所以确实请随时加紧提交微平均的拉取请求(我认为宏观平均没有那么有用,但它更容易实现)。

以上是关于F1 小于 Scikit-learn 中的精度和召回率的主要内容,如果未能解决你的问题,请参考以下文章

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

如何计算聚类中的精度和召回率?

scikit-learn 分类指标中的 classification_report 与 f1_score

如何在 scikit-learn 的分类问题中为 F1 分数做 GridSearchCV?

f1score一般为多大

scikit-learn 在多标签分类中计算 F1