R微博内容聚类

由于时间较紧,且人手不够,不能采用分类方法,主要是没有时间人工分类一部分生成训练集……所以只能用聚类方法,聚类最简单的方法无外乎:K-means与层次聚类。

尝试过使用K-means方法,但结果并不好,所以最终采用的是层次聚类,也幸亏结果还不错……⊙﹏⊙

分词(Rwordseg包):

分词采用的是Rwordseg包,具体安装和一些细节请参考作者首页 http://jliblog.com/app/rwordseg。请仔细阅读该页提供的使用说明pdf文档,真是有很大帮助。

安装:

P.S.

由于我是64位机,但是配置的rj包只能在32bit的R上使用,而且Rwordseg包貌似不支持最新版本的R(3.01),所以请在32bit的R.exe中运行如下语句安装0.0-4版本:

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

貌似直接在Rstudio中运行会安装失败,而且直接在Rstudio中点击install安装,安装的是0.0-5版本,我就一直失败……

使用:

分词时尽量关闭人名识别

segmentCN(doc,recognition=F)

否则会将“中秋国庆”,分为“中”“秋国庆“

可以使用insertWords()函数添加临时的词汇

对文档向量进行分词时,强烈建议用for循环对每一个元素执行segmentCN,而不要对整个向量执行!!!因为我蛋疼的发现对整个向量执行时,还是会出现识别人名的现象……

运行完后请detach()包,removeWords()函数与tm包中的同名函数冲突。

微博分词的一些建议:

微博内容中经常含有url,分词后会将url拆散当做英文单词处理,所以我们需要用正则表达式,将url去掉:

gsub(pattern="http:[a-zA-Z\\/\\.0-9]+","",doc)

微博中含有#标签#,可以尽量保证标签的分词准确,可以先提取标签,然后用insertWords()人工添加一部分词汇:

tag=str_extract(doc,"^#.+?#") #以“#”开头,“."表示任意字符,"+"表示前面的字符至少出现一次,"?"表示不采用贪婪匹配—即之后遇到第一个#就结束

tag=na.omit(tag) #去除NA

tag=unique(tag) #去重

文本挖掘(tm包):

语料库:

分词之后生成一个列表变量,用列表变量构建语料库。

由于tm包中的停用词()都是英文(可以输入stopwords()查看),所以大家可以去网上查找中文的停用词(一般700多个的就够了,还有1208个词版本的),用removeWords函数去除语料库中的停用词:

doc.corpus=tm_map(doc.corpus,removeWords,stopwords_CN)

TDM:

生成语料库之后,生成词项-文档矩阵(Term Document Matrix,TDM),顾名思义,TDM是一个矩阵,矩阵的列对应语料库中所有的文档,矩阵的行对应所有文档中抽取的词项,该矩阵中,一个[i,j]位置的元素代表词项i在文档j中出现的次数。

由于tm包是对英文文档就行统计挖掘的,所以生成TDM时会对英文文档进行分词(即使用标点和空格分词),之前Rwordseg包做的就是将中文语句拆分成一个个词,并用空格间隔。

创建TDM的语句为:

control=list(removePunctuation=T,minDocFreq=5,wordLengths = c(1, Inf),weighting = weightTfIdf)

doc.tdm=TermDocumentMatrix(doc.corpus,control)

变量control是一个选项列表,控制如何抽取文档,removePunctuation表示去除标点,minDocFreq=5表示只有在文档中至少出现5次的词才会出现在TDM的行中。

tm包默认TDM中只保留至少3个字的词(对英文来说比较合适,中文就不适用了吧……),wordLengths = c(1, Inf)表示字的长度至少从1开始。

默认的加权方式是TF,即词频,这里采用Tf-Idf,该方法用于评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度:

在一份给定的文件里,词频 (term frequency, TF) 指的是某一个给定的词语在该文件中出现的次数。这个数字通常会被归一化,以防止它偏向长的文件。

逆向文件频率 (inverse document frequency, IDF) 是一个词语普遍重要性的度量。某一特定词语的IDF,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取对数得到。

某一特定文件内的高词语频率,以及该词语在整个文件集合中的低文件频率,可以产生出高权重的TF-IDF。因此,TF-IDF倾向于保留文档中较为特别的词语,过滤常用词。

由于TDM大多都是稀疏的,需要用removeSparseTerms()函数进行降维,值需要不断的测试,我一般会使词项减少到原有的一半。

