文本分类之情感分析– 去除低信息量的特征

当你的分类模型有数百个或数千个特征,由于是文本分类的情况下,许多(如果不是大多数)的特点是低信息量的,这是一个不错的选择。这些特征对所有类都是通用的,因此在分类过程中作出很小贡献。个别是无害的,但汇总的话,低信息量的特征会降低性能。

通过消除噪声数据给你的模型清晰度,这样就去除了低信息量特征。它可以把你从过拟合和维数灾难中救出来。当你只使用更高的信息特征,可以提高性能,同时也降低了模型的大小,从而导致伴随着更快的训练和分类的是,使用更少的内存的大小。删除特征似乎直觉错了,但请等你看到结果。

高信息量特征的选择

用同样的evaluate_classifier方法在以前的文章上使用二元组分类,我用10000最具信息量的词得到了以下的结果:

evaluating best word features
accuracy: 0.93
pos precision: 0.890909090909
pos recall: 0.98
neg precision: 0.977777777778
neg recall: 0.88
Most Informative Features
             magnificent = True              pos : neg    =     15.0 : 1.0
             outstanding = True              pos : neg    =     13.6 : 1.0
               insulting = True              neg : pos    =     13.0 : 1.0
              vulnerable = True              pos : neg    =     12.3 : 1.0
               ludicrous = True              neg : pos    =     11.8 : 1.0
                  avoids = True              pos : neg    =     11.7 : 1.0
             uninvolving = True              neg : pos    =     11.7 : 1.0
              astounding = True              pos : neg    =     10.3 : 1.0
             fascination = True              pos : neg    =     10.3 : 1.0
                 idiotic = True              neg : pos    =      9.8 : 1.0

把这个与使用了所有单词作为特征的第一篇文章中的情感分类相比:

evaluating single word features
accuracy: 0.728
pos precision: 0.651595744681
pos recall: 0.98
neg precision: 0.959677419355
neg recall: 0.476
Most Informative Features
         magnificent = True              pos : neg    =     15.0 : 1.0
         outstanding = True              pos : neg    =     13.6 : 1.0
           insulting = True              neg : pos    =     13.0 : 1.0
          vulnerable = True              pos : neg    =     12.3 : 1.0
           ludicrous = True              neg : pos    =     11.8 : 1.0
              avoids = True              pos : neg    =     11.7 : 1.0
         uninvolving = True              neg : pos    =     11.7 : 1.0
          astounding = True              pos : neg    =     10.3 : 1.0
         fascination = True              pos : neg    =     10.3 : 1.0
             idiotic = True              neg : pos    =      9.8 : 1.0

只用最好的10000个词,accuracy就超过了20%和POS precision增加了近24%,而负召回提高40%以上。这些都是巨大的增加,没有减少,POS召回和NEG精度甚至略有增加。下面是我得到这些结果的完整代码和解释。

import collections, itertools
import nltk.classify.util, nltk.metrics
from nltk.classify import NaiveBayesClassifier
from nltk.corpus import movie_reviews, stopwords
from nltk.collocations import BigramCollocationFinder
from nltk.metrics import BigramAssocMeasures
from nltk.probability import FreqDist, ConditionalFreqDist

