心血来潮,想做一个微信聊天记录词云,于是就动手了。
最后的效果如下图所示
啊……我真的是一个爽朗的女孩子。
好了,下面就是步骤啦~ 请多多指教。
第一步:导出微信聊天记录。
我使用的手机是安卓系统,是按照 如何备份微信聊天记录—知乎 所说的方法导出来的。
如果你使用的是苹果,可以按照 记一次微信聊天文字导出到Excel工作—知乎 第二部分所说的方法导出记录。这里有点问题,我按照上述方法导出fts_message文件,打开后发现只有群聊。后来发现聊天记录其实是储存在MM.sqlite文件里,导出MM.sqlite文件使用sqlcipher打开,和每个人的聊天记录分别储存在一个表里,格式是"chat_***************"。
因为我是打算做一个自己的聊天记录词云(也就是说,只包含我本人发出的信息),所以在最后所用的sql语法为(此语法不适用于苹果聊天记录文件):
CREATE TABLE mywords AS
SELECT content
FROM message
WHERE type = 1 AND isSend = 1;
然后将表mywords导出,保存为txt格式。
第二步:用R语言分词并做词云。
#加载分词以及做词云所用的包
library(rJava)
library(Rwordseg)
library(wordcloud2)
#引入聊天记录
myfile <- read.csv("C:/Users/Administrator/Desktop/mywords.txt",
header = TRUE, stringsAsFactors = FALSE)
myfile包含了我发出的4541句话。
#进行分词
myfile.words <- unlist(lapply(X = myfile, FUN = segmentCN))
分词的效果是根据你所下载的词典决定的,但是仅依赖从网上下载并添加的词典进行分词可能达不到理想的效果。
比如,“奥宇”是我们学校的餐厅名,网上的词典肯定不会有这个词汇,还有“捂脸”这个词也被分开了。所以进行这一步时,要多次查看分词结果并使用insertWords()手动添加一些你常用的词汇,直到达到理想的分词效果。
insertWords(c("捂脸","奥宇"))
不过这种方法过于繁琐,最好的方法是从手机的输入法应用导出自己的用户词库,不知道其他输入法可不可以,我使用的讯飞输入法是可以导出的,总共导出了16000个词汇。将这个词汇文件添加进词典,对分词是很有帮助的。
接下来这一步要去掉分词中的停用词,包括“的”、“在”、“吧”、“呢”、“就”、“那就”等等无意义的词汇。
#去停词
这一步要去掉分词中的停用词,包括但不限于“的”、“在”、“吧”、“呢”、“就”、“那就”……等无意义的词汇。
##引入停词表
这里使用的停词表是在网上找的别人整理的,效果差强人意。可以根据去停词之后得到的分词情况在停词表手动添加一些未被归纳的停用词。
stopwords <- read.csv("C:/Users/Administrator/Desktop/stopwords.csv",
header = FALSE, stringsAsFactors = FALSE)
RemoveStopWords <- function(x,stopwords) {
temp <- character(0)
index <- 1
xLen <- length(x)
while (index <= xLen) {
if (sum(stopwords == x[index]) < 1)
temp<- c(temp, x[index])
index <- index + 1
}
temp
}
#对myfile.words去停词
words <- lapply(myfile.words, RemoveStopWords, stopwords)
到此,词汇已经处理完毕了,但是生成词云所要的数据是要包括词汇以及词汇出现的频率的。
所以要进行以下操作。
#生成词云数据(包含具体词语和频数)
wordsNum <- table(unlist(words))
wordsNum <- sort(wordsNum, decreasing = TRUE)
wordsData <- data.frame(wordsNum)
wordsData$Var1 <- as.character(wordsData$Var1)
此处要注意对频数表设置降序排列,因为之后的词云是按照所给数据的顺序生成的。也就是说,如果默认升序的话,频数最少的词汇将最先生成,且位置处于最中间;而频数最大的词汇将最后生成,且位置处于最外围。图案如下图所示,不太美观。
finaldata <- wordsData[1:200, ]
wordcloud2(finaldata, size = 1, shape = 'circle',color = 'random-light',
backgroundColor = "gray", fontFamily = "微软雅黑")
如有疑问请留言。