顾名思义,词云就是由词汇组成类似云彩的图形。对于篇幅庞大的文本而言,使用词云进行描述可以过滤掉很多冗杂而无意义的信息,诸如空格、标点符号、停词(像 and,or,but 等)等。
1 什么是词云?
词云是近几年来比较新潮的一个名词,是很多媒体或者社交软件用来展现文本中“关键词”出现频率的有效手段。
观看者一眼扫过就可以快速获取文本中的高频词汇信息。
词云制作需要词和相应频率的信息,但通常我们面临的是原始文本数据。因此,本文试着完整展示整个过程——先从原始文本数据出发,经过必要的数据清洗,最后实现画词云的目的。
在实现过程中需要借助强大的文本处理包tm
包和SnowballC
包,以及具有较大可操作性的词云制作包wordcloud2
包,大家提前在 R 中安装好。
install.packages("tm")
install.packages("SnowballC")
install.packages("wordcloud2")
2 案例导入
本案例是Brett Lantz所著的《机器学习与R语言》中的相关章节内容的重现。
我们考虑垃圾短信分类问题——现实中很多人深受垃圾短信其害,因此我们希望设计一套算法通过分析短信中的文本内容来判断其是否为垃圾短信从而采取规避措施。
sms_raw <- read.csv("sms_spam.csv",stringsAsFactors = F)
str(sms_raw)
'data.frame': 5559 obs. of 2 variables:
$ type: chr "ham" "ham" "ham" "spam" ...
$ text: chr "Hope you are having a good week. Just checking in" "K..give back my thanks." "Am also doing in cbe only. But have to pay." "complimentary 4 STAR Ibiza Holiday or 拢10,000 cash needs your URGENT collection. 09066364349 NOW from Landline"| __truncated__ ...
可见该数据包含两个变量,分别是短信的标签(type):垃圾(spam)和正常(ham)以及短信内容(text)。
3 程序设计
为了分别得到垃圾短信和正常短信的词云,首先采用subset
函数按照短信标签将spam和ham的短信内容分别提取出来。
sms_spam <- subset(sms_raw,type == “spam”)# 选取所有的垃圾信息
sms_ham <- subset(sms_raw,type == “ham”)# 选取所有的正常信息
以正常短信为例,考虑先将所有的正常短信内容拼接到一起。
composition <- paste0(sms_ham,collapse = ' ')# 将所有信息拼合在一起
接下来就是词云制作过程中的重要也是困难部分——文本处理。
通常短信内容包含了很多冗杂的信息比如前面提到的标点等,显然对于本问题能提供的有效信息微乎其微,因此我们需要在制作词云前将他们移除出去。这里就需要R中强大的tm
包和SnowballC
包。
sms_corpus <- VCorpus(VectorSource(composition))# 建立语料库
sms_corpus_clean <- tm_map(sms_corpus,content_transformer(tolower))# 全部转换成小写字母
sms_corpus_clean <- tm_map(sms_corpus_clean,removeNumbers)# 移除数字
sms_corpus_clean <- tm_map(sms_corpus_clean,removeWords,stopwords())# 移除停词
replacePunctuation <- function(x){gsub("[[:punct:]]+"," ",x)}
sms_corpus_clean <- tm_map(sms_corpus_clean,removePunctuation)# 移除标点
sms_corpus_clean <- tm_map(sms_corpus_clean,stemDocument)# 提取词干
sms_corpus_clean <- tm_map(sms_corpus_clean,stripWhitespace)# 移除多余空格
至此文本处理工作就结束了,我们可以通过命令
str(sms_corpus_clean)
List of 1
$ 1:List of 2
..$ content: chr "c chope good week just check kgive back thank also cbe pay aiya discuss later lar pick u much buzi pleas ask mu"| __truncated__
..$ meta :List of 7
.. ..$ author : chr(0)
.. ..$ datetimestamp: POSIXlt[1:1], format: "2018-09-08 07:08:14"...
看到短信文本内容已经转换成意义较强的词汇(当然,你可能觉得里面仍然包括一些无意义的词汇,这通常和你所采用的停词表有关)。在制作词云前还有一项关键的步骤就是计算词频。
wordfreq <- termFreq(sms_corpus_clean[[1]])# 计算词频
wordfreq <- sort(wordfreq,decreasing = T)# 词频排序
最后我们就可以使用wordcloud2
包制作词云了。在wordcloud2
包中制作词云的命令就是wordcloud2
函数,它的基本使用方式如下。
wordcloud2(data, size = 1, minSize = 0, gridSize = 0,
fontFamily = NULL, fontWeight = 'normal',
color = 'random-dark', backgroundColor = "white",
minRotation = -pi/4, maxRotation = pi/4, rotateRatio = 0.4,
shape = 'circle', ellipticity = 0.65, widgetsize = NULL)
# 常用参数:
# (1)data:词云生成数据,包含具体词语以及频率;
# (2)size:字体大小,默认为1,一般来说该值越小,生成的形状轮廓越明显;
# (3)fontFamily:字体,如‘微软雅黑’;
# (4)fontWeight:字体粗细,包含‘normal’,‘bold’以及‘600’;
# (5)color:字体颜色,可以选择‘random-dark’以及‘random-light’,其实就是颜色色系;
# (6)backgroundColor:背景颜色,支持R语言中的常用颜色,如‘gray’,‘blcak’,
# (7)minRontatin与maxRontatin:字体旋转角度范围的最小值以及最大值,选定后,字体会在该范围内随机旋转;
# (8)rotationRation:字体旋转比例,如设定为1,则全部词语都会发生旋转;
# (9)shape:词云形状选择,默认是‘circle’,即圆形。还可以选择# ‘cardioid’(苹果形或心形),‘star’(星形),‘diamond’(钻石),‘triangle-forward’(三角形),‘triangle’(三角形),‘pentagon’(五边形);
通过对两种信息的内容处理,我们使用wordcloud2
函数做出两者的词云图形。
相信大家通过这两幅图就可以判断出左侧是来自于垃圾短信内容。比较右侧图片可以看出,左侧的高频词汇类似free和prize等很具有煽动性,这正是很多广告短信的特点。
4 其他参数调试
当然我们可以改变函数中的一些参数,从而画出不同形式、形状的词云。例如,设置shape
为star
画出星形词云。
wordcloud2(data,size = 1,shape = "star")# 星形
我们还利用wordcloud2
包中的letterCloud
函数,通过设置参数word
为R画出字母R形的词云图。
letterCloud(data, word ="R", wordSize = 2)# 字母R形
此外,wordcloud2
还有一个非常好用的功能,就是可以将词云的图形画成由用户输入的一张黑色图案。例如,我们可以输入一张奔跑的马形图案,然后利用该图案绘制马形词云图。
wordcloud2(data,size = 1,figPath = "fig/ma.png")# 马
5 结语
本文我们主要学习了R中词云的制作方法,通过wordcloud2
包实现各种词云的制作方式。其中,可以允许用户使用自定义的图案作词云图极大的丰富了词云的开发。