如何使用 scikit 学习计算多类案例的精度、召回率、准确性和 f1 分数?

新手上路,请多包涵

我正在处理情绪分析问题,数据如下所示:

 label instances
    5    1190
    4     838
    3     239
    1     204
    2     127

所以我的数据是不平衡的,因为 1190 instances 被标记为 5 。对于使用 scikit 的 SVC 的分类我。问题是我不知道如何以正确的方式平衡我的数据,以便准确计算多类案例的精度、召回率、准确性和 f1 分数。所以我尝试了以下方法:

第一的:

     wclf = SVC(kernel='linear', C= 1, class_weight={1: 10})
    wclf.fit(X, y)
    weighted_prediction = wclf.predict(X_test)

print 'Accuracy:', accuracy_score(y_test, weighted_prediction)
print 'F1 score:', f1_score(y_test, weighted_prediction,average='weighted')
print 'Recall:', recall_score(y_test, weighted_prediction,
                              average='weighted')
print 'Precision:', precision_score(y_test, weighted_prediction,
                                    average='weighted')
print '\n clasification report:\n', classification_report(y_test, weighted_prediction)
print '\n confussion matrix:\n',confusion_matrix(y_test, weighted_prediction)

第二:

 auto_wclf = SVC(kernel='linear', C= 1, class_weight='auto')
auto_wclf.fit(X, y)
auto_weighted_prediction = auto_wclf.predict(X_test)

print 'Accuracy:', accuracy_score(y_test, auto_weighted_prediction)

print 'F1 score:', f1_score(y_test, auto_weighted_prediction,
                            average='weighted')

print 'Recall:', recall_score(y_test, auto_weighted_prediction,
                              average='weighted')

print 'Precision:', precision_score(y_test, auto_weighted_prediction,
                                    average='weighted')

print '\n clasification report:\n', classification_report(y_test,auto_weighted_prediction)

print '\n confussion matrix:\n',confusion_matrix(y_test, auto_weighted_prediction)

第三:

 clf = SVC(kernel='linear', C= 1)
clf.fit(X, y)
prediction = clf.predict(X_test)

from sklearn.metrics import precision_score, \
    recall_score, confusion_matrix, classification_report, \
    accuracy_score, f1_score

print 'Accuracy:', accuracy_score(y_test, prediction)
print 'F1 score:', f1_score(y_test, prediction)
print 'Recall:', recall_score(y_test, prediction)
print 'Precision:', precision_score(y_test, prediction)
print '\n clasification report:\n', classification_report(y_test,prediction)
print '\n confussion matrix:\n',confusion_matrix(y_test, prediction)

F1 score:/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:676: DeprecationWarning: The default `weighted` averaging is deprecated, and from version 0.18, use of precision, recall or F-score with multiclass or multilabel data or pos_label=None will result in an exception. Please set an explicit value for `average`, one of (None, 'micro', 'macro', 'weighted', 'samples'). In cross validation use, for instance, scoring="f1_weighted" instead of scoring="f1".
  sample_weight=sample_weight)
/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:1172: DeprecationWarning: The default `weighted` averaging is deprecated, and from version 0.18, use of precision, recall or F-score with multiclass or multilabel data or pos_label=None will result in an exception. Please set an explicit value for `average`, one of (None, 'micro', 'macro', 'weighted', 'samples'). In cross validation use, for instance, scoring="f1_weighted" instead of scoring="f1".
  sample_weight=sample_weight)
/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:1082: DeprecationWarning: The default `weighted` averaging is deprecated, and from version 0.18, use of precision, recall or F-score with multiclass or multilabel data or pos_label=None will result in an exception. Please set an explicit value for `average`, one of (None, 'micro', 'macro', 'weighted', 'samples'). In cross validation use, for instance, scoring="f1_weighted" instead of scoring="f1".
  sample_weight=sample_weight)
 0.930416613529

但是,我收到这样的警告:

 /usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:1172:
DeprecationWarning: The default `weighted` averaging is deprecated,
and from version 0.18, use of precision, recall or F-score with
multiclass or multilabel data or pos_label=None will result in an
exception. Please set an explicit value for `average`, one of (None,
'micro', 'macro', 'weighted', 'samples'). In cross validation use, for
instance, scoring="f1_weighted" instead of scoring="f1"

我怎样才能正确处理我的不平衡数据,以便以正确的方式计算分类器的指标?

原文由 new_with_python 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 509
2 个回答

我认为对于哪些权重用于什么存在很多混淆。我不确定我是否确切地知道是什么困扰着您,所以我将涵盖不同的主题,请耐心等待 ;)。

班级权重

来自 class_weight 参数的权重用于 训练分类器。它们 不用于计算您正在使用的任何指标:对于不同的类别权重,数字会有所不同,这仅仅是因为分类器不同。

基本上在每个 scikit-learn 分类器中,类别权重用于告诉您的模型类别的重要性。这意味着在训练期间,分类器将付出额外的努力来正确分类具有高权重的类。

他们如何做到这一点是特定于算法的。如果您想了解有关 SVC 如何工作的详细信息并且该文档对您没有意义,请随时提及。

指标

有了分类器后,您想知道它的性能如何。在这里你可以使用你提到的指标: accuracyrecall_scoref1_score

