如何获得多类分类问题中每个类的精度分数?

Posted

技术标签:

【中文标题】如何获得多类分类问题中每个类的精度分数?【英文标题】:How to get the precision score of every class in a Multi class Classification Problem? 【发布时间】:2019-12-15 07:13:09 【问题描述】:

我正在使用 Scikit-learn 进行情绪分析分类。这有 3 个标签,正面、中性和负面。我的训练数据的形状是(14640, 15),其中

negative    9178
neutral     3099
positive    2363

我已经对数据进行了预处理并将bag-of-words字向量化技术应用于twitter的文本,因为还有许多其他属性,其大小为(14640, 1000)。 由于 Y,表示标签采用文本形式,因此我对其应用了 LabelEncoder。这就是我拆分数据集的方式 -

X_train, X_test, Y_train, Y_test = train_test_split(bow, Y, test_size=0.3, random_state=42)
print(X_train.shape,Y_train.shape)
print(X_test.shape,Y_test.shape)

out: (10248, 1000) (10248,)
     (4392, 1000) (4392,)

这是我的分类器

svc = svm.SVC(kernel='linear', C=1, probability=True).fit(X_train, Y_train) 
prediction = svc.predict_proba(X_test) 
prediction_int = prediction[:,1] >= 0.3 
prediction_int = prediction_int.astype(np.int) 
print('Precision score: ', precision_score(Y_test, prediction_int, average=None))
print('Accuracy Score: ', accuracy_score(Y_test, prediction_int))

out:Precision score:  [0.73980398 0.48169243 0.        ]
Accuracy Score:  0.6675774134790529
/usr/local/lib/python3.6/dist-packages/sklearn/metrics/classification.py:1437: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples.
  'precision', 'predicted', average, warn_for)

现在我不确定为什么第三个,精度分数是空白的?我申请了average=None,因为要为每个班级单独打分。另外,我不确定预测是否正确,因为我是为二进制分类编写的?你能帮我调试一下,让它变得更好。提前致谢。

【问题讨论】:

检查你的预测结果(测试数据),看起来没有一个数据点被预测为第三类 @SincoleBrans 这已经在答案中指出,并由其中的 cmets 中的 OP 确认。 【参考方案1】:

正如警告所解释的:

UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples.

您的 预测 prediction_int 中似乎您的 3 个类中的一个缺失(即您永远不会预测它);您可以轻松检查是否是这种情况

set(Y_test) - set(prediction_int)

这应该是空集,如果不是的话。

如果确实是这样,并且上面的操作给出12,最可能的原因是你的数据集不平衡(你有更多的negative样本),并且你没有要求分层拆分;将您的train_test_split 修改为

X_train, X_test, Y_train, Y_test = train_test_split(bow, Y, test_size=0.3, stratify=Y, random_state=42)

然后再试一次。

更新(在 cmets 之后):

事实证明,您有一个类别不平衡问题(而不是 编码 问题),这会阻止您的分类器成功预测您的第 3 类 (positive)。类不平衡本身就是一个巨大的子主题,并且提出了几种补救措施。尽管可以说更详细地超出了单个 SO 线程的范围,但您应该尝试的第一件事(在上述建议之上)是在分类器的定义中使用 class_weight='balanced' 参数,即:

svc = svm.SVC(kernel='linear', C=1, probability=True, class_weight='balanced').fit(X_train, Y_train) 

有关更多选项,请查看专用的imbalanced-learn Python 库(scikit-learn-contrib 项目的一部分)。

【讨论】:

这样做了,但是当我这样做时,set(Y_test) - set(prediction_int),给了我2,所以你的话很真实。接下来我将X_train, X_test, Y_train, Y_test = train_test_split(bow, Y, test_size=0.3, random_state=42) 设置为X_train, X_test, Y_train, Y_test = train_test_split(bow, Y, test_size=0.3, stratify=Y, random_state=42) 并运行它,但仍然没有结果,和以前一样,比如缺少最后一个精度和2。你觉得我的预测有什么问题吗? @DebPrakashChatterjee 那是因为实际上您没有任何 coding 问题(可以说是所有问题),而是 data 问题(阶级不平衡)。请注意,我只是建议“再试一次”(而不是“它应该工作”或其他什么) - 即我写的是正确的操作,但仍然不意味着它足够您的数据不平衡... 这很清楚,但是有什么选择吗?我知道这可能会失败,但我仍然想这样做,我即将完成我的最终项目。那么,请问,有没有成功的机会? 我知道了,我已经打印了prediction_int,结果它没有打印第三类[0 0 0 ... 1 0 0]。相当有问题。 @DebPrakashChatterjee 你的意思是,在使用了class_weights='balanced'?

以上是关于如何获得多类分类问题中每个类的精度分数?的主要内容,如果未能解决你的问题,请参考以下文章

精度分数错误:分类指标无法处理多类和连续目标的混合[重复]

使用 OpenCV 在多类分类中获取 SVM 分类分数

在 ML 分类问题中以高精度预测结果

有没有一种简单的方法来获得多类分类的混淆矩阵? (OneVsRest)

如何在 LogisticRegression 中获得概率和分类?

在 Keras 分类神经网络中进行精度交易以获得更好的召回率