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

5 投票
1 回答
4711 浏览
提问于 2025-04-17 07:09

我正在进行多分类的任务,但类别不平衡。

我发现F1分数总是比精确率和召回率的直接调和平均值要小,有时候F1分数甚至比精确率和召回率都要小。

顺便说一下,我用的是metrics.precision_score(y,pred)来计算精确率,其他的也是类似。

我知道微平均和宏平均的区别,并且通过使用precision_recall_fscore_support()的分类结果测试过它们不是微平均。

我不确定这是不是因为使用了宏平均,还是有其他原因?


下面是更新的详细结果:

样本数:75,特征数:250

使用的模型是MultinomialNB(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上存在的开放问题,编号#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的简写……

1 个回答

2

请你更新一下问题,附上以下代码的输出结果:

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

这样可以显示每个类别的准确率和召回率,还有支持度,这样我们就能理解平均值是怎么计算的,并判断这种情况是否合适。

撰写回答