(R)R语言文本挖掘 读取文本,画wordcloud,情感分析

本文涉及,使用R语言读取文本(从txt文件、http链接或是https链接),构建TermDocumentMatrix(统计每个term(单词或词组)在每个document中出现的频次),绘制wordcloud,并进行情感分析(Sentiment Analysis)。
关键字: R语言,文本挖掘,WordCloud,Sentiment Analysis
数据来源:
要挖掘的数据来自于:
美国布什总统出兵伊拉克前的演讲:
https://www.historyplace.com/speeches/bush-war.htm
positive words和negative words来自于:
https://www.cs.uic.edu/~liub/FBS/sentiment-analysis.html

1 文本读取

1.1 从文件中读取文本

使用如下方法读取文本数据(scan或者readLines)

setwd("E:/Project/tripping/R_Plot/Data")
textfile <- "GB.txt"
# 一行一行地读取文本数据
# 方法1:
text <- scan(textfile, character(0), sep='\n')
#方法2: text <- readLines(textfile)

就我实验结果来看,读取的结果是一样的,都是把一行字符串作为列表中的一个元素.

1.2 从网页中读取文本

使用如下代码从一个HTTP链接中读取文本,读取的结果与1.1相同(这里我把一个模块用if语句括起来了,是为了方便注释)

# --- 从网页读取文本
library(XML)  # 应注意XML不支持HTTPS协议,HTTPS应先用RCurl中的getURL载入数据,或直接把HTTPS改为HTTP
# 处理HTTP
if (FALSE) {
  textLocation <- URLencode("http://www.historyplace.com/speeches/bush-war.htm")
  doc.html <- htmlTreeParse(textLocation, useInternal=TRUE)
  text <- unlist(xpathApply(doc.html, '//p', xmlValue))
  head(text, 3)
}

但要注意,HTTPS链接不适用于上面的xml方法,对于HTTPS,要么把链接里的HTTPS改成HTTP,然后用上面的xml方法,或者采用下面的RCurl的方法:

# 如果处理的是HTTPS,可如下处理:
if (TRUE) {
  library(RCurl)
  url <- "https://www.jianshu.com/p/48d758ce62b4"
  web <- getURL(url)
  doc<-htmlTreeParse(web,encoding="UTF-8", error=function(...){}, useInternalNodes = TRUE,trim=TRUE)
  text <- unlist(xpathApply(doc, '//p', xmlValue))
  head(text, 3)  # 在text中,每个元素是一行字符串
}

2 绘制WordCloud

刚刚读取的文本数据,形成的是一个列表,列表里每个元素是一个字符串,代表文本中的一行。
接下来我们要绘制WordCloud,需要统计在整个文本中每个单词出现的次数,然后对于高频词的单词画的更大。
我们采用的方式是,先构建一个矩阵,其中第i行第j列的元素表示第i个单词在文本的第j行中出现的次数。

library("tm")
words.vec <- VectorSource(text)
words.corpus <- Corpus(words.vec)
# 第二个参数里的content_transformer貌似加不加都一样的,这里对数据进行预处理
words.corpus <- tm_map(words.corpus, content_transformer(tolower))
words.corpus <- tm_map(words.corpus, content_transformer(removePunctuation))
words.corpus <- tm_map(words.corpus, removeNumbers)
words.corpus <- tm_map(words.corpus, removeWords, stopwords("english"))  # 删除stop words
tdm <- TermDocumentMatrix(words.corpus)
tdm

最后的tdm就是我们想要的矩阵,我们在输入tdm后,可以看到关于它的统计信息:

# 输出解读:
<<TermDocumentMatrix (terms: 578, documents: 37)>> #一共有578个term,37个documents(37行)
Non-/sparse entries: 934/20452  #在term-documents构成的578*37矩阵中,非空的只有934个元素
Sparsity           : 96%  #有96%的元素是空值
Maximal term length: 16  #一个term并非是一个单词,可能是一个词组,这里是最大term长度(16个字母)
Weighting          : term frequency (tf)

接下来,我们只需要对每一行求和,即可得到每个单词在整个文本中出现的频次:

m <- as.matrix(tdm)
wordCounts <- rowSums(m)
wordCounts <- sort(wordCounts, decreasing = TRUE)
head(wordCounts)

这里的wordCounts即为所求,接下来,我们把wordCounts转化成DataFrame的格式,便于绘制WordCloud

cloudFrame <- data.frame(word=names(wordCounts), freq=wordCounts)
# -- 绘制wordcloud
library("wordcloud")
wordcloud(cloudFrame$word, cloudFrame$freq)

绘制的WordCloud如下图所示:


WordCloud.png

3 情感分析(Sentiment Analysis)

在情感分析中,我们的目标是分析这个文本是积极的(positive)还是消极的(negative)
在之前已经有一些研究收集了英语中的积极词汇和消极词汇:
https://www.cs.uic.edu/~liub/FBS/sentiment-analysis.html
我们只需要统计我们的目标文本中积极词汇所占的比例和消极词汇所占的比例,即可得到关于文本的积极评分和消极评分。
首先,读取积极词汇文件和消极词汇文件,和刚刚一样,这里我们也是按行读取的,不过在这两个文件里,每个单词一行,所以这样也没什么问题。要注意,文本的开头有些别的信息,要删掉。

# -- Sentiment Analysis
setwd("../Data/opinion-lexicon-English")
pos <- "positive-words.txt"
neg <- "negative-words.txt"
p <- scan(pos, character(0), sep="\n")
n <- scan(neg, character(0), sep="\n")
p <- p[-1:-29]  # 文件的开头有些别的东西,要去掉
n <- n[-1:-30]
head(p, 10)
head(n, 10)

读取了积极单词和消极单词后,我们首先统计文本中积极单词的个数:

totalWords <- sum(wordCounts)  # 总的单词数目
words <- names(wordCounts)  # 都有哪些单词
matched <- match(words, p, nomatch=0)  # 返回一个矩阵,表示words中的每一个单词是p中的第几个单词
mCounts <- wordCounts[which(matched != 0)]
length(mCounts)  # 这篇文章中出现的positive的单词的种类个数(there were 40 unique positive words)
nPos <- sum(mCounts)
nPos  # 共有58个positive words

然后用同样的方法统计消极单词的个数:

# -- 下面对negative words做同样的操作,统计unique negative words的个数和negative words的个数
matched <- match(words, n, nomatch = 0)
nCounts <- wordCounts[which(matched != 0)]
nNeg <- sum(nCounts)
length(nCounts)
nNeg

最后分别计算积极单词和消极单词所占的比率:

totalWords <- length(words)
ratioPos <- nPos / totalWords
ratioNeg <- nNeg / totalWords
ratioPos
ratioNeg

最后结果:

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

推荐阅读更多精彩内容