R文本分析(一)

Part1安装依赖包

http://blog.csdn.net/cl1143015961/article/details/44082731

Part2分词处理

http://blog.csdn.net/cl1143015961/article/details/44108143

Part3文本聚类

http://blog.csdn.net/cl1143015961/article/details/44313025

Part4文本分类

http://blog.csdn.net/cl1143015961/article/details/44413631

Part5情感分析

http://blog.csdn.net/cl1143015961/article/details/44460873

Part1安装依赖包

R语言中中文分析的软件包是Rwordseg,Rwordseg软件包依赖rJava包,rJava需要本机中有安装Java。

第一步是安装Java,请安装JDK,JRE不行。请对应机型,下载安装32位的JDK。机器里已经有JDK的也请改成32位的,不然没办法使用Rwordseg,尝试使用过64位的,不可行。

下载地址:

http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

查看JAVA是否安装成功,运行cmd,输入java –version,如果能正常显示你的Java版本则安装正确。如下图:

第二步是安装rJava,这个直接在R或者RStudio里面安装软件包就行了。如果是刚安装完java记得重启你的R或者RStudio。

重点:一般在安装R的时候可以选择32位或者64位的,尽量都安装,运行Ri386 3.1.2。如果是你用的是RStudio,请设置为32位,设置方法,工具栏Tools > Global Options > General,R version,改成32-bit。

直接输入命令安装:Install.packages(“rJava”);或者在操作界面直接选择安装程序包,在CRAN上选择rJava安装。

安装完后需要添加下面环境变量配置在Path下(感觉路径配置没起作用,可以不配):

%JAVA_HOME%\jre\bin\client;

%JAVA_HOME%\jre\bin\server;

E:\programFiles\R\R-3.1.2\library\rJava\jri

加载rJava包,library(“rJava”),没提示错误则rJava安装成功。

R的下载地址:http://cran.rstudio.com/

RStudio的下载地址:http://www.rstudio.com/products/rstudio/#Desk

第三步是安装Rwordseg。

