我正在处理一个情绪分析问题,数据看起来是这样的:
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"
我如何正确处理不平衡的数据,以便以正确的方式计算分类器的指标?
发布于 2015-07-23 07:44:13
我认为有很多关于哪些权重是用来做什么的困惑。我不确定我确切地知道是什么困扰着你,所以我将涵盖不同的主题,请耐心等待;)。
类权重
来自class_weight
参数的权重用于训练分类器。在计算您正在使用的的任何指标时,它们都不会使用:使用不同的类权重,仅仅因为分类器不同,数字就会不同。
基本上,在每个scikit-learn分类器中,类权重用于告诉您的模型一个类有多重要。这意味着在训练过程中,分类器将付出额外的努力来正确地对权重较高的类进行分类。
它们如何做到这一点是特定于算法的。如果您想了解SVC如何工作的详细信息,并且文档对您没有任何意义,请随时提及。
指标
一旦你有了一个分类器,你就想知道它的表现如何。这里你可以使用你提到的指标:accuracy
,recall_score
,f1_score
...
通常,当类别分布不平衡时,准确性被认为是一个糟糕的选择,因为它给只预测最频繁类别的模型打了高分。
我不会详细介绍所有这些指标,但请注意,除了accuracy
之外,它们自然应用于类级别:正如您在分类报告的print
中所看到的,它们是为每个类定义的。它们依赖于诸如true positives
或false 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分数输出one全局编号?您可以:
avg / total
结果。它也被称为宏评分,使用全局真阳性/假阴性计数来计算F1分数,等等(你可以对每一类的真阳性/假阴性的数量求和)。又名micro averaging.中使用'weighted'
将根据班级的支持来权衡F1分数:班级包含的元素越多,该班级在scikit中的F1分数就越重要
这是scikit learn中的3个选项,警告是你必须选择一个。因此,您必须为score方法指定一个average
参数。
你选择哪一个取决于你想要如何衡量分类器的性能:例如,宏平均没有考虑班级不平衡,1班的F1得分将与5班的F1得分一样重要。但是,如果你使用加权平均,你将获得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"))
希望这能有所帮助。
发布于 2015-07-23 20:35:37
这里有很多非常详细的答案,但我认为你没有回答正确的问题。根据我对问题的理解,有两个问题值得关注:
1.
你可以使用scikit中的大多数评分函数-学习多类问题和单类问题。示例:
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),那么您知道不平衡的数据实际上是一个问题,您可以采取相应的行动,如本主题中的一些其他答案所述。但是,如果您想要预测的数据中存在相同的类分布,则不平衡的训练数据是该数据的良好代表,因此,不平衡是一件好事。
发布于 2015-07-23 01:53:38
提出的问题
在回答“不平衡数据的多类分类应该使用什么度量”的问题时:宏-F1-measure。宏观精度和宏观召回也可以使用,但它们不像二进制分类那样容易解释,它们已经被合并到F-measure中,并且多余的度量使方法比较、参数调整等变得复杂。
微平均对类不平衡很敏感:例如,如果您的方法对最常见的标签很有效,而完全扰乱了其他标签,则微平均指标会显示出良好的结果。
加权平均不太适合不平衡的数据,因为它是通过标签的计数来加权的。此外,它太难解释和不受欢迎:例如,在下面非常详细的survey中没有提到这样的平均值,我强烈建议查看一下:
Sokolova,Marina和Guy Lapalme。“对分类任务的绩效指标进行系统分析。”信息处理与管理45.4 (2009):427-437。
应用程序特定问题
然而,回到你的任务,我会研究两个主题:
通常用于特定任务的
常用的指标。根据我阅读的文献可以推断,有两个主要的评估指标:
使用的
中
Yu,阿普丽尔和达里尔·张。“使用Yelp业务进行多类情绪预测。”
(link) -请注意,作者使用的评分分布几乎相同,请参见图5。
Pang,Bo和Lillian Lee。“看星星:利用等级关系进行情感分类。”计算语言学协会第四十三届年会论文集。计算语言学协会,2005年。
(link)
李,蒙泰和R.格拉夫。“带有餐厅评论的多类别情绪分析。”来自CS N 224 (2010)的期末项目。
(link) -他们同时探索准确性和均方误差,认为后者更好
Pappas,尼古拉斯,Rue Marconi和Andrei Popescu-Belis。“解释星星:基于方面的情感分析的加权多实例学习。”2014年自然语言处理经验方法会议论文集。不是的。EPFL-CONF-200899。2014年。
(link) -他们利用scikit learn进行评估和基线方法,并声明他们的代码是可用的;但是,我找不到它,所以如果你需要它,请给作者写封信,这项工作非常新,似乎是用Python语言编写的。
不同errors.的成本如果你更关心避免严重错误,例如评估1星到5星的评论或类似的东西,请查看MSE;如果差异很重要,但不是很重要,请尝试MAE,因为它不是diff的平方;否则,请保持准确性。
关于方法的,而不是关于指标的
尝试回归方法,例如SVR,因为它们通常比SVC或OVA等多类分类器性能更好。
https://stackoverflow.com/questions/31421413
复制相似问题