练习2 文本处理

R需要包:Rwordseg包、rJava包

需要知识:正则表达式、配置Java环境

 

通过爬虫某热门微博评论得到五万余条数据,对其进行文本挖掘和数据分析

爬虫使用Python,分析使用R。与他人合作所做,本人负责数据处理,故此处仅说明分析

练习来源于想在某条微博上找到某个人,仅知其手机型号和评论内容,需寻找其用户名,后续分析属于无聊产物

  • 数据收集

截至日前“微博搞笑排行榜”的一条关于“评论留下你想听的歌,看会不会有人私信给你唱”的微博已有三百五十余万条评论。通过Python编程针对此进行网页爬虫,根据评论时间截取2017年6月22日至25日四天时间获得50243条有效样本。

为匹配微博用户具体手机品牌,爬虫手机中国网站得到手机品牌库。评论中某些是想听某位歌手的任意歌曲,故爬虫百度音乐网站歌手大全获得5399位歌手。同时为根据不同需求得到歌曲不同曲库,称为小曲库与大曲库。小曲库是爬虫网易云音乐的一只歌单188首热门歌曲,大曲库是爬虫虾米音乐华语标签下1193只歌单共46914首歌曲。

1、微博评论

http://weibo.com/1713926427/Etq2WnSiR?filter=hot&root_comment_id=4070117551679469&type=comment#_rnd1498672693809

2、手机品牌

http://product.cnmo.com/manu.html

3、百度歌手

http://music.baidu.com/artist/

4、网易云歌单

http://music.163.com/#/playlist?id=625735202

5、虾米歌单

http://www.xiami.com/search/collect?spm=a1z1s.2943601.6856185.15.CZWfVA&key=%E5%8D%8E%E8%AF%AD

五个数据文件,分别名为微博weibo.csv、手机phone.csv、歌手artist.csv 、网易云music.summary.csv、虾米music.xiami.csv。

  • 数据预处理

对得到的百度音乐歌手数据进行唯一化处理,同时将网易云音乐歌单中歌曲名进行初步文本处理。对虾米音乐文件中标签(Tag)以及音乐名(MusicName)进行拆分,将标签分为多个词组,将音乐名拆分为歌曲名和歌手名。

考虑到用户回复其他人的非有效信息,对于微博评论数据根据用户ID进行唯一化处理,通过建立索引找出用户ID重复的无效值,得到删除重复值的数据。

# unique user ID
unique.uid <- duplicated(weibo1$uid)   
weibo <- weibo1[!unique.uid, ]
str(weibo)

最终得到16686个有效样本,其中具体的变量指标含义如下: 用户ID(uid)、评论文本(text)、手机类型(source)、评论时间(time)、性别(sex)、用户名(name)、用户地址(location)、用户简介(intro)、注册时间(data),用户名与简介未分析。

  • 数据分析

1. 注册时间

微博用户注册时间格式如:2017/06/25,我们需要提取其注册的年份,首先我们将其转化为2017-06-25这样R软件能识别的日期格式,然后提取前四位即2017,根据最终所得数据绘制出样本微博账号年注册量变化折线图。

# registered date
png(file = "weibo.picture3.png")
regi.date <- as.Date(weibo$date, format="%Y/%m/%d")   #不同电脑版本Excel时间格式不同需要调整
regi.date.y <- substr(regi.date,1,4) 
str(regi.date.y)
regi.date1 <- table(regi.date.y)
plot.regi <- plot(regi.date1,  type = "b", col="red", xlab = "年份", 
                  ylab = "注册量", main = "微博账号年注册量")
tmp <- as.vector(regi.date1)
text(plot.regi, tmp, labels=tmp, pos=3) # 添加值标签
dev.off()

 

2014、2015年注册账号评论的较多,其微博使用时长为2-3年,微博注册时间过早或者过晚评论量都有所下降。

2.  评论时间

