使用python+机器学习方法进行情感分析(详细步骤) - 51CTO.COM

标签: | 发表时间:2018-01-05 17:49 | 作者:
出处:http://bigdata.51cto.com

【限时免费】年底最强一次云计算大会,看传统、社区、互联网企业如何碰撞?


不是有词典匹配的方法了吗?怎么还搞多个机器学习方法。

因为词典方法和机器学习方法各有千秋。

机器学习的方法精确度更高,因为词典匹配会由于语义表达的丰富性而出现很大误差,而机器学习方法不会。而且它可使用的场景更多样。无论是主客观分类还是正负面情感分类,机器学习都可以完成任务。而无需像词典匹配那样要深入到词语、句子、语法这些层面。

而词典方法适用的语料范围更广,无论是手机、电脑这些商品,还是书评、影评这些语料,都可以适用。但机器学习则极度依赖语料,把手机语料训练出来的的分类器拿去给书评分类,那是注定要失败的。

使用机器学习进行情感分析,可以换一个相同意思的说法,就是用有监督的(需要人工标注类别)机器学习方法来对文本进行分类。

这点与词典匹配有着本质的区别。词典匹配是直接计算文本中的情感词,得出它们的情感倾向分值。而机器学习方法的思路是先选出一部分表达积极情感的文本和一部分表达消极情感的文本,用机器学习方法进行训练,获得一个情感分类器。再通过这个情感分类器对所有文本进行积极和消极的二分分类。最终的分类可以为文本给出0或1这样的类别,也可以给出一个概率值,比如”这个文本的积极概率是90%,消极概率是10%“。

Python 有良好的程序包可以进行情感分类,那就是Python 自然语言处理包,Natural Language Toolkit ,简称NLTK 。

NLTK 当然不只是处理情感分析,NLTK 有着整套自然语言处理的工具,从分词到实体识别,从情感分类到句法分析,完整而丰富,功能强大。实乃居家旅行,越货杀人之必备良药。

两本NLTK 的参考书,非常好用。一本是《Python 自然语言处理》,这是《Natural Language Processing with Python》的中文翻译版,是志愿者翻译没有出版社出版的,开源精神万岁!另一本是《Python Text Processing with NLTK 2.0 Cookbook》,这本书写得清晰明了,虽然是英文版的,看起来也很舒服。特别值得一提的是,该书作者Jacob 就是NLTK 包的主要贡献者之一。而且他的博客中有一系列的文章是关于使用机器学习进行情感分类的,我的代码可以说是完全基于他的,在此表示我的感谢。

其实还有国外作者也被他启发,用Python 来处理情感分类。比如这篇文章,写得特别详细认真,也是我重点参考的文章,他的代码我也有所借用。

Jacob 在文章中也有提到,近段时间NLTK 新增的scikit-learn 的接口,使得它的分类功能更为强大好用了,可以用很多高端冷艳的分类算法了。于是我又滚过去看scikit-learn 。简直是天赐我好工具,妈妈再也不用担心我用不了机器学习啦!

有了scikit-learn 的接口,NLTK 做分类变得比之前更简单快捷,但是相关的结合NLTK 和 sciki-learn 的文章实在少,这篇文章是仅有的讲得比较详细的把两者结合的,在此也表示感谢。

但对于我而言还是有点不够的,因为中文和英文有一定的差别,而且上面提到的一些博客里面的代码也是需要改动的。终于把一份代码啃完之后,能写出一个跑得通的中文情感分类代码了。接下来会介绍它的实现思路和具体代码。

在这个系列的文章里面,机器学习都可以认为是有监督的分类方法。

总体流程如图:

\
图1:机器学习的流程和结构(摘自《Natural Language Processing with Python》)

一、有监督意味着需要人工标注,需要人为的给文本一个类标签。

比如我有5000条商品评论,如果我要把这些评论分成积极和消极两类。那我就可以先从里面选2000条评论,然后对这2000条数据进行人工标注,把这2000条评论标为“积极”或“消极”。这“积极”和“消极”就是类标签。

假设有1000条评论被标为“积极”,有1000条评论被标为“消极”。(两者数量相同对训练分类器是有用的,如果实际中数量不相同,应该减少和增加数据以使得它们数量相同)

二、之后就要选择特征。

特征就是分类对象所展现的部分特点,是实现分类的依据。我们经常会做出分类的行为,那我们依据些什么进行分类呢?

举个例子,如果我看到一个年轻人,穿着新的正装,提着崭新的公文包,快步行走,那我就会觉得他是一个刚入职的职场新人。在这里面,“崭新”,“正装”,“公文包”,“快步行走”都是这个人所展现出的特点,也是我用来判断这个人属于哪一类的依据。这些特点和依据就是特征。可能有些特征对我判断更有用,有些对我判断没什么用,有些可能会让我判断错误,但这些都是我分类的依据。

我们没办法发现一个人的所有特点,所以我们没办法客观的选择所有特点,我们只能主观的选择一部分特点来作为我分类的依据。这也是特征选择的特点,需要人为的进行一定选择。

而在情感分类中,一般从“词”这个层次来选择特征。

比如这句话“手机非常好用!”,我给了它一个类标签“Positive”。里面有四个词(把感叹号也算上),“手机”,“非常”,“好用”,“!”。我可以认为这4个词都对分类产生了影响,都是分类的依据。也就是无论什么地方出现了这四个词的其中之一,文本都可以被分类为“积极”。这个是把所有词都作为分类特征。

同样的,对这句话,我也可以选择它的双词搭配(Bigrams)作为特征。比如“手机 非常”,“非常 好用”,“好用 !”这三个搭配作为分类的特征。以此类推,三词搭配(Trigrams),四词搭配都是可以被作为特征的。

三、再之后特征要降维。

特征降维说白了就是减少特征的数量。这有两个意义,一个是特征数量减少了之后可以加快算法计算的速度(数量少了当然计算就快了),另一个是如果用一定的方法选择信息量丰富的特征,可以减少噪音,有效提高分类的准确率。

所谓信息量丰富,可以看回上面这个例子“手机非常好用!”,很明显,其实不需要把“手机”,“非常”,“好用”,“!”这4个都当做特征,因为“好用”这么一个词,或者“非常 好用”这么一个双词搭配就已经决定了这个句子是“积极”的。这就是说,“好用”这个词的信息量非常丰富。

那要用什么方法来减少特征数量呢?答案是通过一定的统计方法找到信息量丰富的特征。

统计方法包括:词频(Term Frequency)、文档频率(Document Frequency)、互信息(Pointwise Mutual Information)、信息熵(Information Entropy)、卡方统计(Chi-Square)等等。

在情感分类中,用词频选择特征,也就是选在语料库中出现频率高的词。比如我可以选择语料库中词频最高的2000个词作为特征。用文档频率选特征,是选在语料库的不同文档中出现频率最高的词。而其它三个,太高端冷艳,表示理解得还不清楚,暂且不表。。。

不过意思都是一样的,都是要通过某个统计方法选择信息量丰富的特征。特征可以是词,可以是词组合。

四、把语料文本变成使用特征表示。

在使用分类算法进行分类之前,第一步是要把所有原始的语料文本转化为特征表示的形式。

还是以上面那句话做例子,“手机非常好用!”

  • 如果在NLTK 中,如果选择所有词作为特征,其形式是这样的:[ {“手机”: True, “非常”: True, “好用”: True, “!”: True} , positive]
  • 如果选择双词作为特征,其形式是这样的:[ {“手机 非常”: True, “非常 好用”: True, “好用 !”: True} , positive ]
  • 如果选择信息量丰富的词作为特征,其形式是这样的:[ {“好用”: True} , positive ]

(NLTK需要使用字典和数组两个数据类型,True 表示对应的元素是特征。至于为什么要用True 这样的方式,我也不知道。。。反正见到的例子都是这样的。。。有空再研究看是不是可以不这样的吧)

无论使用什么特征选择方法,其形式都是一样的。都是[ {“特征1”: True, “特征2”: True, “特征N”: True, }, 类标签 ]

五、把用特征表示之后的文本分成开发集和测试集,把开发集分成训练集和开发测试集。

机器学习分类必须有数据给分类算法训练,这样才能得到一个(基于训练数据的)分类器。

有了分类器之后,就需要检测这个分类器的准确度。

根据《Python 自然语言处理》的方法,数据可以分为开发集合测试集。开发集专门用于不断调整和发现最佳的分类算法和特征维度(数量),测试集应该一直保持“不被污染”。在开发集开发完毕之后,再使用测试集检验由开发集确定的最佳算法和特征维度的效果。具体如图:

\
图2:开发集和测试集(摘自《Natural Language Processing with Python》)

一般来说,训练集的数量应该远大于测试集,这样分类算法才能找出里面的规律,构建出高效的分类器。

用回前面的例子。假设2000条已经标注了积极和消极的评论数据,开发集可以是随机的1600条,测试集是剩余的随机400条。然后开发集中,训练集可以是随机的1400条,开发测试集是200条。

六、用不同的分类算法给训练集构建分类器,用开发测试集检验分类器的准确度(选出最佳算法后可以调整特征的数量来测试准确度)。

这个时候终于可以使用各种高端冷艳的机器学习算法啦!

我们的目标是:找到最佳的机器学习算法。

可以使用朴素贝叶斯(NaiveBayes),决策树(Decision Tree)等NLTK 自带的机器学习方法。也可以更进一步,使用NLTK 的scikit-learn 接口,这样就可以调用scikit-learn 里面的所有,对,是所有机器学习算法了。我已经忍不住的泪流满面。

其实方法很容易。只要以下五步。

  1. 仅仅使用开发集(Development Set)。
  2. 用分类算法训练里面的训练集(Training Set),得出分类器。
  3. 用分类器给开发测试集分类(Dev-Test Set),得出分类结果。
  4. 对比分类器给出的分类结果和人工标注的正确结果,给出分类器的准确度。
  5. 使用另一个分类算法,重复以上三步。

在检验完所有算法的分类准确度之后,就可以选出最好的一个分类算法了。

在选出最好的分类算法之后,就可以测试不同的特征维度对分类准确度的影响了。一般来说,特征太少则不足以反映分类的所有特点,使得分类准确率低;特征太多则会引入噪音,干扰分类,也会降低分类准确度。所以,需要不断的测试特征的数量,这样才可以得到最佳的分类效果。

七、选择出开发集中最佳的分类算法和特征维度,使用测试集检验得出情感分类的准确度。

在终于得到最佳分类算法和特征维度(数量)之后,就可以动用测试集。

直接用最优的分类算法对测试集进行分类,得出分类结果。对比分类器的分类结果和人工标注的正确结果,给出分类器的最终准确度。

用Python 进行机器学习及情感分析,需要用到两个主要的程序包:nltk 和 scikit-learn

nltk 主要负责处理特征提取(双词或多词搭配需要使用nltk 来做)和特征选择(需要nltk 提供的统计方法)。

scikit-learn 主要负责分类算法,评价分类效果,进行分类等任务。

接下来会有四篇文章按照以下步骤来实现机器学习的情感分析。

  1. 特征提取和特征选择(选择最佳特征)
  2. 赋予类标签,分割开发集和测试集
  3. 构建分类器,检验分类准确度,选择最佳分类算法
  4. 存储和使用最佳分类器进行分类,分类结果为概率值

首先是特征提取和选择

一、特征提取方法

1. 把所有词作为特征

      
  1. def bag_of_words(words):  
  2. return dict([(word, True) for word in words]) 

返回的是字典类型,这是nltk 处理情感分类的一个标准形式。

2. 把双词搭配(bigrams)作为特征

      
  1. mport nltk  
  2. from nltk.collocations import BigramCollocationFinder  
  3. from nltk.metrics import BigramAssocMeasures  
  4. def bigram(words, score_fn=BigramAssocMeasures.chi_sq, n=1000):  
  5. bigram_finder = BigramCollocationFinder.from_words(words) #把文本变成双词搭配的形式  
  6. bigrams = bigram_finder.nbest(score_fn, n) #使用了卡方统计的方法,选择排名前1000的双词  
  7. return bag_of_words(bigrams) 

除了可以使用卡方统计来选择信息量丰富的双词搭配,还可以使用其它的方法,比如互信息(PMI)。而排名前1000也只是人工选择的阈值,可以随意选择其它值,可经过测试一步步找到最优值。

3. 把所有词和双词搭配一起作为特征

      
  1. def bigram_words(words, score_fn=BigramAssocMeasures.chi_sq, n=1000):  
  2. bigram_finder = BigramCollocationFinder.from_words(words)  
  3. bigrams = bigram_finder.nbest(score_fn, n)  
  4. return bag_of_words(words + bigrams) #所有词和(信息量大的)双词搭配一起作为特征 

二、特征选择方法

有了提取特征的方法后,我们就可以提取特征来进行分类学习了。但一般来说,太多的特征会降低分类的准确度,所以需要使用一定的方法,来“选择”出信息量最丰富的特征,再使用这些特征来分类。

特征选择遵循如下步骤:

  1. 计算出整个语料里面每个词的信息量
  2. 根据信息量进行倒序排序,选择排名靠前的信息量的词
  3. 把这些词作为特征

1. 计算出整个语料里面每个词的信息量

1.1 计算整个语料里面每个词的信息量

      
  1. from nltk.probability import FreqDist, ConditionalFreqDist  
  2. def create_word_scores(): posWords = pickle.load(open('D:/code/sentiment_test/pos_review.pkl','r')) ..... return word_scores #包括了每个词和这个词的信息量 

1.2 计算整个语料里面每个词和双词搭配的信息量

      
  1. def create_word_bigram_scores():  
  2. posdata = pickle.load(open('D:/code/sentiment_test/pos_review.pkl','r')) negdata = pickle.load(open('D:/code/sentiment_test/neg_review.pkl','r')) ..... return word_scores 

2. 根据信息量进行倒序排序,选择排名靠前的信息量的词

      
  1. def find_best_words(word_scores, number):  
  2. best_vals = sorted(word_scores.iteritems(), key=lambda (w, s): s, reverse=True)[:number] #把词按信息量倒序排序。number是特征的维度,是可以不断调整直至最优的 
  3. best_words = set([w for w, s in best_vals])  
  4. return best_words 

然后需要对find_best_words 赋值,如下:

      
  1. word_scores_1 = create_word_scores()  
  2. word_scores_2 = create_word_bigram_scores() 

3. 把选出的这些词作为特征(这就是选择了信息量丰富的特征)

      
  1. def best_word_features(words): return dict([(word, True) for word in words if word in best_words]) 

三、检测哪中特征选择方法更优

见构建分类器,检验分类准确度,选择最佳分类算法

第一步,载入数据。

要做情感分析,首要的是要有数据。

数据是人工已经标注好的文本,有一部分积极的文本,一部分是消极的文本。

文本是已经分词去停用词的商品评论,形式大致如下:[[word11, word12, ... word1n], [word21, word22, ... , word2n], ... , [wordn1, wordn2, ... , wordnn]]

这是一个多维数组,每一维是一条评论,每条评论是已经又该评论的分词组成。

      
  1. #! /usr/bin/env python2.7  
  2. #coding=utf-8  
  3. pos_review = pickle.load(open('D:/code/sentiment_test/pos_review.pkl','r'))  
  4. neg_review = pickle.load(open('D:/code/sentiment_test/neg_review.pkl','r')) 

我用pickle 存储了相应的数据,这里直接载入即可。

第二步,使积极文本的数量和消极文本的数量一样。

      
  1. from random import shuffle  
  2. shuffle(pos_review) #把积极文本的排列随机化  
  3. size = int(len(pos_review)/2 - 18)  
  4. pos = pos_review[:size]  
  5. neg = neg_review 

我这里积极文本的数据恰好是消极文本的2倍还多18个,所以为了平衡两者数量才这样做。

第三步,赋予类标签。

      
  1. def pos_features(feature_extraction_method):  
  2. posFeatures = []  
  3. ....  
  4. negFeatures.append(negWords)  
  5. return negFeatures 

这个需要用特征选择方法把文本特征化之后再赋予类标签。

第四步、把特征化之后的数据数据分割为开发集和测试集

      
  1. train = posFeatures[174:]+negFeatures[174:]  
  2. devtest = posFeatures[124:174]+negFeatures[124:174]  
  3. test = posFeatures[:124]+negFeatures[:124] 

这里把前124个数据作为测试集,中间50个数据作为开发测试集,最后剩下的大部分数据作为训练集。

在把文本转化为特征表示,并且分割为开发集和测试集之后,我们就需要针对开发集进行情感分类器的开发。测试集就放在一边暂时不管。

开发集分为训练集(Training Set)和开发测试集(Dev-Test Set)。训练集用于训练分类器,而开发测试集用于检验分类器的准确度。

为了检验分类器准确度,必须对比“分类器的分类结果”和“人工标注的正确结果”之间的差异。

所以:

  • 第一步,是要把开发测试集中,人工标注的标签和数据分割开来。
  • 第二步是使用训练集训练分类器;
  • 第三步是用分类器对开发测试集里面的数据进行分类,给出分类预测的标签;第四步是对比分类标签和人工标注的差异,计算出准确度。

一、分割人工标注的标签和数据

dev, tag_dev = zip(*devtest) #把开发测试集(已经经过特征化和赋予标签了)分为数据和标签

二到四、可以用一个函数来做

      
  1. def score(classifier):  
  2. classifier = SklearnClassifier(classifier) #在nltk 中使用scikit-learn 的接口  
  3. classifier.train(train) #训练分类器  
  4. pred = classifier.batch_classify(testSet) #对开发测试集的数据进行分类,给出预测的标签  
  5. return accuracy_score(tag_test, pred) #对比分类预测结果和人工标注的正确结果,给出分类器准确度 

之后我们就可以简单的检验不同分类器和不同的特征选择的结果

      
  1. import sklearn  
  2. .....  
  3. print 'NuSVC`s accuracy is %f' %score(NuSVC()) 

1. 我选择了六个分类算法,可以先看到它们在使用所有词作特征时的效果:

      
  1. BernoulliNB`s accuracy is 0.790000  
  2. MultinomiaNB`s accuracy is 0.810000  
  3. LogisticRegression`s accuracy is 0.710000  
  4. SVC`s accuracy is 0.650000  
  5. LinearSVC`s accuracy is 0.680000  
  6. NuSVC`s accuracy is 0.740000 

2. 再看使用双词搭配作特征时的效果(代码改动如下地方即可)

      
  1. posFeatures = pos_features(bigrams)  
  2. negFeatures = neg_features(bigrams) 

结果如下:

      
  1. BernoulliNB`s accuracy is 0.710000 MultinomiaNB`s accuracy is 0.750000 LogisticRegression`s accuracy is 0.790000 SVC`s accuracy is 0.750000 LinearSVC`s accuracy is 0.770000 NuSVC`s accuracy is 0.780000 

3. 再看使用所有词加上双词搭配作特征的效果

posFeatures = pos_features(bigram_words) negFeatures = neg_features(bigram_words)

结果如下:

      
  1. BernoulliNB`s accuracy is 0.710000  
  2. MultinomiaNB`s accuracy is 0.750000  
  3. LogisticRegression`s accuracy is 0.790000  
  4. SVC`s accuracy is 0.750000  
  5. LinearSVC`s accuracy is 0.770000  
  6. NuSVC`s accuracy is 0.780000 

可以看到在不选择信息量丰富的特征时,仅仅使用全部的词或双词搭配作为特征,分类器的效果并不理想。

接下来将使用卡方统计量(Chi-square)来选择信息量丰富的特征,再用这些特征来训练分类器。

4. 计算信息量丰富的词,并以此作为分类特征

      
  1. word_scores = create_word_scores()  
  2. best_words = find_best_words(word_scores, 1500) #选择信息量最丰富的1500个的特征  
  3. posFeatures = pos_features(best_word_features)  
  4. negFeatures = neg_features(best_word_features) 

结果如下:

      
  1. BernoulliNB`s accuracy is 0.870000  
  2. MultinomiaNB`s accuracy is 0.860000  
  3. LogisticRegression`s accuracy is 0.730000  
  4. SVC`s accuracy is 0.770000  
  5. LinearSVC`s accuracy is 0.720000  
  6. NuSVC`s accuracy is 0.780000 

可见贝叶斯分类器的分类效果有了很大提升。

5. 计算信息量丰富的词和双词搭配,并以此作为特征

      
  1. word_scores = create_word_bigram_scores()  
  2. best_words = find_best_words(word_scores, 1500) #选择信息量最丰富的1500个的特征  
  3. posFeatures = pos_features(best_word_features)  
  4. negFeatures = neg_features(best_word_features) 

结果如下:

      
  1. BernoulliNB`s accuracy is 0.910000  
  2. MultinomiaNB`s accuracy is 0.860000  
  3. LogisticRegression`s accuracy is 0.800000  
  4. SVC`s accuracy is 0.800000  
  5. LinearSVC`s accuracy is 0.750000  
  6. NuSVC`s accuracy is 0.860000 

可以发现贝努利的贝叶斯分类器效果继续提升,同时NuSVC 也有很大的提升。

此时,我们选用BernoulliNB、MultinomiaNB、NuSVC 作为候选分类器,使用词和双词搭配作为特征提取方式,测试不同的特征维度的效果。

      
  1. dimension = ['500','1000','1500','2000','2500','3000']  
  2. for d in dimension:  
  3. word_scores = create_word_scores_bigram()  
  4. best_words = find_best_words(word_scores, int(d))  
  5. posFeatures = pos_features(best_word_features)  
  6. negFeatures = neg_features(best_word_features)  
  7. train = posFeatures[174:]+negFeatures[174:]  
  8. devtest = posFeatures[124:174]+negFeatures[124:174]  
  9. test = posFeatures[:124]+negFeatures[:124]  
  10. dev, tag_dev = zip(*devtest)  
  11. print 'Feature number %f' %d  
  12. print 'BernoulliNB`s accuracy is %f' %score(BernoulliNB())  
  13. print 'MultinomiaNB`s accuracy is %f' %score(MultinomialNB())  
  14. print 'LogisticRegression`s accuracy is %f' %score(LogisticRegression()) 
  15. print 'SVC`s accuracy is %f' %score(SVC())  
  16. print 'LinearSVC`s accuracy is %f' %score(LinearSVC())  
  17. print 'NuSVC`s accuracy is %f' %score(NuSVC()) 

结果如下(很长。。):

      
  1. Feature number 500  
  2. BernoulliNB`s accuracy is 0.880000  
  3. MultinomiaNB`s accuracy is 0.850000  
  4. LogisticRegression`s accuracy is 0.740000  
  5. SVC`s accuracy is 0.840000  
  6. LinearSVC`s accuracy is 0.700000  
  7. NuSVC`s accuracy is 0.810000  
  8. Feature number 1000  
  9. BernoulliNB`s accuracy is 0.860000  
  10. MultinomiaNB`s accuracy is 0.850000  
  11. LogisticRegression`s accuracy is 0.750000  
  12. SVC`s accuracy is 0.800000  
  13. LinearSVC`s accuracy is 0.720000  
  14. NuSVC`s accuracy is 0.760000  
  15. Feature number 1500  
  16. BernoulliNB`s accuracy is 0.870000  
  17. MultinomiaNB`s accuracy is 0.860000  
  18. LogisticRegression`s accuracy is 0.770000  
  19. SVC`s accuracy is 0.770000  
  20. LinearSVC`s accuracy is 0.750000  
  21. NuSVC`s accuracy is 0.790000  
  22. Feature number 2000  
  23. BernoulliNB`s accuracy is 0.870000  
  24. MultinomiaNB`s accuracy is 0.850000  
  25. LogisticRegression`s accuracy is 0.770000  
  26. SVC`s accuracy is 0.690000  
  27. LinearSVC`s accuracy is 0.700000  
  28. NuSVC`s accuracy is 0.800000  
  29. Feature number 2500  
  30. BernoulliNB`s accuracy is 0.850000  
  31. MultinomiaNB`s accuracy is 0.830000  
  32. LogisticRegression`s accuracy is 0.780000  
  33. SVC`s accuracy is 0.700000  
  34. LinearSVC`s accuracy is 0.730000  
  35. NuSVC`s accuracy is 0.800000  
  36. Feature number 3000  
  37. BernoulliNB`s accuracy is 0.850000  
  38. MultinomiaNB`s accuracy is 0.830000  
  39. LogisticRegression`s accuracy is 0.780000  
  40. SVC`s accuracy is 0.690000  
  41. LinearSVC`s accuracy is 0.710000  
  42. NuSVC`s accuracy is 0.800000 

把上面的所有测试结果进行综合可汇总如下:

不同分类器的不同特征选择方法效果

\

综合来看,可以看出特征维数在500 或 1500的时候,分类器的效果是最优的。

所以在经过上面一系列的分析之后,可以得出如下的结论:

  • Bernoulli 朴素贝叶斯分类器效果最佳
  • 词和双词搭配作为特征时效果最好
  • 当特征维数为1500时效果最好

为了不用每次分类之前都要训练一次数据,所以可以在用开发集找出最佳分类器后,把最佳分类器存储下来以便以后使用。然后再使用这个分类器对文本进行分类。

