使用 R 语言挖掘 QQ 群聊天记录
1、获取数据
从 QQ 消息管理器中导出消息记录,保存的文本类型选择 txt 文件。这里获取的是某群从 2016-04-18 到 2016-05-07 期间的聊天记录,记录样本如下所示。
消息记录(此消息记录为文本格式,不支持重新导入)================================================================ 消息分组:我的QQ群 ================================================================ 消息对象:QQGroup ================================================================2016-04-18 20:04:00 谁来弄死我(1122334455) ip 主机名2016-04-18 20:04:20 我来弄死谁(66554432) 这个我配了2016-04-18 20:04:29 我来弄死谁(66554432) hadoop集群是正常的2016-04-18 20:05:07 谁来弄死我(1122334455) 自己找吧2016-04-18 20:05:20 我来弄死谁(66554432) spark集群运行作业的时候就抱这错了2016-04-18 20:05:29 我来弄死谁(66554432) 我都找了好几天了
2、数据预处理
打开 R 软件,先通过 File—>Change dir 切换到聊天文件所在目录。
引入包:
library(stringr) library(plyr) library(lubridate) library(ggplot2) library(reshape2) library(igraph)
没有的包要通过命令 install.packages(”扩展包名”) 安装。
读取聊天记录文件到内存:
qqsrcdata<-readLines("QQGroup.txt",encoding="UTF-8")
这里我们不关心聊天内容,只看时间和发言人,所以,我们把类似 “2016-04-18 20:04:20 我来弄死谁(66554432)” 这样的内容提取出来。这里要用到正则表达式,对此不懂的可参考 正则表达式30分钟入门教程。对 R 语言的 grep、sub、gregexpr 等字符串处理函数不熟的,网上搜一下,资料多的是。
srcdata<-qqsrcdata[grep("^\\d{4}-\\d{2}-\\d{2} \\d+:\\d{2}:\\d{2} .+$",qqsrcdata)]
看看 srcdata 内容,就已经全是发言时间和发言人信息了,没有其它闲杂数据。
然后再从 srcdata 中提取发言时间和发言人信息,分别存到列表 data 的 time 和 id 中。对发言人信息的提取很简单:
data={} # 创建一个空的 list data$id<-sub("\\d{4}-\\d{2}-\\d{2} \\d+:\\d{2}:\\d{2} ", "", srcdata)
对发言时间的提取要稍麻烦些,因为时间字符串的长度不一样,有些是 18 位,如 “2016-04-18 7:36:32”,有些是 19 位,如 “2016-04-18 19:24:01”,所以,在提取时间时,需先用 gregexpr 确定时间字符串的起始和结束位置,然后再用 substring 提取出相应的时间,注意 substring 和 sub 是不同的函数。
getcontent <- function(s,g){substring(s,g,g+attr(g,'match.length')-1) # 读取 s 中的数据 }gg<-gregexpr("\\d{4}-\\d{2}-\\d{2} \\d+:\\d{2}:\\d{2}",srcdata,perl=TRUE) for(j in 1:length(gg)) { data$time[j]<-getcontent(srcdata[j],gg[[j]]) }
现在时间和发言人信息都读到 data 的 time 和 id 中了,可以确认下提取内容:data、data$id、data$time。
还没完,时间还是字符串,还需要继续处理:
# 数据整理 # 将字符串中的日期和时间划分为不同变量 temp1 <- str_split(data$time,' ') result1 <- ldply(temp1,.fun=NULL) names(result1) <- c('date','clock')#分离年月日 temp2 <- str_split(result1$date,'-') result2 <- ldply(temp2,.fun=NULL) names(result2) <- c('year','month','day')# 分离小时分钟 temp3 <- str_split(result1$clock,':') result3 <- ldply(temp3,.fun=NULL) names(result3) <- c('hour','minutes','second')# 合并数据 newdata <- cbind(data,result1,result2,result3)# 转换日期为时间格式 newdata$date <- ymd(newdata$date)# 提取星期数据 newdata$wday <- wday(newdata$date)# 转换数据格式 newdata$month <- ordered(as.numeric(newdata$month) ) newdata$year <- ordered(newdata$year) newdata$day <- ordered(as.numeric(newdata$day)) newdata$hour <- ordered(as.numeric(newdata$hour)) newdata$wday <- ordered(newdata$wday)
至此,数据预处理完成,时间和发言人数据都已合适地存到 newdata 中,可以开始任性地分析了~
3、数据分析
- 一星期中每天合计的聊天记录次数,可以看到该 QQ 群的聊天兴致随星期的分布。
qplot(wday,data=newdata,geom='bar')
周三是工作日,还这么活跃,周六话最多,周日估计出去玩了,周一专心上班。
- 聊天兴致在一天中的分布。
qplot(hour,data=newdata,geom='bar')
这群一天中聊得最嗨的是上午 10 点和下午 17 点,形成两个高峰。
- 前十大发言最多用户
user <- as.data.frame(table(newdata$id)) # 用 table 统计频数 user <- user[order(user$Freq,decreasing=T),] user[1:10,] # 显示前十大发言人的 ID 和 发言次数 topuser <- user[1:10,]$Var1 # 存前十大发言人的 ID
- 根据活跃天数统计前十大活跃用户
# 活跃天数计算 # 将数据展开为宽表,每一行为用户,每一列为日期,对应数值为发言次数 flat.day <- dcast(newdata,id~date,length,value.var='date') flat.mat <- as.matrix(flat.day[-1]) #转为矩阵 # 转为0-1值,以观察是否活跃 flat.mat <- ifelse(flat.mat>0,1,0) # 根据上线天数求和 topday <- data.frame(flat.day[,1],apply(flat.mat,1,sum)) names(topday) <- c('id','days') topday <- topday[order(topday$days,decreasing=T),] # 获得前十大活跃用户 topday[1:10,]
- 寻找聊天峰值日
# 观察每天的发言次数 # online.day为每天的发言次数 online.day <- sapply(flat.day[,-1],sum) # -1 表示去除第一列,第一列是 ID tempdf <- data.frame(time=ymd(names(online.day)),online.day ) qplot(x=time,y=online.day ,ymin=0,ymax=online.day ,data=tempdf,geom='linerange')# 观察到有少数峰值日,看超过200次发言以上是哪几天 names(which(online.day>200))
- 每天活跃人数统计
#根据flat.day数据观察每天活跃用户变化 # numday为每天发言人数 numday <- apply(flat.mat,2,sum) tempdf <- data.frame(time=ymd(names(numday)),numday) qplot(x=time,y=numday,ymin=0,ymax=numday,data=tempdf,geom='linerange')
- 十强选手的日内情况
# 再观察十强选手的日内情况 flat.hour <- dcast(newdata,id~hour,length,value.var='hour',subset=.(id %in% topuser)) # 平行坐标图 hour.melt <- melt(flat.hour) p <- ggplot(data=hour.melt,aes(x=variable,y=value)) p + geom_line(aes(group=id,color=id))+theme_bw()+theme(legend.position = "none")
- 连续对话的次数,以三十分钟为间隔
# 连续对话的次数,以三十分钟为间隔 newdata$realtime <- strptime(newdata$time,'%Y-%m-%d %H:%M') # 时间排序有问题,按时间重排数据 newdata2 <- newdata[order(newdata$realtime),] # 将数据按讨论来分组 group <- rep(1,dim(newdata2)[1]) for (i in 2:dim(newdata2)[1]) {d <- as.numeric(difftime(newdata2$realtime[i],newdata2$realtime[i-1],units='mins'))if ( d < 30) {group[i] <- group[i-1]} else {group[i] <- group[i-1]+1} } barplot(table(group))
- 画社交网络图
# 得到 93 多组对话 newdata2$group <- group# igraph进行十强之间的网络分析 # 建立关系矩阵,如果两个用户同时在一次群讨论中出现,则计数+1 newdata3 <- dcast(newdata2, id~group, sum,value.var='group',subset=.(id %in% user[1:10,]$Var1))# newdata4 <- ifelse(newdata3[,-1] > 0, 1, 0) rownames(newdata4) <- newdata3[,1] relmatrix <- newdata4 %*% t(newdata4) # 很容易看出哪两个人聊得最多 deldiag <- relmatrix-diag(diag(relmatrix)) which(deldiag==max(deldiag),arr.ind=T)# 根据关系矩阵画社交网络画 g <- graph.adjacency(deldiag,weighted=T,mode='undirected') g <-simplify(g) V(g)$label<-rownames(relmatrix) V(g)$degree<- degree(g) layout1 <- layout.fruchterman.reingold(g) #egam <- 10*E(g)$weight/max(E(g)$weight) egam <- (log(E(g)$weight)+1) / max(log(E(g)$weight)+1) #V(g)$label.cex <- V(g)$degree / max(V(g)$degree)+ .2 V(g)$label.color <- rgb(0, 0, .2, .8) V(g)$frame.color <- NA E(g)$width <- egam E(g)$color <- rgb(0, 0, 1, egam) plot(g, layout=layout1)
- 找到配对
#找到配对 pairlist=data.frame(pair=1:length(attributes(deldiag)$dimnames[[1]])) rownames(pairlist)<-attributes(deldiag)$dimnames[[1]]for(i in (1:length(deldiag[1,]))) { pairlist[i,1]<-attributes(which(deldiag[i,]==max(deldiag[i,]),arr.ind=T))$names[1] } pairlistpairmatrix=data.frame(pairA=1:length(attributes(deldiag)$dimnames[[1]]),pairB=1:length(attributes(deldiag)$dimnames[[1]])) pairmatrix=data.frame(pair=1:length(attributes(deldiag)$dimnames[[1]]))for(i in (1:dim(deldiag)[1])) { deldiag[i,] <- ifelse(deldiag[i,] == max(deldiag[i,]), 1, 0) } deldiag
参考资料:
[1] 正则表达式30分钟入门教程
[2] 来玩玩QQ群的数据
转载于:https://www.cnblogs.com/NaughtyBaby/p/5497714.html
使用 R 语言挖掘 QQ 群聊天记录相关推荐
- 【Python】QQ群聊天记录提取
[Python]QQ群聊天记录提取 没想到我的第一篇CSDN竟然是格式化QQ群聊天记录,反正就是要分析一些东西,导出的QQ群聊记录就很不方便,所以进行一下标准化处理,处理好是下面这样的. 下面就直接贴 ...
- Nonebot QQ机器人插件九:qq群聊天记录词云图
QQ机器人插件九:qq群聊天记录词云图 1. 将实时聊天记录保存到数据库 安装数据库可自行到网上查找,本文仅使用mysql数据库为例.linux下mysql数据库安装可参考(59条消息) Linux安 ...
- Python uiautomation使用---自动获取QQ群聊天记录
使用uiautomation获取qq群聊天记录,后续可以拓展到消息自动回复.本章只简单介绍自动获取聊天记录,代码如下: import uiautomation as auto from time im ...
- 巧用R语言挖掘谁是全网最受欢迎和最高产武侠作者
我虽然沉默,但没人敢小看我,这是一种来自武侠的气概,我喜欢看各种武侠小说,今天我巧用R语言挖掘谁是全网最受欢迎和最高产武侠作者. 首先收集全网的武侠小说,按作者整理.然后调用R语言的excel程辑包: ...
- matlab 画qq图,科学网—[转载]R语言绘制QQ图 - 刘朋的博文
R语言绘制QQ图 实例1: #############加载数据 data R R=apply(R,2,as.numeric) #R语言将字符串矩阵转化为数值型矩阵,apply()函数里面的第2个值,如 ...
- R语言绘制QQ图实战(qqplot函数、qqnorm函数、qqline函数)
R语言绘制QQ图实战(qqplot函数.qqnorm函数.qqline函数) 目录 R语言绘制QQ图实战(qqplot函数.qqnorm函数.qqline函数)
- 让QQ群聊天记录自动保存到群空间中(转)
让QQ群聊天记录自动保存到群空间中(转) 笔者经常在不同的电脑登录QQ,所以经常出现群消息丢失的烦恼.现在可以把聊天记录保存到群空间里,就不麻烦了. 笔者加入了多个作者.编辑交流QQ群,在QQ群里共同 ...
- 2018年QQ群聊天记录分析及可视化——时间线
前言 这个小demo是为了练手,把2018年我和我五个好朋友的群聊天记录进行分析挖掘,以及可视化. python3.6 pandas numpy pyecharts 预处理: 首先从QQ消息管理器里导 ...
- R语言之离群点检验(part3)--利用聚类检测离群点
学习笔记 参考文献:<R语言与数据挖掘> PS:本篇Blog以用R语言应用为主,原理部分请移步<多元统计分析>学习笔记之聚类分析 利用聚类分析检测离群点 聚类检测原理 有一种检 ...
最新文章
- python lxml读写xml
- Java IO流之字符缓冲流
- 使用UIWebView载入本地或远程server上的网页
- dll加载问题的解决方法
- python input函数无法输入字符串_python input输入函数
- ORA-3136 - ORA-4030
- 高并发模拟( 测试 )
- Struts1的实现原理
- Javascript特效:利用给节点增加参数或者闭包实现百度首页换肤
- 过水滑环的结构和工作原理
- python解二阶微分方程组_用Python求解一阶和二阶微分方程组
- IP-Guard清除记录
- 【读书笔记】掌控习惯_詹姆斯克里尔
- 对接钉钉API语音功能相关文档
- 55-经典问题分析四
- matlab—绘制给定数据的概率密度曲线+实现图像局部放大效果
- vue使用axios配置多域名
- 2021年安全员-A证最新解析及安全员-A证试题及解析
- Google Earth Engine(GEE)——
- NKOI 1349 工作安排
热门文章
- android windows 共享文件,Android上的Windows共享-文件,文件夹和网络分区
- QT(C++)游戏之坦克大战(一)
- 两条平行线相交于一点
- Redis基础_模拟使用redis是如何缓解数据库的压力
- SqlServer 索引及优化
- Android ble连接过程,Android BLE的一些基础知识及相关操作流程 - 全文
- Grid 与 Dock
- 云呐|林业固定资产包括哪些内容(林业资产属于固定资产吗)
- html entities to unicode text,python中HTML Entities处理及print特殊字符
- 十二个“一”与山海经