如何在多标签分类中计算F1度量?

时间:2016-04-14 10:36:43

标签: python machine-learning scikit-learn units-of-measurement multilabel-classification

我正在研究句子类别检测问题。其中每个句子可以属于示例的多个类别:

if ( bool it = m_member.find (p->dwPID) == m_member.end())

我已经实现了一个可以预测多个类别的分类器。我有587个句子属于多个类别。我用两种方式计算了准确度分数:

  

如果一个例子的所有标签都预测到了吗?

"It has great sushi and even better service."
True Label:  [[ 0.  0.  0.  0.  0.  1.  0.  0.  0.  0.  0.  1.]]
Pred Label:  [[ 0.  0.  0.  0.  0.  1.  0.  0.  0.  0.  0.  1.]]
Correct Prediction!
Output:  ['FOOD#QUALITY' 'SERVICE#GENERAL'] 

输出:

print "<------------ZERO one ERROR------------>" 
print "Total Examples:",(truePred+falsePred) ,"True Pred:",truePred, "False Pred:", falsePred, "Accuracy:", truePred/(truePred+falsePred)
  

所有示例都正确预测了多少个标签?

<------------ZERO one ERROR------------>
Total Examples: 587 True Pred: 353 False Pred: 234 Accuracy: 0.60136286201

输出:

print "\n<------------Correct and inccorrect predictions------------>"
print "Total Labels:",len(total[0]),"Predicted Labels:", corrPred, "Accuracy:", corrPred/len(total[0])

问题: 这些是通过将预测得分与地面实况标签进行比较而计算的所有准确度得分但我想计算F1得分(使用微观平均),精确度和召回率。我有真实的标签,我需要将我的预测与那些地面真相标签相匹配。但是,我不知道如何处理这种类型的多标签分类问题。 我可以在python中使用scikit-learn或任何其他库吗?

3 个答案:

答案 0 :(得分:2)

查看sklearn已经提供的metrics并了解它们。它们不适用于多类多标签分类,因此您可以自己编写或将类别映射到标签。

[ 0.  0.  0.  0.  0.  1.  0.  0.  0.  0.  0.  1.] => 0
[ 0.  0.  0.  0.  0.  1.  0.  0.  0.  0.  0.  0.] => 1
...

您必须了解此解决方案的含义:如果一个示例有4个类,并且如果您有4个中的3个正确预测,则使用accuracy_score将相同作为正确预测的 0/4 的预测。

这是一个错误。

这是一个例子

>>> from sklearn.metrics import accuracy_score
>>> y_pred = [0, 2, 1, 3]
>>> y_true = [0, 1, 2, 3]
>>> accuracy_score(y_true, y_pred)
0.5

答案 1 :(得分:2)

我制作了预测标签的矩阵predictedlabel,我已经有了正确的类别来比较y_test中的结果。所以,我尝试了以下代码:

from sklearn.metrics import classification_report
from sklearn.metrics import f1_score
from sklearn.metrics import roc_auc_score

print "Classification report: \n", (classification_report(y_test, predictedlabel))
print "F1 micro averaging:",(f1_score(y_test, predictedlabel, average='micro'))
print "ROC: ",(roc_auc_score(y_test, predictedlabel))

,我得到了以下结果:

        precision    recall  f1-score   support

      0       0.74      0.93      0.82        57
      1       0.00      0.00      0.00         3
      2       0.57      0.38      0.46        21
      3       0.75      0.75      0.75        12
      4       0.44      0.68      0.54        22
      5       0.81      0.93      0.87       226
      6       0.57      0.54      0.55        48
      7       0.71      0.38      0.50        13
      8       0.70      0.72      0.71       142
      9       0.33      0.33      0.33        33
     10       0.42      0.52      0.47        21
     11       0.80      0.91      0.85       145

     av/total 0.71      0.78      0.74       743

 F1 micro averaging: 0.746153846154
 ROC:  0.77407943841

所以,我正在以这种方式计算我的结果!

答案 2 :(得分:1)

对于多标签方案,如果您的预测或地面真相标签的宽度不恒定,您可能还需要查看MultiLabelBinarizer。这实际上将它们转换为零和一的固定长度数组:

from sklearn.metrics import classification_report
from sklearn.preprocessing import MultiLabelBinarizer

y_true = [(12, 2, 4, 5),
          (5, 2),
          (12,)
         ]

y_pred = [(4, 5),
          (5, 2),
          (5, 4)
         ]

mlb = MultiLabelBinarizer()

y_true_binarized = mlb.fit_transform(y_true)
y_pred_binarized = mlb.transform(y_pred)

print(classification_report(y_true_binarized, y_pred_binarized, 
                            target_names=[str(cls) for cls in mlb.classes_]))