一、使用测试集测试分类器的最终效果

      
  1. word_scores = create_word_bigram_scores() #使用词和双词搭配作为特征  
  2. best_words = find_best_words(word_scores, 1500) #特征维度1500  
  3. posFeatures = pos_features(best_word_features)  
  4. negFeatures = neg_features(best_word_features)  
  5. trainSet = posFeatures[:500] + negFeatures[:500] #使用了更多数据  
  6. testSet = posFeatures[500:] + negFeatures[500:]  
  7. test, tag_test = zip(*testSet)  
  8. def final_score(classifier):  
  9. classifier = SklearnClassifier(classifier)  
  10. classifier.train(trainSet)  
  11. pred = classifier.batch_classify(test)  
  12. return accuracy_score(tag_test, pred)  
  13. print final_score(BernoulliNB()) #使用开发集中得出的最佳分类器 

其结果是很给力的:

      
  1. 0.979166666667 

二、把分类器存储下来

(存储分类器和前面没有区别,只是使用了更多的训练数据以便分类器更为准确)

      
  1. word_scores = create_word_bigram_scores()  
  2. best_words = find_best_words(word_scores, 1500)  
  3. posFeatures = pos_features(best_word_features)  
  4. negFeatures = neg_features(best_word_features)  
  5. trainSet = posFeatures + negFeatures  
  6. BernoulliNB_classifier = SklearnClassifier(BernoulliNB())  
  7. BernoulliNB_classifier.train(trainSet)  
  8. pickle.dump(BernoulliNB_classifier, open('D:/code/sentiment_test/classifier.pkl','w')) 

在存储了分类器之后,就可以使用该分类器来进行分类了。

三、使用分类器进行分类,并给出概率值

给出概率值的意思是用分类器判断一条评论文本的积极概率和消极概率。给出类别也是可以的,也就是可以直接用分类器判断一条评论文本是积极的还是消极的,但概率可以提供更多的参考信息,对以后判断评论的效用也是比单纯给出类别更有帮助。

1. 把文本变为特征表示的形式

要对文本进行分类,首先要把文本变成特征表示的形式。而且要选择和分类器一样的特征提取方法。

      
  1. #! /usr/bin/env python2.7  
  2. #coding=utf-8  
  3. moto = pickle.load(open('D:/code/review_set/senti_review_pkl/moto_senti_seg.pkl','r')) #载入文本数据  
  4. def extract_features(data):  
  5. feat = []  
  6. for i in data:  
  7. feat.append(best_word_features(i))  
  8. return feat  
  9. moto_features = extract_features(moto) #把文本转化为特征表示的形式 

注:载入的文本数据已经经过分词和去停用词处理。

2. 对文本进行分类,给出概率值

      
  1. import pickle  
  2. import sklearn  
  3. clf = pickle.load(open('D:/code/sentiment_test/classifier.pkl')) #载入分类器  
  4. pred = clf.batch_prob_classify(moto_features) #该方法是计算分类概率值的  
  5. p_file = open('D:/code/sentiment_test/score/Motorala/moto_ml_socre.txt','w') #把结果写入文档  
  6. for i in pred:  
  7. p_file.write(str(i.prob('pos')) + ' ' + str(i.prob('neg')) + '\n')  
  8. p_file.close() 

最后分类结果如下图:

\

前面是积极概率,后面是消极概率

折腾了这么久就为了搞这么一个文件出来。。。这伤不起的节奏已经无人阻挡了吗。。。

不过这个结果确实比词典匹配准确很多,也算欣慰了。。。

【编辑推荐】

【责任编辑: 未丽燕TEL:(010)68476606】

点赞0

相关 [python 机器学习 方法] 推荐:

使用python+机器学习方法进行情感分析(详细步骤) - 51CTO.COM

- -
【限时免费】年底最强一次云计算大会,看传统、社区、互联网企业如何碰撞. 不是有词典匹配的方法了吗?怎么还搞多个机器学习方法. 因为词典方法和机器学习方法各有千秋. 机器学习的方法精确度更高,因为词典匹配会由于语义表达的丰富性而出现很大误差,而机器学习方法不会. 无论是主客观分类还是正负面情感分类,机器学习都可以完成任务.

从零开始掌握Python机器学习:十四步教程 - 知乎专栏