comment.time1 <- weibo2$time
comment.time2 <- as.POSIXlt(comment.time1, format="%Y/%m/%d %H:%M")
comment.time  <- comment.time2[!is.na(comment.time2)]
hist(comment.time, breaks = 24)

3.  性别

评论此条微博账号中女性占了绝大一部分比例,高达74%

# sex
png(file = "weibo.picture1.png")
weibo.sex <- weibo$sex
weibo.sex <- table(weibo.sex)
lals <- paste(names(weibo.sex), round(weibo.sex/sum(weibo.sex)*100, 2), 
              "%", sep="")
pie(weibo.sex, col = c("deepskyblue", "#ff1493"),labels = lals)
dev.off()

  

4.  用户地区

微博用户地址格式是“省份 市名”,提取前面两个字符即得到微博用户所在省份,并计算各省样本微博用户人数,统计前10位地区微博使用量最多的地区,绘制其直方图

# address
png(file = "weibo.picture2.png")
weibo.address <- substr(weibo$location, 1, 2)
weibo.address.sort <- sort(table(weibo.address), decreasing = TRUE)
bar.weibo <- barplot(weibo.address.sort[1:10],xlab = "地区",
                     ylab = "人数",ylim=c(0,3000), 
                     col = "chocolate", main = "微博部分用户所在地")
tmp <- as.vector(weibo.address.sort[1:10])
text(bar.weibo, tmp, labels=tmp, pos=3) # 添加值标签
dev.off()

5.  手机类型

微博用户为显示手机型号的个性化,都对其手机品牌名称都进行了自定义命名,手机品牌名称并不是单一的品牌名,比如“某某某的iPhone 6s Plus”。需要利用手机词库进行匹配,通过爬虫得到现有市面上各种手机品牌的名称,将手机品牌整合为一个向量添加进词库。分别将每个人的手机按照手机品牌进行分词,然后将每个人手机品牌分词与手机品牌大全进行匹配,若观测值所有变量都不能进行匹配就作为未知品牌处理

# all phone type
all.phone <- read.csv(file="phone.csv", stringsAsFactors = FALSE)
all.phone1 <- all.phone[215:332, 2]   #仅部分需要
allphone <- c(all.phone1, "荣耀", "红米", "魅蓝", "HUAWEI", "IPad",
              "iPhone", "乐", "iPad", "OnePlus")     #加入部分品牌的子品牌或别称

 

# phone type
insertWords(allphone)   #词库添加
phone.type1 <- segmentCN(weibo$source)    #分词

# JAVA配置出现问题可用以下方法
# phone.exa <- enc2utf8(weibo$source) #转utf-8,有些格式它不支持
# phone.exa <- phone.exa[Encoding(phone.exa) != "unknown"]
# phone.type1 <- segmentCN(phone.exa)

# 筛选所需词汇
keep.word <- function(x, y, txt){
  y <- x[x %in% txt]
  y
}
phone.type2 <- c()    
phone.type2 <- lapply(phone.type1, keep.word, phone.type2, allphone)
phone.type <- unlist(phone.type2)   #列表转为向量
str(phone.type)
# 手机厂商分析
phone.type3 <- phone.type
for (i in 1:length(phone.type)) {
  if(phone.type[i] == "魅蓝")    phone.type3[i] <- "魅族"
  if(phone.type[i] == "HUAWEI")  phone.type3[i] <- "华为"
  if(phone.type[i] == "荣耀")    phone.type3[i] <- "华为"
  if(phone.type[i] == "红米")    phone.type3[i] <- "小米"
  if(phone.type[i] == "乐")      phone.type3[i] <- "乐视"
  if(phone.type[i] == "OnePlus") phone.type3[i] <- "一加"
  if(phone.type[i] == "苹果")    phone.type3[i] <- "iPhone"
}
phone.type4 <- sort(table(phone.type3),decreasing = T)
phone.num1 <- sum(phone.type4 > 300)
phone.num2 <- sum(phone.type4 > 0)
phone.else <-sum(phone.type4[phone.num1:phone.num2])
phone.na <- length(phone.type2)-sum(phone.type4)
phone.type5 <- c(phone.type4[1:phone.num1], phone.else,phone.na)
phone.type5.name <- c(names(phone.type5)[1:(length(names(phone.type5))-2)],"其他","未知类型")

  

