首先,大多数人都知道词典方法,可能会某种程度上不太支持机器学习方法,所以先解释下词典 方法和机器学习方法的不同。
因为词典方法和机器学习方法各有千秋。
机器学习的方法精确度更高,因为词典匹配会由于语义表达的丰富性而出现很大误差,而机器学习方法不会。而且它可使用的场景更多样。无论是主客观分类还是正负面情感分类,机器学习都可以完成任务。而无需像词典匹配那样要深入到词语、句子、语法这些层面。
而词典方法适用的语料范围更广,无论是手机、电脑这些商品,还是书评、影评这些语料,都可以适用。但机器学习则极度依赖语料,把手机语料训练出来的的分类器拿去给书评分类,那是注定要失败的。
使用机器学习进行情感分析,可以换一个相同意思的说法,就是用有监督的(需要人工标注类别)机器学习方法来对文本进行分类。
这点与词典匹配有着本质的区别。词典匹配是直接计算文本中的情感词,得出它们的情感倾向分值。而机器学习方法的思路是先选出一部分表达积极情感的文本和一部分表达消极情感的文本,用机器学习方法进行训练,获得一个情感分类器。再通过这个情感分类器对所有文本进行积极和消极的二分分类。最终的分类可以为文本给出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的文章实在少,这篇文章是仅有的讲得比较详细的把两者结合的,在此也表示感谢。
但对于我而言还是有点不够的,因为中文和英文有一定的差别,而且上面提到的一些博客里面的代码也是需要改动的。终于把一份代码啃完之后,能写出一个跑得通的中文情感分类代码了。接下来会介绍它的实现思路和具体代码。
在这个系列的文章里面,机器学习都可以认为是有监督的分类方法。
总体流程如图:
一、有监督意味着需要人工标注,需要人为的给文本一个类标签。
比如我有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自然语言处理》的方法,数据可以分为开发集合测试集。开发集专门用于不断调整和发现最佳的分类算法和特征维度(数量),测试集应该一直保持“不被污染”。在开发集开发完毕之后,再使用测试集检验由开发集确定的最佳算法和特征维度的效果。具体如图:
一般来说,训练集的数量应该远大于测试集,这样分类算法才能找出里面的规律,构建出高效的分类器。
用回前面的例子。假设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.存储和使用最佳分类器进行分类,分类结果为概率值
( PS:有部分知识是通过摘引前辈的知识点,同时向前辈分享的知识,表示感谢。如有误之处,有待指正。)