分享

R语言入门级实例

 追着天使拔毛 2020-08-25

R语言入门级实例——用igragh包分析社群

珍云恒星 2020-03-02 原文

R语言入门级实例——用igragh包分析社群

引入——

  本文的主要目的是初步实现R的igraph包的基础功能,包括绘制关系网络图(social relationship)、利用算法进行社群发现(community detecting)。对于R语言零基础的同学非常友好。以下R代码中如有含义不清的,建议尝试先在R编辑器中输入?xxx()进行查询(xxx是函数或语句名)。此外,StackOverflow论坛也帮博主小白看懂了不少报错信息。
  主要参考资料为《R语言与网站分析》[李明著][机械工业出版社][2014.04] 的9.3节《关系网络分析》。

0.背景

  现已获得超市中商品的名称、分类以及大量顾客购物篮子中的商品信息,任务是分析哪些商品存在相关性,经常被放在一起购买。题外话,这种分析的一例经典应用就是沃尔玛超市的“啤酒与尿布”,感兴趣者可自行搜索或参见Jocelyn_燕的一篇博客.

1.原始数据及初步处理

  数据来源是Kaggle竞赛的数据库instacart-market-basket-analysis.下载压缩文件之后,将有用的数据合并到一个Excel文件中,此处需要order_product,order,products,departments的数据.注意,这个文件极大,order_product_prior这个spread sheet里的数据在Excel里已经无法完全显示,博主就截取了前500条信息,形成了mini数据集,以下对数据集的操作都是针对这个mini表进行的.如下:

  为了达到参考书上的数据形式,需要先整理这个Excel,形成如下图只有四列数据的形式.这里博主不太熟悉R的操作,就用Python的循环处理了,代码可附在文章最后.

  这是当初处理数据集的一些文件,由于不会用R完成所有命令,显得很笨拙hhh.

2.数据集导入

  导入的数据集包含四列,原商品编号过大,不便于处理,p_id、d_id分别是商品、商品分类的新编号,如下图:(这些也是用Python代劳的)

3.建立关系网络与绘图

步骤描述:

引用igraph包,建立空关系网络并设置点数据→
为点数据添加商品号以及商品分类属性→
添加线数据→
plot出来发现是非连通图(存在孤立的点的图),有两个未连通的点(点43,点44),只用手动对点的个数减2即可
将点的个数修改后,重新跑前面的所有代码即可

这部分代码如下:(完整代码见文末)

  1. #建立空关系网络并设置点数据
  2. library(igraph)
  3. gdata<-graph.empty(directed=F)
  4. #num<-ncol(cart)
  5. num<-ncol(cart)-2 #修改点的个数
  6. gdata<-add.vertices(gdata,num)
  7.  
  8. #为点数据添加商品号以及商品分类属性
  9. category<-c();item<-c()
  10. for(i in colnames(cart))
  11. {
  12. if(i!=136&& i!=140)
  13. {
  14. category<-c(category,data$d_id[which(data$p_id==i)[1]] )
  15. item<-c(item,data$p_id[which(data$p_id==i)[1]] )
  16. }
  17. }
  18. V(gdata)$category<-category
  19. V(gdata)$item<-item
  20.  
  21. #添加线数据
  22. #依次遍历每个订单,读取每个订单内的商品ID,并存放于向量item.i
  23. for(i in 1:nrow(cart))
  24. { item.i<-c()
  25. for(j in 1:ncol(cart))
  26. {
  27. if(cart[i,j]==1)
  28. {
  29. item.i<-cbind(item.i,colnames(cart)[j])
  30. }
  31. }
  32. #建立向量内不同商品间的关联联系
  33. item.i.num<-length(item.i)
  34. from<-c();to<-c()
  35. for(m in 1:(item.i.num-1))
  36. {
  37. from<-c(from,item.i[-c((item.i.num-m+1):item.i.num)])
  38. to<-c(to,item.i[-c(1:m)])
  39. }
  40. if(i>1)
  41. {
  42. edges<-rbind(edges,matrix(c(from,to),nc=2))
  43. }
  44. else
  45. {
  46. edges<-matrix(data=c(from,to),nc=2)
  47. }
  48. }
  49. edges0<-edges
  50. labels<-union(unique(edges[,1]), unique(edges[,2]))
  51. ids<-1: length(labels)#对点的编号重新编码,因为在igraph中边信息的ids必须连续
  52. names(ids)<-labels
  53. newfrom<-as.character(edges[,1]);newto<-as.character(edges[,2])
  54. edges<-matrix (c(ids[newfrom],ids[newto]), nc=2)
  55.  
  56. #添加线信息并设置线权重
  57. gdata<-add.edges(gdata,t(edges[-1,]))#t()是矩阵转置函数
  58. E(gdata)$weight<-count.multiple(gdata)
  59. gdata<-simplify(gdata, remove.multiple=TRUE, remove.loops = TRUE, edge.attr.comb = 'mean')
  60. #最后一个参数一定是edge.attr.comb,不是edges.attr.comb
  61. dev.off()#关闭图形设备
  62. plot(gdata,edge.width=E(gdata)$weight,main="gdata", edge.label=E(gdata)$weight)
  63.  
  64. #发现是非连通图,有两个未连通的点(点43,点44),只用手动对点的个数减2即可
  65. #将点的个数修改后,重新跑前面的所有代码

  画出来的效果如下:

4.社群发现与绘图

  此处采用自旋玻璃法(spinglass community detecting)进行社群发现。其他社群发现的方法包括中心势、标签传播、随机游走等,这几种方法在算法效率与模拟方式上其实存在不同点。但限于篇幅,此处不再介绍。对这几种方法感兴趣者可自行搜索或参考以下论文(引用格式不够规范,但应该能搜索到):

[1]J¨org Reichardt & Stefan Bornholdt (2008) Statistical Mechanics of Community Detection <=spinglass相关

[2]M. Girvan & M. E. J. Newman (2001) Community structure in social and biological networks <=中心势betweeness相关

[3]Jierui Xie & Boleslaw K. Szymanski (2013) LabelRank: A Stabilized Label Propagation Algorithm for Community Detection in Networks <=标签传播labelrank相关

[4]Pascal Pons and Matthieu Latapy (2006) Computing Communities in Large Networks Using Random Walks <=随机游走randomwalk相关

总之,在这里spinglass方法适用于购物车商品分析。
  另外,需要注意:
  ①社群发现必须基于连通图(即,所有点上都在线上,没有孤立的点);
  ②此处的社群个数对应之后画子图的分组个数。

步骤描述:

对不同商品类别的点配置不同颜色→
建立绘图分组member.list,作为plot函数mark.groups参数的列表对象→
画图并手动添加图例→
可添加点的标签属性vertex.label,呈现原有编号

这部分代码如下:

  1. ##社群发现并绘制关系图(自旋玻璃法)
  2. member<-spinglass.community(gdata, weights= E(gdata)$weight)
  3. V(gdata)$member<-member$membership
  4. member.num<-length(table(V(gdata)$member)); member.num #注意:此处的社群个数对应之后的绘图分组
  5.  
  6. #对不同商品类别的点配置不同颜色
  7. mem.col<-rainbow(length(unique(V(gdata)$category)),alpha=0.5)#注意设置alpha值调节对比度
  8. V(gdata)$color<-mem.col[V(gdata)$category]

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多