# 画图
png(file = "weibo.picture4.png")
lals <- paste(phone.type5.name, "", 
              round(phone.type5/sum(phone.type5), 2)*100, "%", sep="")
pie(phone.type5,labels = lals, main = "手机类型占比",
    col = c("lightskyblue","lawngreen","lightcoral", "yellow","red", "cyan", "chocolate","magenta", "pink"))
dev.off()

pdf(file = "weibo.picture5.pdf")
bar.phone <- barplot(phone.type5,col = "chocolate", xlab = "手机类型", 
                     ylab = "人数", main = "手机类型使用情况",
                     ylim = c(0,5500),names.arg=phone.type5.name)
tmp <- as.vector(phone.type5)
text(bar.phone, tmp, labels=tmp, pos=3) # 添加值标签
dev.off()

  

6.  评论文本

微博用户在微博下的评论较为杂乱,没有固定的评论格式,有的介绍自己喜欢的歌手,有的写出自己喜欢的歌曲,部分回复消息以及广告信息。首先分析微博用户评论中提及的歌手,然后分析评论中提及的歌曲。

对于评论数据的预处理,首先要剔除大量回复的数据,然后利用正则表达式删除“<>”中不需要的词

weibo.index <- substr(weibo$text, 1, 2)
weibo.text1  <- weibo$text[which(weibo.index != "回复")]
weibo.text2 <- gsub("<.*>", "", weibo.text1)   # 删除<>中不需要词句

(1)歌手匹配

通过爬虫找到歌手名单,建立相应的歌手词库,利用歌手全部名单匹配各条评论里所提及的歌手,最后统计各个歌手被提到的次数

# singer list
singer1 <- read.csv("artist.csv", header=FALSE, stringsAsFactors = FALSE)
singer <- singer1[201:nrow(singer1), 2]

# commment singer
insertWords(singer)
weibo.singer1 <- segmentCN(weibo.text2) 
weibo.singer2 <- c()
weibo.singer2 <- lapply(weibo.singer1, keep.word,  weibo.singer2, singer)
weibo.singer <- unlist(weibo.singer2)
weibo.singer3 <- sort(table(weibo.singer), decreasing = TRUE)

 

歌手

薛之谦

陈奕迅

五月天

周杰伦

林宥嘉

林俊杰

太阳

陈粒

鹿晗

张学友

杨千嬅

方圆

天空之城

王力宏

王菲

评论数

202

131

96

88

68

60

49

42

30

28

26

25

21

21

20


当前最热门的歌手薛之谦被评论的次数最多,其次是陈奕迅、五月天、和周杰伦等大众熟知的歌手。但是其中出现了太阳、方圆两位歌手,这主要是由于文本分词时有一定的缺陷,有些语句中出现了太阳和方圆两个词,但指的并非这两位歌手,而在统计词频时被统计进去。

(2) 歌曲匹配

(i)对评论里歌曲进行挖掘时方法一是将书名号里的内容摘选出来,得到《彩虹》、《心酸》、《独家记忆》等639首歌曲。

# comment music
weibo.text3 <- grep("《.*》", weibo.text2)
weibo.text4 <- gsub(".*《", "", weibo.text2[weibo.text3])
weibo.text5 <- gsub("》.*", "", weibo.text4)
weibo.text5[1:20]

(ii)爬虫网易云一只歌单188首热门歌曲,建立相应的小曲库,将其导入进词库中,由此进行分词,将分词后的结果与上述曲库进行匹配摘选出有效信息。

