如何获得多 class 分类问题中每个 class 的精度分数?
How to get the precision score of every class in a Multi class Classification Problem?
我正在使用 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,)
这是我的class制作者
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
,因为要为每个 class 做一个单独的精度分数。另外,我不确定这个预测是否正确,因为我写它是为了二进制 classification?你能帮我调试一下让它变得更好吗?提前致谢。
正如警告所解释的那样:
UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples.
您的 预测 prediction_int
中,您的 3 个 class 似乎 缺失(即你永远不会预测它);您可以使用
轻松检查是否属于这种情况
set(Y_test) - set(prediction_int)
如果不是,则应该是空集{}
。
如果确实是这样,并且上面的操作给出{1}
或{2}
,最可能的原因是你的数据集不平衡(你有更多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)
然后重试。
更新(评论后):
事实证明,你有一个 class 不平衡问题(而不是 coding 问题),它阻止你的 classifier 成功预测你的第三 class (positive
)。 Class 不平衡本身就是一个巨大的子主题,并且提出了几种补救措施。虽然进入更多细节可以说超出了单个 SO 线程的范围,但您应该尝试的第一件事(在上述建议之上)是在 class 的定义中使用 class_weight='balanced'
参数过滤器,即:
svc = svm.SVC(kernel='linear', C=1, probability=True, class_weight='balanced').fit(X_train, Y_train)
有关更多选项,请查看专门的 imbalanced-learn Python library (part of the scikit-learn-contrib 项目)。
我正在使用 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,)
这是我的class制作者
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
,因为要为每个 class 做一个单独的精度分数。另外,我不确定这个预测是否正确,因为我写它是为了二进制 classification?你能帮我调试一下让它变得更好吗?提前致谢。
正如警告所解释的那样:
UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples.
您的 预测 prediction_int
中,您的 3 个 class 似乎 缺失(即你永远不会预测它);您可以使用
set(Y_test) - set(prediction_int)
如果不是,则应该是空集{}
。
如果确实是这样,并且上面的操作给出{1}
或{2}
,最可能的原因是你的数据集不平衡(你有更多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)
然后重试。
更新(评论后):
事实证明,你有一个 class 不平衡问题(而不是 coding 问题),它阻止你的 classifier 成功预测你的第三 class (positive
)。 Class 不平衡本身就是一个巨大的子主题,并且提出了几种补救措施。虽然进入更多细节可以说超出了单个 SO 线程的范围,但您应该尝试的第一件事(在上述建议之上)是在 class 的定义中使用 class_weight='balanced'
参数过滤器,即:
svc = svm.SVC(kernel='linear', C=1, probability=True, class_weight='balanced').fit(X_train, Y_train)
有关更多选项,请查看专门的 imbalanced-learn Python library (part of the scikit-learn-contrib 项目)。