层次聚类:

层次聚类的核心实际在距离阵的计算,一般聚类时会使用欧氏距离、闵氏距离等,但在大型数据条件下会优先选择 cosine 距离,及 dissmilarity 函数:

dissimilarity(tdm_removed, method = 'cosine')

(P.S.要使用cosine方法,需要先安装proxy包。)

层次聚类的方法也有很多,这里选用mcquitty,大家还是多试试,本文给出的选择不一定适合你~

注意:由于R对向量的大小有限制,所以在计算距离时,请优先使用64bit,3.0版本的R~

但如果出现如下报错信息:

"Error in vector(typeof(x$v), nr * nc) : vector size cannot be NAIn addition: Warning message:

In nr * nc : NAs produced by integer overflow"

恭喜你!这个问题64位版本的R也解决不了,因为矩阵超出了R允许的最大限制~我也是遇到同样的问题,所以没办法,只能将原始数据进行拆分,不过我的情况是多个微博账户,但彼此之间的微博分类差不太多,所以可以进行拆分。强烈推荐大家有问题去stackoverflow查找!

(我看到有国外友人说可以用int64包尝试一下,因为tdm其实也是个list,但我没试成功……)

好了,下面贴上全部代码:

全文word版下载:

回复 数据挖掘入门与实战 公众号 “聚类”即可获取。

################################################################## 读取数据

col=c(rep("character",6),"NULL",NA,NA,"character",rep("NULL",4))

data=read.csv(file="text.csv",header=T,sep=",",colClasses=col)

# 将文本存储到一个向量中

doc=c(NULL)for(i in 1:dim(data)[1]){

doc=c(doc,data$Text[i])

}################################################################## 去除微博中含有的url

doc=gsub(pattern="http:[a-zA-Z\\/\\.0-9]+","",doc)

# 无意义微博处理

empty_N=c(2032,2912,7518,8939,14172,14422,26786,30126,34501,35239,48029,48426,48949,49100,49365,49386,49430,50034,56818,56824,56828,57859)

doc[empty_N]="NA"

################################################################## 添加词汇

library("Rwordseg")

textwords=c("...")

insertWords(textwords)

# removeWords(tagwords)

doc_CN=list()for(j in 1:length(doc)){

doc_CN[[j]]=c(segmentCN(doc[j],recognition=F))

}

detach("package:Rwordseg", unload=TRUE)

################################################################## 构建语料库(Corpus对象)

library("tm")

doc.corpus=Corpus(VectorSource(doc_CN))

###########停用词###########

data_stw=read.table(file="中文停用词库.txt",colClasses="character")

stopwords_CN=c(NULL)for(i in 1:dim(data_stw)[1]){

stopwords_CN=c(stopwords_CN,data_stw[i,1])

}

doc.corpus=tm_map(doc.corpus,removeWords,stopwords_CN)

# 删除停用词############################# 创建词项-文档矩阵(TDM)

control=list(removePunctuation=T,minDocFreq=5,wordLengths = c(1, Inf),weighting = weightTfIdf)

doc.tdm=TermDocumentMatrix(doc.corpus,control)

length(doc.tdm$dimnames$Terms)

tdm_removed=removeSparseTerms(doc.tdm, 0.9998)

# 1-去除了低于 99.98% 的稀疏条目项

length(tdm_removed$dimnames$Terms)

################################################################## 层次聚类:

dist_tdm_removed <- dissimilarity(tdm_removed, method = 'cosine')

hc <- hclust(dist_tdm_removed, method = 'mcquitty')

cutNum = 20

ct = cutree(hc,k=cutNum)

sink(file="result.txt")

for(i in 1:cutNum){ print(paste("第",i,"类: ",sum(ct==i),"个")); print("----------------");

print(attr(ct[ct==i],"names"));

# print(doc[as.integer(names(ct[ct==i]))])

print("----------------")

}

sink()

#输出结果

output=data.frame(clas=NULL,tag=NULL,text=NULL)for(i in 1:cutNum){

in_tag=tag[as.integer(names(ct[ct==i]))]

in_text=doc[as.integer(names(ct[ct==i]))]

cut_output=data.frame(clas=rep(i,length(in_tag)),tag=in_tag,text=in_text)

output=rbind(output,cut_output)

}

write.table(output,file="classification.csv",sep=",",row.names=F)

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

推荐阅读更多精彩内容