# part music matching
music.part1 <- read.csv("music.summary.csv", header=FALSE,   stringsAsFactors = FALSE)
music.part2 <- as.vector(as.matrix(music.part1))
music.part <- gsub("(.*)", "", music.part2)

insertWords(music.part)
weibo.text2[1:10]
weibo.music.part1 <- segmentCN(weibo.text2) 
weibo.music.part2 <- c()
weibo.music.part2 <- lapply(weibo.music.part1, keep.word,  weibo.music.part2, music.part)
weibo.music.part <- unlist(weibo.music.part2)
weibo.music.part.sort <- sort(table(weibo.music.part), decreasing = TRUE)
as.data.frame(weibo.music.part.sort[1:50])  
 

序号

歌曲名

点歌数

序号

歌曲名

点歌数

序号

歌曲名

点歌数

1

可乐

211

11

说散就散

100

21

好久不见

61

2

安和桥

198

12

晚安

99

22

我们

58

3

有没有

195

13

理想三旬

95

23

小半

58

4

成全

154

14

那就这样吧

82

24

男孩

50

5

成都

148

15

突然好想你

81

25

浪费

48

6

暧昧

147

16

岁月神偷

73

26

春风十里

45

7

小幸运

140

17

我想

72

27

走马

42

8

晴天

120

18

白山茶

68

28

春雨里洗过的太阳

41

9

童话镇

120

19

睡不着

63

29

彩虹

39

10

追光者

113

20

刚好遇见你

61

30

奇妙能力歌

39

(iii) 爬虫虾米音乐华语标签下1193只歌单得到共46914首歌曲,建立相应的歌曲词库,将其导入进词汇库,利用各个评论分词后结果与曲库进行匹配,得到评论中的歌曲名。
# xiami music
music.xiami1 <- read.csv("music.xiami.csv", header=TRUE, stringsAsFactors = FALSE)
music.xiami2 <- music.xiami1[ , c(1, 3, 4)])
music_name1 <- music.xiami2$MusicName
music_name2 <- sub("-.*", "", music_name1)
music_name <- gsub("\\(.*\\)", "", music_name2)

music_singer <- gsub(".*-", "", music_name1)

music_tag1 <- music.xiami2$Tag
music_tag2 <- sub("虾.*", "", music_tag1)
music_tag3 <- strsplit(music_tag2, "\\s")

# duplicated(music_name)[1:50]
# music_name3[which(duplicated(music_name))[1:6]]
# music_tag3[which(music_name == "一千零一个愿望")]
# sort(table(unlist(music_tag[which(music_name == "十年")])), decreasing = TRUE)

  

# all music matching
insertWords(music_name)
weibo.music1 <- segmentCN(weibo.text2) 

weibo.music2 <- c()
weibo.music2 <- lapply(weibo.music1, keep.word,  weibo.music2, music_name)
weibo.music <- unlist(weibo.music2)

# sort(table(weibo.music), decreasing = TRUE)[1:30]
# weibo.music2[10:20]

  

用户ID

评论

歌曲

标签

歌单

3194198775

杨千嬅的炼金术

炼金术

粤语 流行 安静 伤感

深情粤语

6118833189

我怀念的_. 萧敬腾

我怀念的

青春 时光 经典

那些感动过我们的华语声音

5519079950

想听《你爱上的我》,有人会么。

你爱上的我

爱情 抒情 流行 情歌 温暖

她爱他,后知后觉

5502421670

梁咏琪的短发<span class="url-icon">……

短发

女声 怀旧 经典 80后

那些和回忆有关的美丽声音

5677925408

还是想听海阔天空,beyond的,发了好几遍了,却始终没人唱给我听……

海阔天空

经典 怀旧 老歌 回忆 精选 追忆 励志

经典华语怀旧老歌一百首

posted @ 2017-07-24 21:04  坴戋  阅读(363)  评论(0编辑  收藏  举报