Accuracy不是评估分类器的有效性的唯一度量。另外两个有用的指标是precision和recall。这两个度量可提供二元分类器的性能特征的更多视角。

分类器的 Precision

Precision度量一个分类器的正确性。较高的精确度意味着更少的误报,而较低精度意味着更多的误报。这经常与recall相反,作为一种简单的方法来提高精度,以减少召回。

分类器的 Recall

召回度量分类器的完整性,或灵敏度。较高的召回意味着更少的假负,而较低的召回意味着更多的假负。提高召回率往往可以降低精确度,因为随着样本空间增大,precision增加变得越来越难达到。

F-measure Metric

准确率和召回可以组合产生一个单一的值称为F值,这是精确度和召回率的加权调和平均数。我发现F值大约和accuracy一样有用。或者换句话说,相对于精度和召回,F值大多是无用的,正如你将在下面看到的。

朴素贝叶斯分类器的准确率和召回率度量

NLTK度量模块提供的功能可以计算上述三个指标。但要做到这一点,你需要建立2套各分类标签:一个正确值的引用集,以及一个测试集作为观察值。下面是从以前的文章中,我们训练的朴素贝叶斯分类器代码的修改版本。这一次,不是测量精度,我们将为每个标签(正或负)收集的参考值和观测值,然后使用这些集来计算的朴素贝叶斯分类器的accuracy,precision 和 recall和F值。收集到的实际值是简单地使用枚举每个功能集的索引。

import collections
import nltk.metrics
from nltk.classify import NaiveBayesClassifier
from nltk.corpus import movie_reviews
 
def word_feats(words):
    return dict([(word, True) for word in words])
 
negids = movie_reviews.fileids('neg')
posids = movie_reviews.fileids('pos')
 
negfeats = [(word_feats(movie_reviews.words(fileids=[f])), 'neg') for f in negids]
posfeats = [(word_feats(movie_reviews.words(fileids=[f])), 'pos') for f in posids]
 
negcutoff = len(negfeats)*3/4
poscutoff = len(posfeats)*3/4
 
trainfeats = negfeats[:negcutoff] + posfeats[:poscutoff]
testfeats = negfeats[negcutoff:] + posfeats[poscutoff:]
print 'train on %d instances, test on %d instances' % (len(trainfeats), len(testfeats))
 
classifier = NaiveBayesClassifier.train(trainfeats)
refsets = collections.defaultdict(set)
testsets = collections.defaultdict(set)
 
for i, (feats, label) in enumerate(testfeats):
    refsets[label].add(i)
    observed = classifier.classify(feats)
    testsets[observed].add(i)
 
print 'pos precision:', nltk.metrics.precision(refsets['pos'], testsets['pos'])
print 'pos recall:', nltk.metrics.recall(refsets['pos'], testsets['pos'])
print 'pos F-measure:', nltk.metrics.f_measure(refsets['pos'], testsets['pos'])
print 'neg precision:', nltk.metrics.precision(refsets['neg'], testsets['neg'])
print 'neg recall:', nltk.metrics.recall(refsets['neg'], testsets['neg'])
print 'neg F-measure:', nltk.metrics.f_measure(refsets['neg'], testsets['neg'])

正、负评论的准确率和召回率

我发现结果相当有趣:

pos precision: 0.651595744681
pos recall: 0.98
pos F-measure: 0.782747603834
neg precision: 0.959677419355
neg recall: 0.476
neg F-measure: 0.636363636364
那么,这是什么意思呢?
  1. 几乎每一个是pos的文件被正确识别有98%的召回率。这意味着在POS类中极少数假负。
  2. 但是,给定一个POS分类的文件只有65%可能是正确的。不太好精确度将导致pos类有35%的假阳性。
  3.  标识为负任何文件是96%可能是正确的(高精度)。这意味着负类极少误报。 
  4. 但是,许多负的文件被错误分类。低召回原因为负标号52%的假阴性。 
  5. F值未提供任何有用的信息。拥有它并没有带来洞察力,如果没有它,我们将失去所有知识。(F-measure provides no useful information. There’s no insight to be gained from having it, and we wouldn’t lose any knowledge if it was taken away.)

用更好的特征选择来改善结果

对于上述结果一个可能的解释是,人们通常使用在负面评论中使用正面的评价词,但这个词前面有“不”(或其他一些负面的字),如“不是很大”。此外,由于分类器使用词袋模型,它假定每个字都是独立的,它不能得知“不是很大”是一种负面的。如果是这样的话,如果我们还要在多个词上训练的话,那么这些指标应该改善,我将在以后的文章探讨下一个话题。

另一种可能性是丰富的自然中性词,那种话是毫无情绪的。但分类器对待所有词是相同的,并且必须向每个字分配要么正要么负。因此,也许另有中性或无意义的词都被放置在POS类,因为分类不知道自己还能做些什么。如果是这样的话,如果我们消除了特征集中中性或无意义的词,只使用情感丰富的词进行分类的话,那么指标应该改善。这通常是利用信息增益,又名互信息的概念,以改善特征选择,这也是我在以后的文章将探讨的。

如果你有自己的理论来解释结果,或关于如何提高准确率和召回的想法,请分享在评论中。

原文:http://streamhacker.com/2010/05/17/text-classification-sentiment-analysis-precision-recall/

Logo

学大模型,用大模型上飞桨星河社区!每天8点V100G算力免费领!免费领取ERNIE 4.0 100w Token >>>

更多推荐