如何使用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" 

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

我认为有哪些权重用于什么是非常混乱的。 我不确定我是否确切地知道什么困扰你,所以我将会涵盖不同的话题,并承担我的责任)。

class级权重

class_weight参数的权重用于训练分类器 。 它们不用于计算您使用的任何度量标准 :使用不同的类别权重,因为分类不同,数字将会不同。

基本上在每个scikit-learn分类器中,类的权重用来告诉你的模型一个类是多么重要。 这意味着在训练过程中,分类器将会做出额外的努力来对高权重的类进行适当的分类。
他们如何做是特定于algorithm的。 如果您想了解SVC的工作原理,而且文档对您没有意义,请随时提及。

指标

一旦你有一个分类器,你想知道它的performance如何。 在这里,您可以使用您提到的指标: accuracyrecall_scoref1_score

通常当class级分布不平衡时,准确性被认为是一个不好的select,因为它给那些预测最频繁的class级的模型带来高分。

我不会详细说明所有这些指标,但是请注意,除了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分数? 你可以:

  1. 取每个class的f1分数的avg / total :这就是上面的avg / total结果。 这也被称为macros观平均。
  2. 使用全球真阳性数/假阴性数等来计算f1分数(您将每个类的真阳性数/假阴性数相加)。 又名平均。
  3. 计算f1分数的加权平均值。 在scikit学习中使用'weighted'会在类的支持下权衡f1得分:一个类的元素越多,这个类在计算中的f1得分越重要。

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

你select哪一个取决于你想要衡量分类器的性能:例如,macros平均不考虑阶级失衡,而阶级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")) 

希望这可以帮助。

很多非常详细的答案在这里,但我不认为你正在回答正确的问题。 根据我的理解,有两个问题:

  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。

…你可以告诉不平衡的数据是否是一个问题。 如果评分较低的class级(class级1和class级2)低于class级较多的class级(class级4和class级5),那么你知道不平衡的数据实际上是一个问题,你可以采取相应的行动,在这个线程的一些其他答案中描述。 但是,如果您想要预测的数据中存在相同的类别分布,那么您的不平衡的训练数据就是数据的良好代表,因此,失衡是一件好事。

有问题

回答“使用不平衡数据进行多类分类时应使用什么度量标准:Macro-F1-measure”的问题。 Macro Precision和Macro Recall也可以使用,但是它们不像二进制分类那么容易解释,它们已经被纳入到F-measure中,并且过多的度量使方法比较,参数调整等变得复杂。

微观平均对类别失衡很敏感:例如,如果您的方法适用于最常见的标签并完全混淆了其他标签,则微观平均指标显示良好的结果。

加权平均不适合不平衡的数据,因为它按标签计数进行加权。 而且,它太难以解释和不受欢迎了,例如,在下面的非常详细的调查中,我没有提到这样一个平均值,我强烈build议通过这样的调查 :

Sokolova,Marina和Guy Lapalme。 “对分类任务的性能测量进行系统分析”。 信息处理与pipe理45.4(2009):427-437。

应用程序特定的问题

然而,回到你的任务,我会研究2个主题:

  1. (a)将您的方法与其他方法进行比较,并了解您是否做错了什么,以及(b)不要自己去探索,重复使用别人的发现;
  2. 您的方法的不同错误的代价 – 例如,您的应用程序的用例可能仅依赖于四星和五星评论 – 在这种情况下,良好的指标应该只计算这两个标签。

常用的指标。 通过查阅文献可以推断,有两个主要的评估指标:

  1. 准确性 ,例如在

余,四月,和Daryl Chang。 “使用Yelp商业进行多types情绪预测”

( 链接 ) – 请注意,作者的评分几乎相同,见图5。

庞博,莉莲李。 “看星:在评级量表上利用class级关系进行情感分类。” 第43届计算语言学学会年会。 计算语言学协会,2005年。

( 链接 )

  1. MSE (或者更less的情况下,平均绝对误差 – MAE ) – 例如,

Lee,Moontae和R. Grafe。 “餐厅评论的多types情绪分析” 来自CS N 224(2010)的最终项目。

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

帕帕斯,尼古劳斯,马可尼街和安德烈·波佩斯库 – 贝利斯。 “解释星星:基于方面情感分析的加权多实例学习”。 2014年会议在经验方法在自然语言处理会议。 EPFL-CONF-200899号。 2014年

( 链接 ) – 他们利用scikit学习评估和基准方法,并表示他们的代码是可用的; 然而,我找不到它,所以如果你需要的话,给作者写一封信,这个工作很新,似乎是用Python编写的。

不同的错误的代价 如果你更关心避免重大失误,比如说一星到五星的评论或类似的话,看看MSE; 如果差异很重要,但不是那么多,请尝试MAE,因为它不是方差; 否则保持准确。

关于方法,而不是度量

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

首先,使用计数分析来判断您的数据是否不平衡有点困难。 例如:千分之一的正面观察只是一个噪音,错误还是科学的突破? 你永远不会知道。
所以,最好是充分利用所有可用的知识,并select自己的状态。

好吧,如果真的不平衡呢?
再次 – 看看你的数据。 有时你可以find一两倍的观察乘以百倍。 有时候创build这个假的一个一级的观察是有用的。
如果所有的数据都是干净的下一步是在预测模型中使用类权重。

那么多类指标呢?
根据我的经验,通常不会使用任何度量标准。 主要有两个原因。
首先:使用概率总比使用可靠预测总是更好(因为如果它们同时给予同一个类别的话,还可以用0.9和0.6的预测来分离模型吗?)
第二:比较你的预测模型和build立新的预测模型要容易得多,这取决于一个好的指标。
从我的经验,我可以推荐logloss或MSE (或只是意味着平方误差)。

如何解决sklearn警告?
只是简单地(如杨杰注意到的)用这些值之一覆盖average参数: 'micro' (全局计算度量), 'macro' (计算每个标签的度量)或者'weighted' (与macros相同,但是具有自动权重)。

 f1_score(y_test, prediction, average='weighted') 

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

编辑:
我发现另一个回答者build议切换到回归方法(例如SVR),我不能同意。 据我所知,甚至没有多分类回归这样的事情。 是的,多标记回归是非常不同的,是的,在某些情况下,可以在回归和分类之间进行切换(如果类以某种方式sorting),但是很less见。

我会推荐(在scikit学习范围)是尝试另一个非常强大的分类工具: 梯度提升 , 随机森林 (我最喜欢), KNeighbors等等。

之后,你可以计算预测之间的算术或几何平均数,大部分时间你会得到更好的结果。

 final_prediction = (KNNprediction * RFprediction) ** 0.5