r语言中v1=c(v1i),R语言入门级实例——用igragh包分析社群

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

引入——

本文的主要目的是初步实现R的igraph包的基础功能,包括绘制关系网络图(social relationship)、利用算法进行社群发现(community detecting)。对于R语言零基础的同学非常友好。以下R代码中如有含义不清的,建议尝试先在R编辑器中输入?xxx()进行查询(xxx是函数或语句名)。此外,stackflow论坛也帮博主小白看懂了不少报错信息。

主要参考资料为《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表进行的.如下:

20200302161221341dr7dwwltxqgs12a_12.png

20200302161221341dr7dwwltxqgs12a_0.png

20200302161221341dr7dwwltxqgs12a_11.png

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

20200302161221341dr7dwwltxqgs12a_14.png

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

20200302161221341dr7dwwltxqgs12a_7.png

2.数据集导入

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

20200302161221341dr7dwwltxqgs12a_9.png

3.建立关系网络与绘图

步骤描述:

引用igraph包,建立空关系网络并设置点数据→

为点数据添加商品号以及商品分类属性→

添加线数据→

plot出来发现是非连通图(存在孤立的点的图),有两个未连通的点(点43,点44),只用手动对点的个数减2即可

将点的个数修改后,重新跑前面的所有代码即可

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

#建立空关系网络并设置点数据

library(igraph)

gdata

num

gdata

category

{if(i!=136&& i!=140)

{

category

item

}

}

V(gdata)$category

V(gdata)$item

for(i in 1:nrow(cart))

{ item.i

{if(cart[i,j]==1)

{

item.i

}

}#建立向量内不同商品间的关联联系

item.i.num

{from

to

}if(i>1)

{

edges

}else{

edges

}

}

edges0

labels

ids

names(ids)

newfrom

edges

gdata

E(gdata)$weight

gdata

dev.off()#关闭图形设备

plot(gdata,edge.width=E(gdata)$weight,main="gdata", edge.label=E(gdata)$weight)#发现是非连通图,有两个未连通的点(点43,点44),只用手动对点的个数减2即可#将点的个数修改后,重新跑前面的所有代码

画出来的效果如下:

20200302161221341dr7dwwltxqgs12a_3.png

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相关

总之,在这里这种方法适用于购物车商品分析。

另外,需要注意:

①社群发现必须基于连通图(即,所有点上都在线上,没有孤立的点);

②此处的社群个数对应之后画子图的分组个数。

步骤描述:

对不同商品类别的点配置不同颜色→

建立绘图分组member.list,作为plot函数mark.groups参数的列表对象→

画图并手动添加图例→可添加点的标签属性vertex.label,呈现原有编号

这部分代码如下:

##社群发现并绘制关系图(自旋玻璃法)

member

V(gdata)$member

member.num

#对不同商品类别的点配置不同颜色

mem.col

V(gdata)$color

member.list

{

member.list

}#svg(filename=paste(root, "demol.svg",sep=""), width = 14, height = 14)#画图并手动添加图例

legend0

plot(gdata, vertex.label=V(gdata)$item, vertex.size=10, layout=layout.fruchterman.reingold, vertex.color=V(gdata)$color, edge.width=scale(E(gdata)$weight, center=F)+1, mark.groups=member.list)

#第二个plot加了label属性

legend("topleft",legend=legend0, pch=16, col=mem.col, bty="n", cex=1)

画出图如下(右图为加了lable标签后的效果,所有点恢复了真实编号,而不是左图中临时的连续编号):

20200302161221341dr7dwwltxqgs12a_13.png

20200302161221341dr7dwwltxqgs12a_5.png

OK! 看上去还不错。

现在我们得到的图里,每个点的颜色对应左侧图例中的不同商品分类(蛋奶制品、烘焙类、冷冻品、零食等等),点与点之间的连线代表两个曾在同一购物篮子(即订单信息order)中出现过。现在利用算法已经发现了五个可能存在的社群,即,在这个图中关系更密切的点的集合,由浅色“冲积扇”形状色块标出。右图中,点的编号就是原mini数据库中的商品号码。现在就可以研究能不能得出有趣的结论了!

对照如下图的数据库,上方右图中编号81,80,31,119的商品位于一个社群中。也许数据量再大些能说明热爱有机蔬果的顾客也偏好矿泉水?

20200302161221341dr7dwwltxqgs12a_2.png

5.绘制子图

为了单独研究形成的各个社群,还可以把关系图拆成子图分别绘制。

有两种方法画子图:

A.设置par,用循环一次性画出;

B.依次画每个图,放大后更清晰

#绘制不同社群内的关系图#svg(filename=paste(root, "demol.svg",sep=""), width = 14, height = 14)#par(mfcol=c(3,2))

for(i in 1:length(table(member$membership)))

{

tmp.g

member.list

tmp.category

{

member.list

}

plot(tmp.g, vertex.size=10,layout=layout.fruchterman.reingold, edge.width=scale(E(tmp.g)$weight,center=F)+1,mark.groups=member.list,vertex.label=V(tmp.g)$item)#手动添加图例

#legend("topleft",legend= ,pch=16,col=mem.col,bty="n",cex=1)

}

子图如下:

20200302161221341dr7dwwltxqgs12a_8.png              

20200302161221341dr7dwwltxqgs12a_1.png              

20200302161221341dr7dwwltxqgs12a_4.png

20200302161221341dr7dwwltxqgs12a_6.png                        

20200302161221341dr7dwwltxqgs12a_10.png

------------------------------------------------分割线----------------------------------------------------

6.完整代码

ls()

rm(list=ls())#初步读取数据

root="C:/Users/asus/Desktop/"data

colname1

colname1[1]

#install.packages('reshape')

library('reshape')

data

cart=as.matrix(cast(data,order_id~p_id,value="value",fill=0))

cart[,-1]=1,1,0)#好像有点多余,因为此数据集中每个购物篮子中的某件商品只被记了一次

#注:这是最开始的数据准备部分,限于篇幅,后面的部分就是前文各小节代码的拼凑综合,不再重复复制粘贴。

参考资料:《R语言与网站分析》[李明著][机械工业出版社][2014.04] 的9.3节《关系网络分析》。

代码部分引用自原书作者,增加了注释,结合R语言语法的变化也有改动。

小注:写作本文源于博主小白去年一段做RA的经历,当时与队友们共同学习社会网络分析(Social Network Analysis,SNA),主要参考书是上文提及的《R语言与网站分析》9.3节。博主小白与搭档负责实现书上的两个实例,但由于教材没有提供数据来源、R语言语法近几年的变化,中间费了一番波折,故写作本文,主要内容为博主负责的“购物篮子商品相关性分析”实例。如有疏漏,还望指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值