R实战——大众点评-汉拿山评论情感浅析

有实际的需求才有行动的动力,因为一个朋友开了一家烤肉店,在大众点评上线了团购套餐,遭遇了几次中差评,朋友第一次接触这个,也不知道怎么回复和处理,于是向我寻求帮助。本人也不知道如何处理,正好最近在学R语言,于是就想到了不如通过R语言编写个简单的爬虫抓取大众点评上评论,参考其他店的回复和处理方式。爬取了数据,又可以拿来练手,做个简单的情感分析。

本文主要分以下三部分:

第一部分,编写爬虫抓取数据,主要的R包有XML包,RCurl包,readr包

第二部分,清洗数据和分词,主要的R包有stringr包,Rwordseg包

第三部分,简单情感分析和结论,主要的R包有plyr

情感分析采用最基础的词典型情感分析。

第一部分:获取数据

获取数据主要使用RCurl包+XML包。RCurl这个程序包提供了由R到libcurl库的接口,从而实现HTTP的一些功能。主要是链接网站,下载文件,上传文件等。主要的函数有:

getURL()

getForm()

postForm()

这里主要使用getURL()来获取网页内容。XML包用于解析和处理XML,主要使用的函数有:

htmlParse() #解析网页

getNodeSet() #获取节点

xmlValue() #获取节点值

xmlGetAttr() #获取节点属性值

第一步:伪装浏览器

第二步:获取网站内容

上面代码把页面代码(HTML格式)保存在temp中,输入temp可以查看内容。只要把url改成你需要的网址就能爬取自己想要的网站

PS.假如爬取的中文出现乱码,要注意将编码改成与页面编码一致

第三步:解析HTML

将temp解析成XML包能够处理的格式

第四步:提取节点内容

提取节点内容使用getNodeSet()函数,定位需要使用XPath路径

使用谷歌浏览器查看代码,找到需要提取的节点和内容

那么我们要的XPath路径就是div[@class='comment-txt']/div

更多XPath内容请自行查阅资料

str_trim()函数去除前后空格

sapply()函数将节点的内容使用xmlValue()函数提取出来生成向量

小结

到这里,已经爬取了一个页面的全部点评内容了,假如你还需要爬取别的内容,比如商家的回应,星级,人均消费,图片等等,都可以通过XPath定位到不同的节点,再抓取数据。只需做些小改动,就能将全部点评都爬取下来。思路很简单,先爬取某店的点评页面,抓取点评页面的页码数,生成点评页面url的列表(点评页面网址成规律性),然后写个循环语句即可,在这里就不多展开说明了。

上面只涉及最简单的爬虫用法,更复杂的爬虫涉及到分布式访问,登录,ajax等知识,非基础知识也超出了笔者的知识范围,是笔者的下一步学习内容。

第二部分:数据清洗

每一种分析方法,都有其数据结构,而数据清洗就是为了使用原数据符合分析方法的数据结构而做的关键步骤。数据清洗是否合理关系着分析结果是否正确(准确率高低),不同的数据清洗方法也影响着分析结果,数据清洗往往也是数据分析过程中最费时间的一个步骤。

这一部分使用的R包有Rwordseg包,plyr包。Rwordseg包用于中文文本分词,安装Rwordseg包是个难题,需要安装依赖rJava包,这两个包安装都容易出问题,请自行Google解决。plyr包主要用于数据框的变形组合。

由第一部分的数据获取,我们得到了下面这样一份数据:

总共有2660条数据,数据量不算大,但对于一家店的点评数来说,看得出这家店还算比较火。

一级清洗

这一步骤主要去除一些标点符号,比如逗号,句号,波浪线等。这里使用gsub()函数,其中涉及的正则表达式请自行查阅资料。

二级清洗

二级清洗主要去除无用内容,比如字母,数字等

分词和三级清洗

分词即将整段文本分成由词组够成的向量,那么要按照什么规律或者方式分词才能符合中文的习惯呢?方法有两种:

情感词典

自建词典

情感词典可由强大的互联网搜索下载,有些分为正、负向词典,有些整合在一起,并有单独正负向标签。可自行上网下载。同时也可以自建词典,不同的场景下,同一单词的倾向是不一样的,所以当某个词典在某个场景下使用时,能够很好的完成分词,而当应用在别的场景下时,效果却不理想。本文采用已打标签的情感词典。

Rwordseg包支持安装scel格式的词典,读者感兴趣可以查阅Rwordseg包帮助文档。

可以看出能够将大部分词分出来,但仍然有些分词结果不太理想,比如“牛舌”,“买单”,“韩式”等等。此时可以将这些词加入到分词词库(自建词库)

生成文档-词组矩阵。先用lapply()函数算出每条评论分词的个数,然后生成每个词对应的ID。

从分词结果来看,出现了大量的“的”,“啊”,“呀”,“了”之类的无用词,由于这些词出现的次数较多,容易造成分析结果偏差,解决方法就是将这些词(停用词)去除。原理也很简单,导入停用词列表(词典),先将停用词列表与情感词典匹配,匹配到情感词典的词就从停用词列表中删去,然后再将新的停用词列表与分词结果相匹配,删除分词结果中的停用词。停用词列表可以从网上搜索下载。三级清洗就是删除停用词。

%in%是集合运算符号,A %in% B,代表在A中匹配B,生成(TRUE,FALSE,TRUE……)布尔向量,其中TURE代表A/B共有的。形成一个与A等长的波尔值向量。

小结

到这里,数据已经处理完成了。一级清洗和二级清洗使用了正则表达式,匹配到无用的符号或者内容则删除,三级清洗在分词完成的基础下,去除一些停用词,让数据更加的合理。但是实际操作中,分词的结果并不理想,原因是导入的分词词典并非专门为行业准备的,可以通过自建词典来补充。停用词的选用也对结果影响甚大,对于特定的停用词,可以添加到停用词中再删去。

第三部分:情感分析

在第二部分,我们得到了一个情感词典,一个经过三级清洗的文档-单词矩阵,接下我们只需将这两个矩阵结合就能得到一个文档-单词-得分矩阵。在第一部分,我们获取的数据框中包含了一列star的数据,这个数据就是每条评论对应的星级数,范围从1星到5星,我们规定1到3星为负向情感,标记为-1,4星和5星为正向情感,标记为1。这样我们就得到一个人工标记的正负倾向情感表。

使用join()函数将df.emotion数据框和emotion数据框通过"word"列结合,看得出来,在emotion数据框(情感词典)中只含有少部分词组与df.emotion数据框匹配上,比如id为1的评论,只匹配了3个词组,而原数据框有15个词组。

计算每个ID(文档)的得分,aggregate()函数将score列按id分类并计算总和。同时我们发现有8个id缺失了,这是由于个别评论较短,导致匹配不到情感得分,这特别需要注意,在与人工标注好的情感表做比较时,会发生id不匹配的问题。

上面代码先生成跟id长度一致的向量,再将每个ID的得分匹配到对应的id,再根据得分打上标签,得分大于0的规定为正向情感,标签为1,得分小于等于0的规定为负向情感,标签为-1。生成了测试使用的文档-标签矩阵。

同理,生成人工标注的标签向量。

最后,算出准确率为76%,可以看得出结果并不理想。

小结

这是最基础的情感分析,思路如下:先文本分词,算出每个文档的权重,再添加标签,生成的文档-标签矩阵。而本文中的每条评论的打星数可以看成已经过人工标注的文档-标签矩阵,最后生成混淆矩阵,算出准确率。这个模型仍然有很大的改进的空间,比如分词的准确度,情感词典的完善度等等,留给读者自己完成。

扫一扫,免费获取各种数据分析视频及源码

  • 发表于:
  • 原文链接:http://kuaibao.qq.com/s/20171218G0KB9U00?refer=cp_1026

扫码关注云+社区