在图论中,集聚系数(也称群聚系数、集群系数)是用来描述一个图中的顶点之间结集成团的程度的系数。具体来说,是一个点的邻接点之间相互连接的程度。例如生活社交网络中,你的朋友之间相互认识的程度。有证据表明,在各类反映真实世界的网络结构,特别是社交网络结构中,各个结点之间倾向于形成密度相对较高的网群。也就是说,相对于在两个节点之间随机连接而得到的网络,真实世界网络的集聚系数更高。
集聚系数分为整体与局部两种。整体集聚系数可以给出一个图中整体的集聚程度的评估,而局部集聚系数则可以测量图中每一个结点附近的集聚程度。
局部聚集系数的计算
对于有向图而言,聚集系数的公式为:
C
(
v
i
)
=
e
j
k
D
(
v
i
)
(
D
(
v
i
)
−
1
)
C(v_i)=\frac{e_{jk}}{D(v_i)(D(v_i)-1)}
C(vi)=D(vi)(D(vi)−1)ejk
其中,
v
i
v_i
vi代表结点,
j
,
k
j,k
j,k是属于结点
v
i
v_i
vi的邻接点集合的结点
v
j
,
v
k
v_j,v_k
vj,vk,
D
(
v
i
)
D(v_i)
D(vi)为结点
v
i
v_i
vi的邻接点个数。
对无向图而言,聚集系数的公式为:
C
(
v
i
)
=
2
e
j
k
D
(
v
i
)
(
D
(
v
i
)
−
1
)
C(v_i)=\frac{2e_{jk}}{D(v_i)(D(v_i)-1)}
C(vi)=D(vi)(D(vi)−1)2ejk
注:对于
v
i
v_i
vi的邻接点个数,我认为是该点出度入度之和,不知道理解的是否有误,特此标明。
聚集系数
代码实现如下:
def getNeighbor(nodes,edges):
nodeDict={}
for node in nodes:
neighbor=[[],[]]
for edge in edges:
if edge[0]==node:
neighbor[0].append(edge[1])#neighbor[0]存放node指向的结点
elif edge[1]==node:
neighbor[1].append(edge[0])#neighbor[1]存放指向node的结点
nodeDict[node]=neighbor
return nodeDict
def getCount(nodes,edges):
#获取结点node邻接点中,存在edge的个数count
nodeDict=getNeighbor(nodes,edges)
resultDict={}
for k,v in nodeDict.items():
nodeList=[]
#将所有邻接点放到一个列表
nodeList.extend(v[0])
nodeList.extend(v[1])
count=0
for n1 in nodeList:
for n2 in nodeList:
if (n1,n2) in edges:
count+=1
resultDict[k]=count
return resultDict
#计算聚集系数
def getClusterCoffident(nodes,edges):
countDict=getCount(nodes,edges)
neighborDict=getNeighbor(nodes,edges)
resultDict={}
for k,v in countDict.items():
total=len(neighborDict[k][0])+len(neighborDict[k][1])
resultDict[k]=v/(total*(total-1))
return resultDict
if __name__ == "__main__":
vertices = []
edges = []
nodeStr=open("./data/nodes.txt").read()
f=open("clusterResult.txt","w+")
for l in nodeStr.splitlines():
vertices.append(int(l))
edgeStr=open("./data/edges.txt").read()
for l in edgeStr.splitlines():
edges.append((int(l.split(",")[0]),int(l.split(",")[1])))
result=getClusterCoffident(vertices,edges)
for k,v in result.items():
f.write(str(k)+"\t"+str(v)+"\n")
f.close()
计算结果见示图:
node数据形式为:
edges数据形式为: