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

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

由于词典办法和机器学习办法各有千秋。

机器学习的办法精确度更高,由于词典匹配会由于语义表达的丰厚性而呈现很大差错,而机器学习办法不会。而且它可运用的场景更多样。不论是主客观分类仍是正负面情感分类,机器学习都能够完成使命。而无需像词典匹配那样要深化到词语、语句、语法这些层面。

而词典办法适用的语料规模更广,不论是手机、电脑这些产品,仍是谈论、影评这些语料,都能够适用。但机器学习则极度依靠语料,把手机语料练习出来的的分类器拿去给谈论分类,那是注定要失利的。

运用机器学习进行情感剖析,能够换一个相同意思的说法,便是用有监督的(需求人工标示类别)机器学习办法来对文本进行分类。

这点与词典匹配有着实质的差异。词典匹配是直接核算文本中的情感词,得出它们的情感倾向分值。而机器学习办法的思路是先选出一部分表达活跃情感的文本和一部分表达消沉情感的文本,用机器学习办法进行练习,取得一个情感分类器。再通过这个情感分类器对避实就虚文本进行活跃和消沉的二分分类。终究的分类能够为文本给出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 的文章真实少,这篇文章是仅有的讲得比较详细的把两者结合的,在此也表明感谢。

但对于我而言仍是有点不行的,由于中文和英文有必定的不同,而且上面说到的一些博客里边的代码也是需求改动的。总算把一份代码啃完之后,能写出一个跑得通的中文情感分类代码了。接下来会介绍它的完成思路和详细代码。

在这个系列的文章里边,机器学习都能够以为是有监督的分类办法。

整体流程如图:

运用Python+机器学习方法进行情感剖析(具体过程)(基于python的情感分析)  Python 机器学习 情感分析 第1张
图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 自然语言处理》的办法,数据能够分为开发调集测验集。开发集专门用于不断调整和发现***的分类算法和特征维度(数量),测验集应该一向坚持“不被污染”。在开发集开发结束之后,再运用测验集查验由开发集确认的***算法和特征维度的作用。详细如图:

运用Python+机器学习方法进行情感剖析(具体过程)(基于python的情感分析)  Python 机器学习 情感分析 第2张
图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. defbag_of_words(words):
  2. returndict([(word,True)forwordinwords])

回来的是字典类型,这是nltk 处理情感分类的一个规范办法。

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

  1. mportnltk
  2. fromnltk.collocationsimportBigramCollocationFinder
  3. fromnltk.metricsimportBigramAssocMeasures
  4. defbigram(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. returnbag_of_words(bigrams)

除了能够运用卡方核算来挑选信息量丰厚的双词调配,还能够运用其它的办法,比方互信息(PMI)。而排名前1000也只是人工挑选的阈值,能够随意挑选其它值,可通过测验一步步找到***值。

3. 把避实就虚词和双词调配一同作为特征

  1. defbigram_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. returnbag_of_words(words+bigrams)#避实就虚词和(信息量大的)双词调配一同作为特征

二、特征挑选办法

有了提取特征的办法后,咱们就能够提取特征来进行分类学习了。但一般来说,太多的特征会下降分类的准确度,所以需求运用必定的办法,来“挑选”出信息量最丰厚的特征,再运用这些特征来分类。

特征挑选遵从如下过程:

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

1. 核算出整个语料里边每个词的信息量

1.1 核算整个语料里边每个词的信息量

  1. fromnltk.probabilityimportFreqDist,ConditionalFreqDist
  2. defcreate_word_scores():posWords=pickle.load(open('D:/code/sentiment_test/pos_review.pkl','r')).....returnword_scores#包含了每个词和这个词的信息量

1.2 核算整个语料里边每个词和双词调配的信息量

  1. defcreate_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')).....returnword_scores

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

  1. deffind_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([wforw,sinbest_vals])
  4. returnbest_words

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

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

3. 把选出的这些词作为特征(这便是挑选了信息量丰厚的特征)

  1. defbest_word_features(words):returndict([(word,True)forwordinwordsifwordinbest_words])

三、检测哪中特征挑选办法更优

见构建分类器,查验分类准确度,挑选***分类算法

***步,载入数据。

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

数据是人工现已标示好的文本,有一部分活跃的文本,一部分是消沉的文本。

文本是现已分词去停用词的产品谈论,办法大致如下:[[word11, word12, ... word1n], [word21, word22, ... , word2n], ... , [wordn1, wordn2, ... , wordnn]]

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

  1. #!/usr/bin/envpython2.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. fromrandomimportshuffle
  2. shuffle(pos_review)#把活跃文本的摆放随机化
  3. size=int(len(pos_review)/2-18)
  4. pos=pos_review[:size]
  5. neg=neg_review

我管中窥豹活跃文本的数据恰好是消沉文本的2倍还多18个,所以为了平衡两者数量才这样做。

第三步,赋予类标签。

  1. mportnltk
  2. fromnltk.collocationsimportBigramCollocationFinder
  3. fromnltk.metricsimportBigramAssocMeasures
  4. defbigram(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. returnbag_of_words(bigrams)
0

这个需求用特征挑选办法把文本特征化之后再赋予类标签。

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

  1. mportnltk
  2. fromnltk.collocationsimportBigramCollocationFinder
  3. fromnltk.metricsimportBigramAssocMeasures
  4. defbigram(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. returnbag_of_words(bigrams)
1

管中窥豹把前124个数据作为测验集,中心50个数据作为开发测验集,***剩余的大部分数据作为练习集。

在把文本转化为特征表明,而且切割为开发集和测验集之后,咱们就需求针对开发集进行情感分类器的开发。测验集就放在一边暂时不论。

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

为了查验分类器准确度,有必要比照“分类器的分类成果”和“人工标示的正确成果”之间的差异。

所以:

  • ***步,是要把开发测验会集,人工标示的标签和数据切割开来。
  • 第二步是运用练习集练习分类器;
  • 第三步是用分类器对开发测验集里边的数据进行分类,给出分类猜测的标签;第四步是比照分类标签和人工标示的差异,核算出准确度。

一、切割人工标示的标签和数据

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

二到四、能够用一个函数来做

  1. mportnltk
  2. fromnltk.collocationsimportBigramCollocationFinder
  3. fromnltk.metricsimportBigramAssocMeasures
  4. defbigram(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. returnbag_of_words(bigrams)
2

之后咱们就能够简略的查验不同分类器和不同的特征挑选的成果。

  1. mportnltk
  2. fromnltk.collocationsimportBigramCollocationFinder
  3. fromnltk.metricsimportBigramAssocMeasures
  4. defbigram(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. returnbag_of_words(bigrams)
3

1. 我挑选了六个分类算法,能够先看到它们在运用避实就虚词作特征时的作用:

  1. mportnltk
  2. fromnltk.collocationsimportBigramCollocationFinder
  3. fromnltk.metricsimportBigramAssocMeasures
  4. defbigram(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. returnbag_of_words(bigrams)
4

2. 再看运用双词调配作特征时的作用(代码改动如下当地即可)

  1. mportnltk
  2. fromnltk.collocationsimportBigramCollocationFinder
  3. fromnltk.metricsimportBigramAssocMeasures
  4. defbigram(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. returnbag_of_words(bigrams)
5

成果如下:

  1. mportnltk
  2. fromnltk.collocationsimportBigramCollocationFinder
  3. fromnltk.metricsimportBigramAssocMeasures
  4. defbigram(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. returnbag_of_words(bigrams)
6

3. 再看运用避实就虚词加上双词调配作特征的作用

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

成果如下:

  1. mportnltk
  2. fromnltk.collocationsimportBigramCollocationFinder
  3. fromnltk.metricsimportBigramAssocMeasures
  4. defbigram(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. returnbag_of_words(bigrams)
7

能够看到在不挑选信息量丰厚的特征时,只是运用悉数的词或双词调配作为特征,分类器的作用并不抱负。

接下来将运用卡方核算量(Chi-square)来挑选信息量丰厚的特征,再用这些特征来练习分类器。

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

  1. mportnltk
  2. fromnltk.collocationsimportBigramCollocationFinder
  3. fromnltk.metricsimportBigramAssocMeasures
  4. defbigram(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. returnbag_of_words(bigrams)
8

成果如下:

  1. mportnltk
  2. fromnltk.collocationsimportBigramCollocationFinder
  3. fromnltk.metricsimportBigramAssocMeasures
  4. defbigram(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. returnbag_of_words(bigrams)
9

可见贝叶斯分类器的分类作用有了很大广大。

5. 核算信息量丰厚的词和双词调配,并以此作为特征

  1. defbigram_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. returnbag_of_words(words+bigrams)#避实就虚词和(信息量大的)双词调配一同作为特征
0

成果如下:

  1. defbigram_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. returnbag_of_words(words+bigrams)#避实就虚词和(信息量大的)双词调配一同作为特征
1
转载请说明出处
知优网 » 运用Python+机器学习方法进行情感剖析(具体过程)(基于python的情感分析)

发表评论

您需要后才能发表评论