如何用scikit学习多类案例的精确度,召回率,准确度和f1分数?

new*_*hon 99 python nlp artificial-intelligence machine-learning scikit-learn

我正在处理情绪分析问题,数据看起来像这样:

label instances
    5    1190
    4     838
    3     239
    1     204
    2     127
Run Code Online (Sandbox Code Playgroud)

所以我的数据是不平衡的,因为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)
Run Code Online (Sandbox Code Playgroud)

第二:

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)
Run Code Online (Sandbox Code Playgroud)

第三:

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
Run Code Online (Sandbox Code Playgroud)

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

/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"
Run Code Online (Sandbox Code Playgroud)

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

ldi*_*rer 142

我认为关于哪些权重用于什么存在很多混淆.我不确定我确切地知道是什么困扰你所以我将涵盖不同的主题,忍受我;).

等级权重

class_weight参数的权重用于训练分类器.它们不用于计算您正在使用的任何指标:使用不同的类权重,数字将因为分类器不同而不同.

基本上在每个scikit-learn分类器中,类权重用于告诉您的模型一个类的重要性.这意味着在训练期间,分类器将进行额外的努力以正确地对具有高权重的类进行分类.
他们如何做到这一点是特定于算法的.如果您想了解SVC的工作原理以及doc对您没有意义,请随时提及.

指标

一旦你有了一个分类器,你想知道它的表现如何.在这里,你可以使用你所提到的指标:accuracy,recall_score,f1_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
Run Code Online (Sandbox Code Playgroud)

警告

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".
Run Code Online (Sandbox Code Playgroud)

你得到这个警告是因为你使用的是f1-score,召回和精确度,而没有定义它们应该如何计算!这个问题可以改写一下:从上面的分类报告中,你如何为f1分数输出一个全球数字?你可以:

  1. 取每个班级的f1分数的平均值:这是avg / total上面的结果.它也被称为宏观平均.
  2. 使用真阳性/假阴性等的全局计数来计算f1分数(您总结每个类的真阳性/假阴性的数量).阿卡平均.
  3. 计算f1分数的加权平均值.使用'weighted'在scikit学习会由支持类的权衡F1评分:越要素类有,更重要的F1的得分这个类在计算中.

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

你选择哪一个取决于你想要如何衡量分类器的性能:例如宏观平均不考虑类不平衡,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"))    
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.


won*_*id2 64

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

  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))
Run Code Online (Sandbox Code Playgroud)

这样,您最终会得到每个类的有形和可解释的数字.

| 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    |
Run Code Online (Sandbox Code Playgroud)

然后...

2.

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

  • 嘿,只是一个后续问题:你是如何使用`` precision_recall_fscore_support```打印标签的?标签是按订单打印的吗? (2认同)

Nik*_*sev 15

提出问题

回答"用不平衡数据进行多级分类应采用什么度量标准"的问题:Macro-F1-measure.宏精密和宏调用也可以使用,但它们并不这么容易解释为二进制classificaion,它们已经并入F值,和过量的指标复杂化的方法相比,参数调整,等等.

微平均对类不平衡敏感:如果你的方法,例如,作品好最常见的标签,完全打乱别人,微平均指标,显示效果不错.

加权平均不太适合不平衡数据,因为它按标签计数加权.此外,它太难以解释和不受欢迎:例如,在我强烈建议的下面非常详细的调查中没有提到这样的平均值:

Sokolova,Marina和Guy Lapalme."系统分析分类任务的绩效指标." 信息处理与管理45.4(2009):427-437.

特定于应用的问题

但是,回到你的任务,我将研究2个主题:

  1. 通常用于您的特定任务的指标 - 它允许(a)将您的方法与其他人进行比较,并了解您是否做错了什么,以及(b)不自己探索这个并重用其他人的发现;
  2. 您的方法的不同错误的成本 - 例如,您的应用程序的用例可能仅依赖于4和5星审查 - 在这种情况下,良好的指标应该只计算这2个标签.

常用指标. 通过阅读文献后我可以推断,有两个主要的评估指标:

  1. 准确性,例如在...中使用

Yu,April和Daryl Chang."使用Yelp业务的多类情绪预测."

(链接) - 请注意作者使用几乎相同的评级分布,见图5.

Pang,Bo和Lillian Lee."看星星:在评级量表上利用情感分类的阶级关系." 第43届计算语言学协会年会论文集.计算语言学协会,2005年.

(链接)

  1. MSE(或者,通常,平均绝对误差 - MAE) - 参见,例如,

Lee,Moontae和R. Grafe."餐厅评论的多类情绪分析." CS N 224(2010)的最终项目.

(链接) - 他们探索准确性和MSE,考虑到后者更好

Pappas,Nikolaos,Rue Marconi和Andrei Popescu-Belis."解释星星:基于方面的情感分析的加权多实例学习." 2014年自然语言处理经验方法会议记录.No. EPFL-CONF-200899.2014年

(链接) - 他们利用scikit-learn进行评估和基线方法,并说明他们的代码是可用的; 但是,我找不到它,所以如果你需要它,写信给作者,这项工作很新,似乎是用Python编写的.

不同错误的成本. 如果你更关心避免重大失误,例如协助一星级到五星级的审查或类似的事情,请看MSE; 如果差异很重要,但不是那么多,试试MAE,因为它不是方差; 否则保持准确性.

关于方法,而不是指标

尝试回归方法,例如SVR,因为它们通常优于多类分类器,如SVC或OVA SVM.


Vla*_*nov 12

首先,使用计数分析判断您的数据是否不平衡有点困难.例如:千分之一的正面观察只是一个噪音,错误或科学上的突破?你永远都不会知道.
因此,最好使用所有可用的知识并明智地选择其状态.

好的,如果它真的不平衡怎么办?
再一次 - 查看您的数据.有时您可以找到一两次观察乘以百次.有时创建这种假的一类观察是有用的.
如果所有数据都是干净的,则下一步是在预测模型中使用类权重.

那么多类指标呢?
根据我的经验,通常不使用任何指标.主要有两个原因.
第一:使用概率总是比使用实体预测更好(因为如果他们都给你相同的类,你怎么能用0.9和0.6预测分离模型?)
第二:比较你的预测模型和建立新的更容易仅取决于一个好的指标.
根据我的经验,我可以推荐loglossMSE(或只是均方误差).

如何修复sklearn警告?
只是简单地(正如杨杰注意到的)average用以下值之一覆盖参数:( 'micro'全局计算度量),'macro'(计算每个标签的度量)或'weighted'(与宏相同但具有自动权重).

f1_score(y_test, prediction, average='weighted')
Run Code Online (Sandbox Code Playgroud)

所有警告都是在调用具有默认average值的度量函数之后发生的,'binary'这对于多类预测是不合适的.
祝你好运,享受机器学习带来的乐趣!

编辑:
我发现另一个回答者建议切换到我不能同意的回归方法(例如SVR).据我记得,甚至没有多类回归这样的东西.是的,有多标签回归,这是非常不同的,是的,在某些情况下,有可能在回归和分类之间切换(如果类以某种方式排序),但这种情况非常罕见.

我推荐的(在scikit-learn范围内)是尝试另一种非常强大的分类工具:渐变增强,随机森林(我最喜欢的),KNeighbors等等.

之后,您可以计算预测之间的算术或几何平均值,并且大多数时候您将获得更好的结果.

final_prediction = (KNNprediction * RFprediction) ** 0.5
Run Code Online (Sandbox Code Playgroud)