Rwordseg项目目前发布在R-forge上,所以不能直接在R或者Rstudio中用安装软件包功能。网上有说(参考http://jliblog.com/app/rwordseg):

在最新版本的R下可以直接安装:

1install.packages("Rwordseg", repos = "http://R-Forge.R-project.org")

如果是旧版本的R,可以通过source的方式进行安装:

1install.packages("Rwordseg", repos = "http://R-Forge.R-project.org", type = "source")

但是这样安装不成功。后来尝试把软件包下载到本地后,从本地安装,可行。

下载地址:http://R-Forge.R-project.org/bin/windows/contrib/3.0/Rwordseg_0.2-1.zip

下载完成后,在R或者RStudio中选择从本地zip文件安装软件包。安装完成后,加载程序包library(“Rwordseg”)。尝试使用Rwordseg,如下一个简单的例子:

1segmentCN(c("生命在于运动", "生活处处皆风景"))[[1]][1] "生命" "在于" "运动" [[2]][1] "生活" "处处" "皆"   "风景"

另外,该R包的中文文档下载地址:http://download.csdn.net/detail/cl1143015961/8436741

该文档中很详细地说明了软件包的功能,包括如何做分词,如何添加删除词语,如何添加删除字典,它支持的字典除了.dic格式之外,还有.scel(搜狗输入法的词库)。搜狗输入法的词库下载地址http://pinyin.sogou.com/dict/,选择你自己需要的分类去做尝试吧!

Part2分词处理

在RStudio中安装完相关软件包之后,才能做相关分词处理,请参照Part1部分安装需要软件包。参考文档:玩玩文本挖掘,这篇文章讲用R做文本挖掘很详尽,并且有一些相关资料的下载,值得看看!

1.       RWordseg功能

说明文档可在http://download.csdn.net/detail/cl1143015961/8436741下载,这里只做简单介绍。

分词

> segmentCN(c("如果你因为错过太阳而流泪", "你也会错过星星"))

[[1]]

[1] "如果""你"   "因为" "错"   "过"   "太阳" "而"

[8] "流泪"

[[2]]

[1] "你"   "也"   "会"   "错"   "过"   "星星"

可以看到分词的效果不是很理想,“错过”这是一个词却被分开了,说明词库中不存在这个词,所以,我们有时候需要向词库中添加我们需要的词语。

加词删词

> insertWords("错过")

> segmentCN(c("如果你因为错过太阳而流泪", "你也会错过星星"))

[[1]]

[1] "如果""你"   "因为" "错过" "太阳" "而"   "流泪"

[[2]]

[1] "你"   "也"   "会"   "错过" "星星"

有些情况下,你不希望某个词被分出来,例如还是“错过”这个词,这里“错”和“过”语义上已经不应该是一个词语了,所以,可以从词典中删除这个词,再添加上你需要的词语,继续做分词,效果就好多了。

> segmentCN("这个错过去你可以犯,但是现在再犯就不应该了")

[1] "这个" "错过" "去"   "你"   "可以" "犯"   "但是"

[8] "现在" "再"   "犯"   "就"   "不"   "应该" "了"

>deleteWords("错过")

> insertWords("过去")

> segmentCN("这个错过去你可以犯,但是现在再犯就不应该了")

[1] "这个" "错"   "过去" "你"   "可以" "犯"   "但是"

[8] "现在" "再"   "犯"   "就"   "不"   "应该" "了"

安装卸载词典

在做分词处理时,可能会遇到一些比较精而专的文章,专业词汇在词库里面并没有,这时候就需要去找相关的词典,安装到R中。例如,在做新闻分析中,一些娱乐新闻里会有很多明星歌手的名字出现,这些名字在做分词时,不会被识别为一个个词。此时可能需要添加一个名字的词典,词典可以是自己建也可以从网上找。推荐从搜搜狗输入法的词库下载地址http://pinyin.sogou.com/dict/,可以选择需要的分类词典下载。

这里我用到的一个词典names的下载地址:http://pinyin.sogou.com/dict/cate/index/429。

> segmentCN("2015年的几部开年戏都出现了唐嫣的身影")

[1] "2015年" "的"     "几部"   "开"     "年"

[6] "戏"     "都"     "出现"   "了"     "唐"

[11] "嫣"     "的"     "身影"

>installDict("D:\\R\\sources\\Dictionaries\\singers.scel", dictname ="names")

3732 words were loaded! ... New dictionary 'names' was installed!

>segmentCN("2015年的几部开年戏都出现了唐嫣的身影")

[1] "2015年" "的"     "几部"   "开"     "年"

[6] "戏"     "都"     "出现"   "了"     "唐嫣"

[11] "的"     "身影"

>listDict()

Name Type                          Des

1 names 明星官方推荐,词库来源于网友上传

Path

1 E:/programFiles/R/R-3.1.2/library/Rwordseg/dict/names.dic

在不需要自己添加的词典时,还可以删除。

> uninstallDict()

3732 words were removed! ... The dictionary 'names' wasuninstalled!

>listDict()

[1] Name Type Des  Path

<0 行>(或0-长度的row.names)

以上这些是基本的介绍,RWordseg还有更多的功能,请查看其中文文档。

2.       对某品牌官微做分词

数据来源是某服装品牌的官方微博从2012年到2014年末的微博。数据的基本内容结构如下图示,看内容大概能猜出来是哪个品牌了吧。

首先安装跟服装相关的词典,同样是从搜狗输入法的词库中下载的两个服饰类的词典, 下载地址http://pinyin.sogou.com/dict/cate/index/397,这个地址下的前两个词库。

> installDict("D:\\R\\sources\\Dictionaries\\fushi.scel",dictname = "fushi")

> installDict("D:\\R\\sources\\Dictionaries\\Ali_fushi.scel",dictname = "alifushi")

> listDict()

Name Type

1 names 明星

2 pangu Text

3 fushi 服饰

4   ali 服饰

下一步是将数据读入R中,可以看到一共有1640条微博数据,注意数据的编码格式,readLines默认读取格式是gbk格式的,读取格式不对时会乱码。

>hlzj <-readLines("d:\\R\\RWorkspace\\orgData.txt",encoding ="UTF-8")

>length(hlzj)

[1] 1640

接下来就是做分词了,要先去除数据中可能存在的数字和一些特殊符号,然后分词。

>hlzjTemp <- gsub("[0-90123456789< > ~]","",hlzj)

> hlzjTemp <- segmentCN(hlzjTemp)

> hlzjTemp[1:2]

[[1]]

[1] "新品"     "推荐"     "时尚"     "迷彩"     "面料"     "设计"

[7] "为"       "简约"     "的"       "单"       "西"       "注入"

[13] "非同凡响""的"       "野性"     "魅力"     "良好"     "的"

[19] "防水"     "效果"     "使得"     "实用"     "性"       "更"

[25] "高"       "极"       "具"       "春日"     "吸"       "睛"

[31] "亮点"     "春季"     "新品"     "海澜之家" "男士"     "休闲"

[37] "西服"     "韩版"     "迷彩"     "西装"     "外套"     "HWXAJAA"

[[2]]

[1] "小编"     "推荐"     "修身"     "薄款"     "连帽"     "暖心"

[7] "设计"     "防风"     "保暖"     "撞色"     "线条"     "设计"

[13] "年轻"     "时尚"     "走亲访友" "休闲"     "出行"     "的"

[19] "时尚"     "选择"     "活力"     "过冬"     "保暖"     "轻松"

[25] "冬季"     "热卖"     "海澜之家" "正品"     "男士"     "保暖"

[31] "连帽"     "羽绒服"   "外套"     "HWRAJGA"

可以看到微博内容都已经被做过分词处理了,这个过程很简单,但实际上可能需要多次查看分词处理结果,有些词库中不存在所以被截开了的词需要被添加进去,从而让分词效果达到最好。

3.       去停词

分词已经有结果了,但是分词的结果中存在很多像,“吧”,“吗”,“的”,“呢”这些无实际含义的语气词,或者是“即使”,“但是”这样的转折词,或者是一些符号,这样的词就叫做停词。要做进一步的分析可能需要去掉这些停词。

先自己整理一个停词表,这个停词表是我自己找的,包含一些常见的停词,然后根据实际内容中出现的一些无实际分析意义的词语,就可以作为我们的停词表了,网上能找到别人已经整理好的停词表。

>stopwords<- unlist(read.table("D:\\R\\RWorkspace\\StopWords.txt",stringsAsFactors=F))

> stopwords[50:100]

V150       V151       V152       V153       V154       V155       V156

"哎哟"       "唉"       "俺"     "俺们"       "按"     "按照"       "吧"

V157       V158       V159       V160       V161       V162       V163

"吧哒"       "把"     "罢了"       "被"       "本"     "本着"       "比"

V164       V165       V166       V167       V168       V169       V170

"比方"     "比如"     "鄙人"       "彼"     "彼此"       "边"       "别"

V171       V172       V173       V174       V175       V176       V177

"别的"     "别说"       "并"     "并且"     "不比"     "不成"     "不单"

V178       V179       V180       V181       V182       V183       V184

"不但"     "不独"     "不管"     "不光"     "不过"     "不仅"     "不拘"

V185       V186       V187       V188       V189       V190       V191

"不论"     "不怕"     "不然"     "不如"     "不特"     "不惟"     "不问"

V192       V193       V194       V195       V196       V197       V198

"不只"       "朝"     "朝着"       "趁"     "趁着"       "乘"       "冲"

V199      V1100

"除""除此之外"

removeStopWords <- function(x,stopwords) {

temp <- character(0)

index <- 1

xLen <- length(x)

while (index <= xLen) {

if (length(stopwords[stopwords==x[index]]) <1)

temp<- c(temp,x[index])

index <- index +1

}

temp

}

> hlzjTemp2 <-lapply(hlzjTemp,removeStopWords,stopwords)

> hlzjTemp2[1:2]

[[1]]

[1] "新品"     "推荐"     "时尚"     "迷彩"     "面料"     "设计"

[7] "简约"     "单"       "西"       "注入"     "非同凡响" "野性"

[13] "魅力"     "防水"     "效果"     "实用"     "性"       "高"

[19] "极"       "具"       "春日"     "吸"       "睛"       "亮点"

[25] "春季"     "新品"     "海澜之家" "男士"     "休闲"     "西服"

[31] "韩版"     "迷彩"     "西装"     "外套"     "HWXAJAA"

[[2]]

[1] "小编"     "推荐"     "修身"     "薄款"     "连帽"     "暖心"

[7] "设计"     "防风"     "保暖"     "撞色"     "线条"     "设计"

[13] "年轻"     "时尚"     "走亲访友" "休闲"     "出行"     "时尚"

[19] "选择"     "活力"     "过冬"     "保暖"     "轻松"     "冬季"

[25] "热卖"     "海澜之家" "正品"     "男士"     "保暖"     "连帽"

[31] "羽绒服"   "外套"     "HWRAJGA"

跟hlzjTemp[1:2]的内容比较可以明显发现“的”这样的字都被去掉了。

4.       词云

词云是现在很常见的一种分析图,把这些词语放在一张图中,频次来显示词语的大小,这样就能很直观看出那些词语出现得比较多,在舆情分析中经常被用到。

下面的过程是将分词结果做一个统计,计算出每个词出现的次数并排序,然后取排名在前150的150个词语,用wordcloud()方法来画词云。

> words <- lapply(hlzjTemp2,strsplit," ")

> wordsNum <- table(unlist(words))

> wordsNum <- sort(wordsNum) #排序

> wordsData <- data.frame(words =names(wordsNum), freq = wordsNum)

> library(wordcloud) #加载画词云的包

> weibo.top150 <- tail(wordsData,150) #取前150个词

>colors=brewer.pal(8,"Dark2")

>wordcloud(weibo.top150$words,weibo.top150$freq,scale=c(8,0.5),colors=colors,random.order=F)

该品牌微博的内容有很明显的特征,品牌名“海澜之家”出现的次数远大于其他词语;其次出现频度比较高的词语是“链接”,“旗舰店”,“时尚”,“新品”,“修身”,“男装”,可以大概看出这个该品牌专注于男装,该微博账号经常做新品推荐,可能会提供服装链接到它的旗舰店;另外还能看到“全能星战”,“奔跑吧兄弟”这样的电视节目,稍微了解一下就知道,这是海澜之家这两年赞助的两个节目,所以在它的微博中出现多次是很正常的。

原始数据就不共享了,大家可以另外找数据尝试。

Part3文本聚类

分类和聚类算法,都是数据挖掘中最常接触到的算法,分类聚类算法分别有很多种。可以看下下面两篇文章对常见的分类聚类算法的简介:

分类算法:http://blog.csdn.net/chl033/article/details/5204220

聚类算法:http://blog.chinaunix.net/uid-10289334-id-3758310.html

文本分类聚类会要用到这些算法去实现,暂时不用深究算法细节,R中已经有成熟的可以直接调用的这些算法了。大概说下分类和聚类的差异,照我的理解,分类算法和聚类算法最后实现的效果是相同的,都是给一个集合划分成几个类别。不同的是分类算法是根据已知的确定类别去做划分,所以分类需要训练集,有训练、测试、预测这个过程;而聚类则未规定类别,它是基于给定集合的里面的内容,根据内容的相似度去给集合划分成指定的几个类(你可以指定划分成多少个类,而不是指定有哪些类),这些相似度的测量就是聚类算法的核心,这个度量标准可以是欧几里得距离、是曼哈顿距离、是切比雪夫距离等等。它们分别叫做有监督分类和无监督分类。

还是用Part2里面的例子。做聚类不需要训练集,将文本内容做完分词处理,也就是Part2里面2.对某品牌官微做分词,这里处理完得到的结果hlzjTemp,用这个做接下来的聚类工作。下图(图片来源:玩玩文本挖掘)是一个文本挖掘的过程,不管是分类还是聚类,都要经历前面一个过程将文本转为为Tem-Document Matrix。然后再做后续分析Analysis,及分类或者聚类。另一个参考:R语言进行中文分词和聚类

聚类算法是针对数值型变量的,先要将文本数据转换为matrix—数据矩阵。过程如下,这里需要用到tm软件包,先安装该软件包并加载。tm包中的Corpus()方法就是用来将文本转换为语料库的方法。DocumentTermMatrix()方法,显然就是将语料库转换为文档-词条矩阵,然后再将文档-词条矩阵转换为普通矩阵,过程如下:

>library(tm)

载入需要的程辑包:NLP

>corpus  <-Corpus(VectorSource(hlzjTemp))

> hlzj.dtm<- DocumentTermMatrix(corpus,control=list(wordLengths=c(1,Inf)))

>hlzj.matrix <- as.matrix(hlzj.dtm)

补充说明:这个过程可能会遇到很多问题,没有详细的说明,附上两个参考:用tm进行文本挖掘、R语言文本挖掘。

接下来就是做聚类了,聚类算法有很多,常见的几种做聚类的方法

1.      kmeans()

方法的介绍参考:http://blog.sina.com.cn/s/blog_4ac9f56e0101h8xp.html。运行结果kmeansRes是一个list,names方法可以查看到kmeansRes的所有维度或者说组件,其中第一个cluster就是对应的分类结果,我们可以查看到前三十个聚类的结果,第一排对应着行号,第二排对应着聚类的结果1-5分别代表1-5类。然后我们可以将原始微博和聚类结果赋值给一个新的list变量,这样我们就能看到聚类结果和每条微博对应的关系了。最后将这个新的list变量hlzj.kmeansRes导出到本地,就能很方便地查看到聚类结果了。当然我们也可以通过fix()方法查看hlzj.kmeansRes的内容,如图所示,content是原微博内容,type是聚类结果。每个类别对应的文本数据的特点就要靠我们自己来总结了,这是聚类的一个不足的地方。

> k <- 5

> kmeansRes <- kmeans(hlzj.matrix,k) #k是聚类数

> mode(kmeansRes)#kmeansRes的内容

[1]"list"

> names(kmeansRes)

[1]"cluster"     "centers"     "totss"       "withinss"

[5]"tot.withinss" "betweenss"    "size"         "iter"

[9]"ifault"

> head(kmeansRes$cluster,10)

1 2  3  4 5  6  7 8  9 10

1 1  1  2 1  5  2 1  1  5

> kmeansRes$size #每个类别下有多少条数据

[1]  327  1159   63  63   27

>hlzj.kmeansRes <- list(content=hlzj,type=kmeansRes$cluster)

> write.csv(hlzj.kmeansRes,"hlzj_kmeansRes.csv")

> fix(hlzj.kmeansRes)

2.      hclust()。

方法详细介绍,过程不再细说http://blog.sina.com.cn/s/blog_615770bd01018dnj.html,这个方法可以用plot()来查看聚类结果图,但是在数据量挺多的时候,图的上面的内容都挤在一起看不清楚了,这种情况下,还是直接查看聚类结果比较好。同样,将原始数据hlzj和分类结果放在一起hlzj.hclustRes来看。可以看出类跟kmeans的聚类结果有些接近,说明微博的特征还是挺明显的。

>hclustRes <- hclust(hlzj,matrix,method="complete")

> hclustRes.type <- cutree(hclustRes,k=5) #按聚类结果分5个类别

> length(hclustRes.type)

[1] 1639

> hclustRes.type[1:10]

1 2  3  4 5  6  7 8  9 10

1 1  1  2 1  2  3 1  1  2

> hlzj.hclustRes <- list(content=hlzj,type=hclustRes.type)

> hlzj.hclustRes <- as.data.frame(hlzj.hclustRes)

>fix(hlzj.hclustRes)

3.      kernel聚类,方法specc()

软件包kernlab中的specc()方法可以实现kernel聚类算法。查看这个包的说明文档,见链接http://127.0.0.1:25210/library/kernlab/doc/kernlab.pdf,这是本机的帮助文档,不知道大家的地址是不是都一致的,也可以输入??kernel查看帮助文档能看到。网上能够找到的翻译后的方法说明http://www.biostatistic.net/thread-49108-1-1.html。这个聚类结果五个分类的统计如下,第四个类别有1402个,其他分类分别是135,55,24和23,所以截图中看到前面23个都是4类下,用这个聚类可能效果不是很理想。具体实现过程如下:

> stringkern <-stringdot(type="string")

> kernelRes <-specc(hlzj.matrix,centers=5,kernel=stringkern)

> mode(kernelRes)

[1] "numeric"

> length(kernelRes)

[1] 1639

> kernelRes[1:10]

1  2 3  4  5  6  7 8  9 10

4  4 4  4  4  4  4 4  4  4

> table(kernelRes)

kernelRes

1    2   3    4    5

135   55  24 1402   23

>temp <-t(kernelRes) #行列转换

> hlzj.kernelRes<-list(cotent=hlzj,type=temp[1:1639]

> hlzj.kernelRes <-as.data.frame(hlzj.kernelRes)

>fix(hlzj.kernelRes)

4.      除此之外。

fpc软件包中的dbscan()方法可以实现dbscan聚类,还有其他的聚类方法,就不一一介绍了,优劣取舍要在实际应用中去控制了。

Part4文本分类

Part3文本聚类里讲到过,分类跟聚类的简单差异。所以要做分类我们需要先整理出一个训练集,也就是已经有明确分类的文本;测试集,可以就用训练集来替代;预测集,就是未分类的文本,是分类方法最后的应用实现。

1.       数据准备

训练集准备是一个很繁琐的功能,暂时没发现什么省力的办法,根据文本内容去手动整理。这里还是使用的某品牌的官微数据,根据微博内容,我将它微博的主要内容分为了:促销资讯(promotion)、产品推介(product)、公益信息(publicWelfare)、生活鸡汤(life)、时尚资讯(fashionNews)、影视娱乐(showbiz),每个分类有20-50条数据,如下可看到训练集下每个分类的文本数目,训练集分类名为中文也没问题。

训练集为hlzj.train,后面也会被用作测试集。

预测集就是Part2里面的hlzj。

> hlzj.train <-read.csv("hlzj_train.csv",header=T,stringsAsFactors=F)

> length(hlzj.train)

[1] 2

> table(hlzj.train$type)

fashionNews      life         product

27            34            38

promotion    publicWelfare     showbiz

45            22            36

> length(hlzj)

[1] 1639

2.       分词处理

训练集、测试集、预测集都需要做分词处理后才能进行后续的分类过程。这里不再详细说明,过程类似于Part2中讲到的。训练集做完分词后hlzjTrainTemp,之前对hlzj文件做过分词处理后是hlzjTemp。然后分别将hlzjTrainTemp和hlzjTemp去除停词。

> library(Rwordseg)

载入需要的程辑包:rJava

# Version: 0.2-1

> hlzjTrainTemp <- gsub("[0-90123456789< > ~]","",hlzj.train$text)

> hlzjTrainTemp <-segmentCN(hlzjTrainTemp)

> hlzjTrainTemp2 <-lapply(hlzjTrainTemp,removeStopWords,stopwords)

>hlzjTemp2 <-lapply(hlzjTemp,removeStopWords,stopwords)

3.      得到矩阵

在Part3中讲到了,做聚类时要先将文本转换为矩阵,做分类同样需要这个过程,用到tm软件包。先将训练集和预测集去除停词后的结果合并为hlzjAll,记住前202(1:202)条数据是训练集,后1639(203:1841)条是预测集。获取hlzjAll的语料库,并且得到文档-词条矩阵,将其转换为普通矩阵。

> hlzjAll <- character(0)

> hlzjAll[1:202] <- hlzjTrainTemp2

> hlzjAll[203:1841] <- hlzjTemp2

> length(hlzjAll)

[1] 1841

> corpusAll <-Corpus(VectorSource(hlzjAll))

> (hlzjAll.dtm <-DocumentTermMatrix(corpusAll,control=list(wordLengths = c(2,Inf))))

<>

Non-/sparse entries: 33663/20167630

Sparsity           : 100%

Maximal term length: 47

Weighting          : term frequency (tf)

> dtmAll_matrix <-as.matrix(hlzjAll.dtm)

4.      分类

用到knn算法(K近邻算法),这个算法在class软件包里。矩阵的前202行数据是训练集,已经有分类了,后面的1639条数据没有分类,要根据训练集得到分类模型再为其做分类的预测。将分类后的结果和原微博放在一起,用fix()查看,可以看到分类结果,效果还是挺明显的。

> rownames(dtmAll_matrix)[1:202] <-hlzj.train$type

> rownames(dtmAll_matrix)[203:1841]<- c("")

> train <- dtmAll_matrix[1:202,]

> predict <-dtmAll_matrix[203:1841,]

> trainClass <-as.factor(rownames(train))

> library(class)

> hlzj_knnClassify <-knn(train,predict,trainClass)

> length(hlzj_knnClassify)

[1] 1639

> hlzj_knnClassify[1:10]

[1] product    product     product     promotion  product     fashionNews life

[8] product    product     fashionNews

Levels: fashionNews life productpromotion publicWelfare showbiz

> table(hlzj_knnClassify)

hlzj_knnClassify

fashionNews    life   product     promotion   publicWelfare   showbiz

40        869       88        535        28        79

> hlzj.knnResult <-list(type=hlzj_knnClassify,text=hlzj)

> hlzj.knnResult <-as.data.frame(hlzj.knnResult)

> fix(hlzj.knnResult)

Knn分类算法算是最简单的一种,后面尝试使用神经网络算法(nnet())、支持向量机算法(svm())、随机森林算法(randomForest())时,都出现了电脑内存不够的问题,我的电脑是4G的,看内存监控时能看到最高使用达到3.92G。看样子要换台给力点的电脑了╮(╯▽╰)╭

在硬件条件能达到时,应该实现分类没有问题。相关的算法可以用:??方法名,的方式来查看其说明文档。

5.       分类效果

上面没有讲到测试的过程,对上面的例子来说,就是knn前两个参数都用train,因为使用数据集相同,所以得到的结果也是正确率能达到100%。在训练集比较多的情况下,可以将其随机按7:3或者是8:2分配成两部分,前者做训练后者做测试就好。这里就不再细述了。

在分类效果不理想的情况下,改进分类效果需要丰富训练集,让训练集特征尽量明显,这个在实际问题是一个很繁琐却不能敷衍的过程。

Part5情感分析

这是这个系列里面最后一篇文章了,其实这里文本挖掘每一个部分单拎出来都是值得深究和仔细研究的,我还处于初级研究阶段,用R里面现成的算法,来实现自己的需求,当然还参考了众多网友的智慧结晶,所以也想把我的收获总结出来分享给大家,希望也能像我一样在看大家的分享时得到自己的启发。

网上翻了下中文文本情感分析的一些文章,再回想了一下我自己做情感分析的方法,觉得我的想法真的是简单粗暴直接。这是一篇介绍中文文本情感分析倾向的论文。http://wenku.baidu.com/link?url=TVf5LgNS6esnunpgubvM14z24m0f4lTyD483gw_hEnp2RyeL6XzanSlz8oCcZCFlwKLqD0PdBhVUcV4-0loTdGp3hL-kqeTTwJ3l91HfTa3,中间讲到做情感分析目前主要有三种方法。第一种由已有的电子词典或词语知识库扩展生成情感倾向词典;第二种,无监督机器学习的方法。第三种基于人工标注语料库的学习方法。

上面三种方法不仔细一一说明了,它们都有一个共同的特点,需要一个情感倾向的语料库。我在R中的实现方案与第一种方法类似,整理一个褒义词词库一个贬义词词库(这个万能的互联网上有自己稍加整理就OK)。给文本做分词,并提取出中间的情感词。给每条文本定情感倾向评分初始值为1,跟褒义贬义词词库做匹配,褒义词+1,贬义词-1,计算出每条文本的最终情感倾向评分,为正值则是正面评价,为负值则是负面评价。方法可以基本实现情感倾向判断,但还可以改进。像前面参考论文中讲到的,还可以根据词语的词性强弱来评定感情的强,不只是+1和-1之分;还有考虑一些词语在不同语境下情感倾向可能会不同,比如论文中讲到的“骄傲”,这个我在想可能需要整理出有这样特殊情况的词语;还有负负得正的情况,比如“不喜欢是不可能的事情!”,照我的评分标准它的结果就是负面评价了;反问的情况,“哪里便宜了?”,评出来结果变成了正。“便宜”这个词我把它放在褒义词表下,其实仔细考虑如果是说“便宜实惠”肯定是褒义,如果说“便宜没好货”,也会是褒义,这就不对了,还是第二个问题不同语境下情感倾向会不同。

R中的实现过程:

1.      数据输入处理

数据还是某品牌官微,取它微博中的1376条评论,情感褒义词库和贬义词库,将数据读入到R中。附词库下载地址:http://www.datatang.com/data/44317/,可能不是很全,需要自己整理丰富,我在看服装相关的文本时,发现有些词像“褪色”,“开线”,“显瘦”,“显胖”都没有在里面,这些就需要自己另外加进去。

> hlzj.comment <- readLines("hlzj_commentTest.txt")

> negative <-readLines("D:\\R\\RWorkspace\\hlzjWorkfiles\\negative.txt")

> positive <-readLines("D:\\R\\RWorkspace\\hlzjWorkfiles\\positive.txt")

> length(hlzj.comment)

[1] 1376

> length(negative)

[1] 4477

> length(positive)

[1] 5588

2.      对评论做分词处理并评级

过程类似Part2中讲到的分词处理。然后我自己写了个方法getEmotionalType(),将分词结果与negative表和positive表作对照计算得分。

> commentTemp <- gsub("[0-90123456789< > ~]","",hlzj.comment)

> commentTemp <-segmentCN(commentTemp)

> commentTemp[1:2]

[[1]]

[1] "恭喜""大家""又"   "没有" "找到" "俺"

[[2]]

[1] "没有" "私信" "給"   "我"   "小编" "把"   "我"   "给"   "漏"   "了"

> EmotionRank <-getEmotionalType(commentTemp,positive,negative)

[1] 0.073

[1] 0.145

[1] 0.218

[1] 0.291

[1] 0.363

[1] 0.436

[1] 0.509

[1] 0.581

[1] 0.654

[1] 0.727

[1] 0.799

[1] 0.872

[1] 0.945

> EmotionRank[1:10]

[1] 1 0 2 1 1 2 3 1 0 0

> commentEmotionalRank <-list(rank=EmotionRank,comment=hlzj.comment)

> commentEmotionalRank <-as.data.frame(commentEmotionalRank)

> fix(commentEmotionalRank)

[plain]view plaincopyprint?

getEmotionalType <- function(x,pwords,nwords){

emotionType <-numeric(0)

xLen <-length(x)

emotionType[1:xLen]<- 0

index <- 1

while(index <=xLen){

yLen <-length(x[[index]])

index2 <- 1

while(index2<= yLen){

if(length(pwords[pwords==x[[index]][index2]]) >= 1){

emotionType[index] <- emotionType[index] + 1

}elseif(length(nwords[nwords==x[[index]][index2]]) >= 1){

emotionType[index] <- emotionType[index] - 1

}

index2<- index2 + 1

}

#获取进度

if(index%%100==0){

print(round(index/xLen,3)

}

index <-index +1

}

emotionType

}

getEmotionalType <- function(x,pwords,nwords){    emotionType <-numeric(0)    xLen <-length(x)    emotionType[1:xLen]<- 0    index <- 1    while(index <=xLen){        yLen <-length(x[[index]])        index2 <- 1        while(index2<= yLen){           if(length(pwords[pwords==x[[index]][index2]]) >= 1){               emotionType[index] <- emotionType[index] + 1            }elseif(length(nwords[nwords==x[[index]][index2]]) >= 1){               emotionType[index] <- emotionType[index] - 1            }            index2<- index2 + 1        }        #获取进度       if(index%%100==0){        print(round(index/xLen,3)        }              index <-index +1    }    emotionType}

查看到结果如下,第一个图里看着还挺正常的,第二个图好像是hlzj赞助的RM里出现了衣服被撕坏的时候的评论。没有黑他们家的意思,只是想找个例子来说明下差评的效果,好像不是很理想。那些反问的话无法识别判断,还有一些比较口语化的“醉了”,“太次”这样的词没有放到情感词库里,对这些评论的情感倾向识别效果不是很好。

像前面说的,方法有待改进,我的方法只是一个最基础的情感分析的实现方式,有任何问题欢迎指正。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,580评论 18 139
  • 常用概念: 自然语言处理(NLP) 数据挖掘 推荐算法 用户画像 知识图谱 信息检索 文本分类 常用技术: 词级别...
    御风之星阅读 9,148评论 1 25
  • 文从小就是一个很上进的女孩子,她在老家做文职,工资也就两千不到,她和我说,她不想就窝在她们老家这样生活下去,每个月...
    章鱼妈_1ab5阅读 367评论 0 0
  • 从健身房走出来,突然闻到一阵桂花香,味道不是很浓烈,可能是因为花期要过了的原因吧。抬头一看,果然,门口有一棵桂花树...
    longlong8612009阅读 112评论 0 3
  • 一 许多年以后,当我的灵魂扭曲着升起,自嘲地看着自己的躯体的时候,我想起这个夜晚,我开着从我的老毛子室友那边借来的...
    大乙八郎阅读 524评论 0 0