通常当类别分布不平衡时,准确性被认为是一个糟糕的选择,因为它会给仅预测最频繁类别的模型打高分。

我不会详细说明所有这些指标,但请注意,除了 accuracy 之外,它们自然地应用于类级别:正如您在分类报告中看到的 print 为每个类定义。它们依赖于诸如 true positivesfalse negative 之类的概念,这些概念需要定义哪个类是 类。

              precision    recall  f1-score   support

          0       0.65      1.00      0.79        17
          1       0.57      0.75      0.65        16
          2       0.33      0.06      0.10        17
avg / total       0.52      0.60      0.51        50

警告

F1 score:/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:676: DeprecationWarning: The
default `weighted` averaging is deprecated, and from version 0.18,
use of precision, recall or F-score with multiclass or multilabel data
or pos_label=None will result in an exception. Please set an explicit
value for `average`, one of (None, 'micro', 'macro', 'weighted',
'samples'). In cross validation use, for instance,
scoring="f1_weighted" instead of scoring="f1".

您收到此警告是因为您使用的是 f1 分数、召回率和精度,但没有定义它们的计算方式!这个问题可以换个说法:从上面的分类报告中,你如何为 f1-score 输出 一个 全局数字?你可以:

  1. 取每个班级的 f1 分数的平均值:即上面的 avg / total 结果。它也称为 平均。
  2. 使用真阳性/假阴性等的全局计数计算 f1-score(您将每个类别的真阳性/假阴性的数量相加)。又名 平均。
  3. 计算 f1 分数的加权平均值。在 scikit-learn 中使用 'weighted' 将通过类的支持权衡 f1-score:一个类具有的元素越多,该类的 f1-score 在计算中就越重要。

这些是 scikit-learn 中的 3 个选项,警告说你 必须选择一个。所以你必须为 score 方法指定一个 average 参数。

你选择哪一个取决于你想如何衡量分类器的性能:例如宏平均不考虑类别不平衡,类别 1 的 f1 分数将与类别的 f1 分数一样重要5. 但是,如果您使用加权平均,您将更加重视第 5 类。

这些指标中的整个参数规范目前在 scikit-learn 中不是很清楚,根据文档,它会在 0.18 版中变得更好。他们正在删除一些不明显的标准行为,并发出警告,以便开发人员注意到它。

计算分数

我想提的最后一件事(如果您知道,请随意跳过它)是只有在分类 器从未见过 的数据上计算分数才有意义。这一点非常重要,因为您在用于拟合分类器的数据上获得的任何分数都是完全不相关的。

这是一种使用 StratifiedShuffleSplit 的方法,它可以随机拆分数据(洗牌后)以保留标签分布。

 from sklearn.datasets import make_classification
from sklearn.cross_validation import StratifiedShuffleSplit
from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score, classification_report, confusion_matrix

# We use a utility to generate artificial classification data.
X, y = make_classification(n_samples=100, n_informative=10, n_classes=3)
sss = StratifiedShuffleSplit(y, n_iter=1, test_size=0.5, random_state=0)
for train_idx, test_idx in sss:
    X_train, X_test, y_train, y_test = X[train_idx], X[test_idx], y[train_idx], y[test_idx]
    svc.fit(X_train, y_train)
    y_pred = svc.predict(X_test)
    print(f1_score(y_test, y_pred, average="macro"))
    print(precision_score(y_test, y_pred, average="macro"))
    print(recall_score(y_test, y_pred, average="macro"))

原文由 ldirer 发布,翻译遵循 CC BY-SA 4.0 许可协议

这里有很多非常详细的答案,但我认为您没有回答正确的问题。据我了解这个问题,有两个问题:

  1. 如何对多类问题进行评分?
  2. 如何处理不平衡数据?

1.

您可以将 scikit-learn 中的大多数评分函数用于多类问题和单类问题。前任。:

 from sklearn.metrics import precision_recall_fscore_support as score

predicted = [1,2,3,4,5,1,2,1,1,4,5]
y_test = [1,2,3,4,5,1,2,1,1,4,1]

precision, recall, fscore, support = score(y_test, predicted)

print('precision: {}'.format(precision))
print('recall: {}'.format(recall))
print('fscore: {}'.format(fscore))
print('support: {}'.format(support))

通过这种方式,您最终会得到每个类的有形且可解释的数字。

 | Label | Precision | Recall | FScore | Support |
|-------|-----------|--------|--------|---------|
| 1     | 94%       | 83%    | 0.88   | 204     |
| 2     | 71%       | 50%    | 0.54   | 127     |
| ...   | ...       | ...    | ...    | ...     |
| 4     | 80%       | 98%    | 0.89   | 838     |
| 5     | 93%       | 81%    | 0.91   | 1190    |

然后…

2.

…您可以判断不平衡数据是否是一个问题。如果代表较少的类别(第 1 类和第 2 类)的得分低于具有更多训练样本的类别(第 4 类和第 5 类),那么您就知道不平衡数据实际上是一个问题,您可以采取相应的行动,因为在此线程的其他一些答案中进行了描述。但是,如果您要预测的数据中存在相同类别的分布,则您的不平衡训练数据可以很好地代表数据,因此,不平衡是一件好事。

原文由 wonderkid2 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