- -
Python 可以说是现在最流行的机器学习语言,而且你也能在网上找到大量的资源. 你现在也在考虑从 Python 入门机器学习吗. 本教程或许能帮你成功上手,从 0 到 1 掌握 Python 机器学习,至于后面再从 1 到 100 变成机器学习专家,就要看你自己的努力了. 本教程原文分为两个部分,机器之心在本文中将其进行了整合,原文可参阅:7 Steps to Mastering Machine Learning With Python 和 7 More Steps to Mastering Machine Learning With Python.

GitHub 上最著名的20个 Python 机器学习项目,值得收藏!

- - IT瘾-geek
源 | kdnuggets|小象. 开源是技术创新和快速发展的核心. 这篇文章向你展示Python机器学习开源项目以及在分析过程中发现的非常有趣的见解和趋势. 我们分析了GitHub上的前20名Python机器学习项目,发现scikit-Learn,PyLearn2和NuPic是贡献最积极的项目. 让我们一起在Github上探索这些流行的项目.

从Pipenv到PyTorch,盘点2017年最受欢迎的十大机器学习Python库

- -
参与:蒋思源、黄小天、刘晓坤. 2017 年即将结束,又到了总结的时刻. 本文作者把范围限定为机器学习,盘点了 2017 年以来最受欢迎的十大 Python 库;同时在这十个非常流行与强大的 Python 库之外,本文还给出了一些同样值得关注的 Python 库,如 PyVips 和 skorch.

如何用Python和机器学习训练中文文本情感分类模型?

- - 神刀安全网
利用Python机器学习框架scikit-learn,我们自己做一个分类模型,对中文评论信息做情感分析. 其中还会介绍中文停用词的处理方法. 前些日子,我在微信后台收到了一则读者的留言. 我一下子有些懵——这怎么还带点播了呢. 但是旋即我醒悟过来,好像是我自己之前挖了个坑. 如何用Python从海量文本抽取主题.

基于机器学习方法的POI品类推荐算法 -

- -
在美团商家数据中心(MDC),有超过100w的已校准审核的POI数据(我们一般将商家标示为POI,POI基础信息包括:门店名称、品类、电话、地址、坐标等). 如何使用这些已校准的POI数据,挖掘出有价值的信息,本文进行了一些尝试:利用机器学习方法,自动标注缺失品类的POI数据. 例如,门店名称为“好再来牛肉拉面馆”的POI将自动标注“小吃”品类.

python 代码自动生成的方法 (代码生成器)

- - 大CC
python 代码自动生成的方法 (代码生成器). 工作中遇到这么一个事,需要写很多C++的底层数据库类,但这些类大同小异,无非是增删改查,如果人工来写代码,既费力又容易出错;而借用python的代码自动生成,可以轻松搞定;. (类比JAVA中的Hibernate自动生成的数据库底层操作代码). 下面介绍使用python字符串替换的方法;.

用Python进行时间序列预测的7种方法

- - 标点符
时间序列预测在日常分析中常会用到,前段时间在处理预算相关的内容,涉到一些指标预测,学习到了这篇文章,整理出来分享给大家. 数据集(JetRail高铁的乘客数量)下载,链接: https://pan.baidu.com/s/15w5_5_o8IK6ZT3VlNSRa7Q 提取码: 9be3. 假设要解决一个时序问题:根据过往两年的数据(2012 年 8 月至 2014 年 8月),需要用这些数据预测接下来 7 个月的乘客数量.

大数据和AI策略–面向投资的机器学习和另类数据方法(附280页报告)

- - 互联网数据中心-199IT
J.P.摩根最新的280 页研究报告《大数据和 AI 策略——面向投资的机器学习和另类数据方法》,极为详尽地梳理、评述、预测了对冲基金和投资者使用机器学习技术利用、分析另类数据的现状与未来,对于一切关注这一新兴大趋势的人们、一切投资者都有重要的借鉴意义. 大数据,特别是另类数据集的构建和利用,已经极大地改变了投资领域的面貌.

[译] 巧妙使用机器学习的方法来检测 IoT 设备中的 DDoS 攻击

- - IT瘾-dev
异常检测是识别数据中与预期行为有所不同的数据模式. 异常检测技术可以用来区别常用流量与异常攻击流量. 常用简单的基于门阀值的检测技术并不适用于IOT的攻击本质. 而使用机器学习算法的异常检测模型可以有效降低检测中的假阳性. 网络中间件的内存和处理能力有限,导致在异常检测方面在算法上有一定的限制. 智慧家庭网关路由器用的异常检测框架有以下的特征:.