2

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

"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'] 

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

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

代码:

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])

输出:

<------------Correct and inccorrect predictions------------> 
Total Labels: 743 Predicted Labels: 522 Accuracy: 0.702557200538

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

4

3 回答 3

3

我制作了预测标签矩阵,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

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

于 2016-04-16T11:44:40.167 回答
2

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

[ 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 将与正确预测的 4 个类别中的0 个预测相同

这是一个错误。

这里有一个例子

>>> 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
于 2016-04-15T21:43:11.260 回答
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_]))
于 2020-11-04T14:52:38.563 回答