首先为两个事情道歉,1 增热点 2 标题党 (下文中并不会告诉你怎么花10亿,仅仅是一篇数据分析的案例)
开门见山
R语言有一个伟大的包:word2vec ,该包的一个主要功能就是通过神经网络将大量文本进行建模,根据上下文信息,词频信息等,将文本转化成数值向量。转化之后的向量,依然可以保留词语语义相关信息。比如之前统计之都那篇文章,张无忌 周芷若 赵敏 等人物 转化成数值向量之后,依然保留了人物的亲密关系等信息。(将抽象的人物关系,转化成数值空间关系)
但是,我这里有一个假设,假如一句话是一个向量(将这句话所有的词语向量求均值,得到均值向量),这个向量是否可以保留这句话的信息呢?比如电影评论,转化成数值向量之后,这个向量是否可以保留积极、消极的信息。本文将从这个方面去验证这个观点是否成立。本文通过Wordvec算法将评论句子转化成文本向量,然后通过转化之后的文本向量进行建模,采用C50 算法进行分类,通过模型验证,经过wordvec转化之后的评论文本的数值向量可以保留评论文本的情感极性信息。
目录
数据获取
现在很多专家认为数据是未来仅次于石油的资源,那么既然是这么优质的资源,肯定需要想办法去开采这个资源。这里介绍一个第三方小工具 火车头采集,其实就是一家公司将爬虫代码包装起来,然后将一些需要配置的参数露出来进行配置。
下面以采集豆瓣网 《西红柿首富》电影评论为例 简单介绍下使用方法:
第一步:网址获取
从网站评论的的网址规则可以看出,具有如下规则
1 每一页有20条评论
2 这些信息反映在链接的参数里面,并且以等差数列递增
https://movie.douban.com/subject/27605698/reviews?start=20
于是可以在火车头进行如下设置:
第二步: 字段获取
首先我们需要获取的字段信息有:用户名 、星级、评论日期、评论内容;需要在源码里面解析我们需要的内容,这里需要用到正则表达式,不过不用害怕,软件自己已经写好了。你只要设置参数就行。
例如下面:日期字段在下列代码中
class="main-meta">2018-07-27 16:52:30
你只要这样设置参数就可以class="main-meta">【参数】
第三步:保存到本地
第四步: 设置间隔时间,容易被发现
最后运行就可以了,运行结束后,会在本地生成下列文件
描述性数据分析
数据有了,下面来简单的看基本情况
总共采集2300条评论信息
> setwd('E:\\数据分析\\西红柿首富')
> library(ggplot2)
> xhs = read.csv("西红柿首富.csv",header=F,sep=",",stringsAsFactors=F)
> names(xhs)=c("names","sentm","time","conment")
> xhs=xhs[nchar(xhs$sentm)==2,]
> nrow(xhs)
[1] 2300
#电影西红柿首富评论情感分布差评占比14%
sent_cnt=table(xhs$sentm)
dt = data.frame(B =names(sent_cnt), A = as.numeric(sent_cnt),stringsAsFactors=F)
str(dt)
dt = dt[order(dt$A, decreasing = TRUE),]
myLabel = as.vector(dt$B)
myLabel = paste(myLabel, "(", round(dt$A / sum(dt$A) * 100, 2), "%)", sep = "")
p = ggplot(dt, aes(x = "", y = A, fill = B)) +
geom_bar(stat = "identity", width = 1) +
coord_polar(theta = "y") +
labs(x = "", y = "", title = "电影西红柿首富评论情感分布") +
theme(axis.ticks = element_blank()) +
theme(legend.title = element_blank(), legend.position = "top") +
scale_fill_discrete(breaks = dt$B, labels = myLabel) +
theme(axis.text.x = element_blank())
#geom_text(aes(y = A/2 + c(0, cumsum(A)[-length(A)]), x = sum(A)/20, label = myLabel), size = 5) ## 在图中加上百分比:x 调节标签到圆心的距离, y 调节标签的左右位置
p
好评的人都说了啥? 可以看出观众还是喜欢该(开心麻花)电影一如既往(夏洛特烦恼)的喜剧元素
library(wordcloud2)
tj_sent=xhs[xhs$sentm %in% c("推荐","力荐"),"conment"]
wordcloud2(seg_word_frq(tj_sent,100), size = 1, minRotation = -pi/6, maxRotation = -pi/6,
rotateRatio = 1)
差评的人都说了啥? 屌丝级别的脑洞打开,故事情节的庸俗
数据建模:
训练词语向量
> library(wordVectors)
> model = train_word2vec("yitian_split.txt", output="yitian_split.bin",
+ threads = 3, vectors = 100, window=12, force = T)
Starting training using file E:/数据分析/西红柿首富/yitian_split.txt
Vocab size: 3199
Words in train file: 303691
Filename ends with .bin, so reading in binary format
Reading a word2vec binary file of 3199 rows and 100 columns
|=================================================================================================| 100%
There were 50 or more warnings (use warnings() to see the first 50)
> vec = read.vectors("yitian_split.bin")
Filename ends with .bin, so reading in binary format
Reading a word2vec binary file of 3199 rows and 100 columns
|=================================================================================================| 100%
There were 50 or more warnings (use warnings() to see the first 50)
##评论句子向量化
new_date=data.frame(t(c(1:100)))
colnames(new_date)=paste("x",1:100,sep="")
new_date=new_date[-1,]
seg=worker()
for(i in 1:nrow(xhs)){
if(i%in% c(641,1585)){}else{
x=seg
y=x[x%in%rownames(model@.Data)]
rrd = apply(sapply(y, function(x) vec[[x]]),1,mean)
new_date_t=data.frame(t(rrd))
colnames(new_date_t)=paste("x",1:100,sep="")
new_date=rbind(new_date,new_date_t)
}
}
new_date=read.csv("new_date.csv")
head(new_date)
str(new_date)
new_date$y=as.character(new_date$y)
new_date=new_date[new_date$y%in%c("很差","较差","力荐","推荐"),]
new_date[new_date$y%in%c("很差","较差"),"y"]="消极"
new_date[new_date$y%in%c("力荐","推荐"),"y"]="积极"
new_date$y=as.factor(new_date$y)
#训练集测试集 28 分
l=sample(1:nrow(new_date), 0.8*nrow(new_date), replace = FALSE)
l_date=new_date[l,]
test_date=new_date[-l,]
#训练C50模型
library(C50)
str(l_date$y)
treeModel
plot(treeModel, subtree = 5)
summary(treeModel)
Evaluation on training data (1388 cases):
Decision Tree
----------------
Size Errors
32 178(12.8%)
(a) (b)
---- ----
1120 7 (a): class 积极
171 90 (b): class 消极
Attribute usage:
100.00%x33
51.80%x42
48.20%x6
48.13%x57
37.32%x43
13.11%x26
12.39%x97
11.38%x28
10.73%x100
10.09%x87
9.22%x3
5.98%x95
5.40%x49
4.97%x31
3.82%x17
3.82%x64
3.75%x72
3.46%x86
3.39%x71
3.31%x29
3.10%x20
2.95%x47
2.59%x73
2.45%x85
1.59%x89
1.44%x67
1.08%x37
0.86%x56
0.36%x93
Time: 0.4 secs
测试实验集数据
见证奇迹的时刻(正确率:79.2%)
table(predict(treeModel, test_date[,-101]),test_date[,101])
还行 很差 较差 力荐 推荐
还行 33 1 2 3 6
很差 3 25 9 8 4
较差 5 3 14 9 2
力荐 22 2 1 53 37
推荐 41 1 2 39 92
结论:经过wordvec转化的之后的评论文本向量,经过C50算法,可以很好进行分类鉴别,即其保留了文本的极性信息
领取专属 10元无门槛券
私享最新 技术干货