def evaluate_classifier(featx):
    negids = movie_reviews.fileids('neg')
    posids = movie_reviews.fileids('pos')

    negfeats = [(featx(movie_reviews.words(fileids=[f])), 'neg') for f in negids]
    posfeats = [(featx(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:]

    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 'accuracy:', nltk.classify.util.accuracy(classifier, testfeats)
    print 'pos precision:', nltk.metrics.precision(refsets['pos'], testsets['pos'])
    print 'pos recall:', nltk.metrics.recall(refsets['pos'], testsets['pos'])
    print 'neg precision:', nltk.metrics.precision(refsets['neg'], testsets['neg'])
    print 'neg recall:', nltk.metrics.recall(refsets['neg'], testsets['neg'])
    classifier.show_most_informative_features()

def word_feats(words):
    return dict([(word, True) for word in words])

print 'evaluating single word features'
evaluate_classifier(word_feats)

word_fd = FreqDist()
label_word_fd = ConditionalFreqDist()

for word in movie_reviews.words(categories=['pos']):
    word_fd.inc(word.lower())
    label_word_fd['pos'].inc(word.lower())

for word in movie_reviews.words(categories=['neg']):
    word_fd.inc(word.lower())
    label_word_fd['neg'].inc(word.lower())

# n_ii = label_word_fd[label][word]
# n_ix = word_fd[word]
# n_xi = label_word_fd[label].N()
# n_xx = label_word_fd.N()

pos_word_count = label_word_fd['pos'].N()
neg_word_count = label_word_fd['neg'].N()
total_word_count = pos_word_count + neg_word_count

word_scores = {}

for word, freq in word_fd.iteritems():
    pos_score = BigramAssocMeasures.chi_sq(label_word_fd['pos'][word],
        (freq, pos_word_count), total_word_count)
    neg_score = BigramAssocMeasures.chi_sq(label_word_fd['neg'][word],
        (freq, neg_word_count), total_word_count)
    word_scores[word] = pos_score + neg_score

best = sorted(word_scores.iteritems(), key=lambda (w,s): s, reverse=True)[:10000]
bestwords = set([w for w, s in best])

def best_word_feats(words):
    return dict([(word, True) for word in words if word in bestwords])

print 'evaluating best word features'
evaluate_classifier(best_word_feats)

def best_bigram_word_feats(words, score_fn=BigramAssocMeasures.chi_sq, n=200):
    bigram_finder = BigramCollocationFinder.from_words(words)
    bigrams = bigram_finder.nbest(score_fn, n)
    d = dict([(bigram, True) for bigram in bigrams])
    d.update(best_word_feats(words))
    return d

print 'evaluating best words + bigram chi_sq word features'
evaluate_classifier(best_bigram_word_feats)

计算信息增益

要找到最具信息的特征,我们需要为每个词计算信息增益。分类的信息增益是一项度量一个常见的特征在一个特定的类和其他类中的对比。一个主要出现在正面电影评论中的词,很少在负面评论中出现就是具有高的信息量。例如,在电影评论中“magnificent”的存在是一个重要指标,表明是正向的。这使得“magnificent”是高信息量的词。注意,上面的信息量最大的特征并没有改变。这是有道理的,因为该观点是只使用最有信息量的特征而忽略其他。

一个是信息增益的最佳指标是卡方。 NLTK在度量标准数据包的BigramAssocMeasures类中包含有它。要使用它,首先我们需要计算每个词的频率:其整体频率及其各类别内的频率。用FreqDist来表示单词的整体频率,ConditionalFreqDist的条件是类别标签。一旦我们有了这些数字,我们就可以用BigramAssocMeasures.chi_sq函数为词汇计算评分,然后按分数排序,放入一个集合里,取前10000个。然后,我们把这些单词放到一个集合中,并在我们的特征选择函数中使用一组成员资格测试仅选择出现在集合的那些词。现在,基于这些高信息量的词,每个文件都被分类了。

显著的二元词组

上面的代码还评估了包含200个显著二元词组的搭配。下面是结果:

evaluating best words + bigram chi_sq word features
accuracy: 0.92
pos precision: 0.913385826772
pos recall: 0.928
neg precision: 0.926829268293
neg recall: 0.912
Most Informative Features
             magnificent = True              pos : neg    =     15.0 : 1.0
             outstanding = True              pos : neg    =     13.6 : 1.0
               insulting = True              neg : pos    =     13.0 : 1.0
              vulnerable = True              pos : neg    =     12.3 : 1.0
       (‘matt‘, ‘damon‘) = True              pos : neg    =     12.3 : 1.0
          (‘give‘, ‘us‘) = True              neg : pos    =     12.3 : 1.0
               ludicrous = True              neg : pos    =     11.8 : 1.0
             uninvolving = True              neg : pos    =     11.7 : 1.0
                  avoids = True              pos : neg    =     11.7 : 1.0
    (‘absolutely‘, ‘no‘) = True              neg : pos    =     10.6 : 1.0

这表明,只采用高信息量的词的时候二元组并没有多重要。在这种情况下,评估包括二元组或没有的区别的最好方法是看精度和召回。用二元组,你得到的每个类的更均匀的性能。如果没有二元组,准确率和召回率不太平衡。但差异可能取决于您的特定数据,所以不要假设这些观察总是正确的。

改善特征选择

这里最大的教训是,改善特征选择会改善你的分类器。降维是提高分类器性能的你可以做的最好的事情之一。如果数据不增加价值,抛弃也没关系的。特别推荐的是有时数据实际上使你的模型变得更糟。

原文:http://streamhacker.com/2010/06/16/text-classification-sentiment-analysis-eliminate-low-information-features/

时间: 2024-11-08 06:11:20

文本分类之情感分析– 去除低信息量的特征的相关文章

文本分类之情感分析 – 朴素贝叶斯分类器

情感分析正成为研究和社交媒体分析的热点领域,尤其是在用户评论和微博上.它是文本挖掘的一种特殊情况,一般关注在识别正反观点上,虽然它常不很准确,它仍然是有用的.为简单起见(因为训练数据容易获取),我将重点放在2个可能的情感分类:积极的和消极的. NLTK 朴素贝叶斯分类 NLTK附带了所有你需要的情感分析的入手的东西:一份带有分为POS和NEG类别的电影评论语料,以及一些可训练分类器.我们先从一个简单的NaiveBayesClassifier作为基准,用布尔特征提取. 词袋特征提取 所有NLTK分

文本分类之情感分析– 停用词和惯用语

改善特征提取往往可以对分类的accuracy(和precision和召回率)有显著的正面影响.在本文中,我将评估word_feats的两项修改特征提取的方法: 过滤停用词 包含二元语法搭配 为了有效地做到这一点,我们将修改前面的代码,这样我们就可以使用任意的特征提取函数,它接收一个文件中的词,并返回特征字典.和以前一样,我们将使用这些特征来训练朴素贝叶斯分类器. import collections import nltk.classify.util, nltk.metrics from nlt

文本分类之情感分析– 准确率和召回率

Accuracy不是评估分类器的有效性的唯一度量.另外两个有用的指标是precision和recall.这两个度量可提供二元分类器的性能特征的更多视角. 分类器的 Precision Precision度量一个分类器的正确性.较高的精确度意味着更少的误报,而较低精度意味着更多的误报.这经常与recall相反,作为一种简单的方法来提高精度,以减少召回. 分类器的 Recall 召回度量分类器的完整性,或灵敏度.较高的召回意味着更少的假负,而较低的召回意味着更多的假负.提高召回率往往可以降低精确度,

谷歌做了45万次不同类型的文本分类后,总结出一个通用的“模型选择算法”...

谷歌做了45万次不同类型的文本分类后,总结出一个通用的"模型选择算法"... 2018年07月25日 17:43:55 阅读数:6 新智元报道 来源:developers.google.com 编译:肖琴.大明 [导读]谷歌官方推出"文本分类"指南教程.为了最大限度地简化选择文本分类模型的过程,谷歌在进行大约450K的文本分类实验后,总结出一个通用的"模型选择算法",并附上一个完整的流程图,非常实用. 文本分类(Text classificati

情感分析简述

情感分析,我研究了也有半年有余了,号称看遍ACL上关于情感分析的论文,但是到目前还没有什么成就的.以下是我为一位同学毕业设计写的情感分析方面的综述,引用的论文基本上是ACL和COLING还有EMNLP上历年关于情感分析的论文,本文应该学术性比较强一点,本文虽不打算发表,但由于将来可能还有用,以及关于学术上的原因,请大家如果要引用请务必标明出处(http://blog.sina.com.cn/s/blog_48f3f8b10100irhl.html). 概述 情感分析自从2002年由Bo Pang

文本分类:survey

作者:尘心链接:https://zhuanlan.zhihu.com/p/76003775 简述 文本分类在文本处理中是很重要的一个模块,它的应用也非常广泛,比如:垃圾过滤,新闻分类,词性标注等等.它和其他的分类没有本质的区别,核心方法为首先提取分类数据的特征,然后选择最优的匹配,从而分类.但是文本也有自己的特点,根据文本的特点,文本分类的一般流程为:1.预处理:2.文本表示及特征选择:3.构造分类器:4.分类. 通常来讲,文本分类任务是指在给定的分类体系中,将文本指定分到某个或某几个类别中.被

step by step带你RCNN文本分类

本文参考原文-http://bjbsair.com/2020-03-25/tech-info/6304/ **传统文本分类 ** 之前介绍的都是属于深度神经网络框架的,那么在Deep Learning出现或者风靡之前,文本分类是怎么做的呢? 传统的文本分类工作主要分为三个过程:特征工程.特征选择和不同分类机器学习算法. 1.1 特征工程 对于文本数据的特征工程来说,最广泛使用的功能是bag-of-words.tf-idf等.此外,还可以设计一些更复杂的特征,比如词性标签.名词短语以及tree k

LSTM 文本情感分析/序列分类 Keras

LSTM 文本情感分析/序列分类 Keras 请参考 http://spaces.ac.cn/archives/3414/ neg.xls是这样的 pos.xls是这样的neg=pd.read_excel('neg.xls',header=None,index=None) pos=pd.read_excel('pos.xls',header=None,index=None) #读取训练语料完毕 pos['mark']=1 neg['mark']=0 #给训练语料贴上标签 pn=pd.concat

主题模型及其在文本情感分析中的应用

随着Web2.0技术的出现和发展,互联网上(包括门户网站.电子商务网站.社交网站.音/视频分享网站.论坛.博客.微博等)产生了海量的.由用户发表的对于诸如人物.事件.产品等目标实体的评论信息.例如,下面这两个短文本评论:(1)“比较了多个智能手机后选择了8150,性价比还可以.另外,就是考虑到它是3.7的屏幕,大小比较合适,否则携带很不方便.”(京东商城用户,2011.11.25):(2)“我以前在杭州做二手房地产,用温州炒房客的话说:全世界房价降了,杭州的房价永远不会降,因为他们有一道坚不可摧