社团结构的划分及实现过程
022036930019 张志龙 2022.11.18
题目
什么是网络社团结构,介绍给出社团结构划分几种常见算法,并且给出你实现的过程。同时对一些真实网络进行划分与真实情况进行比较,并且给出你的解释。
社团结构划分的算法介绍
从Barabasi在1999年首次发表关于无标度网络的论文后,对复杂网络的研究引起许多研究工作者的关注。复杂网络存在于人类现实社会中,存在于虚拟空间中,形态各异,复杂多变,但在统计意义上呈现很多相似的属性[1]。在这些复杂网络中,存在一些内部链接紧密,外部链接稀疏的节点,这些节点组成的网络结构称为网络社团结构。
在网络科学中对社团的定义,主要从以下几点假设出发:
1) 网络的社团结构仅由其连接模式决定。
2)社团是网络中局部紧密连接的子图。
社团结构的划分通常是利用网络连接的结构信息从网络中发现模块化的社团结构,通常也被称为社团检测和图聚类。社团结构划分有很多算法,以下列出四种:
1)GN(Girvan-Newman)算法[2]
GN算法是分裂算法,该算法依据边不属于社团的程度,逐步删除不同社区的节点之间的连接,最终将网络拆解成彼此独立的社区。GN算法复杂度量级为O(L2N),在稀疏网络上为O(N3)。
2)Louvain算法
Louvain算法是贪婪算法。由Blondel [3]等人提出,是基于模块化,进行局部优化的层次凝聚方法。该算法的优点在于速度快,可以较短时间内实现大规模网络以不同粒度的社团划分,并且无需指定社团的数量,当模块化不再增益时,迭代自动停止。Louvain算法复杂度量级为O(nlogn)。该算法优点是:1. 时间复杂度小;2.支持权重图;3.提供分层的社区结果,可根据需要选择层级;4.适用于研究大型网络。
3)FN算法
Newman[4]在GN算法基础上提出快速模块度优化FN算法,FN算法是一种基于贪婪算法思想的凝聚算法。该算法先使每个顶点初始化一个社团,选择使模块度增值最大的社团进行合并,从而在此过程中形成树图。最后在树图的所有层次中选择模块度最大的社团划分作为最终划分。
4)CNN算法
针对FN算法的缺点,付常雷[5]提出一种基于Newman快速算法改进的社团划分算法,将社团贡献度(community contribution)作为社团合并依据。CNN算法的合并步骤直接根据各个社团的贡献度大小,然后选择贡献度最小且相连的两个社团合并,在时间性能上较FN算法有较大程度的提高。
算法实现
GN算法的实现
借助python中的networkx、community库,可以很方便的实现GN算法。
1)导入网络数据
2)调用community库里的girvan-Newman函数
comp = community.girvan_newman(G) # GN算法
GN算法步骤:
① 计算网络中所有边介数
②找到介数最高的边并删除,然后重新计算边介数
③重复第二步,直到所有边都被移除
k = 4 # 想要4个社区
limited = itertools.takewhile(lambda c: len(c) <= k, comp) # 层次感迭代器
for communities in limited:
b = list(sorted(c) for c in communities)
3)绘制网络图
pos = nx.spring_layout(G) # 节点的布局为spring型
NodeId = list(G.nodes())
print("NodeID:%s"%NodeId)
node_size = [G.degree(i)**1.2*90 for i in NodeId] # 节点大小
plt.figure(figsize = (8,6)) # 图片大小
nx.draw(G,pos, with_labels=False, node_size =node_size, node_color='w', node_shape = '.')
'''
node_size表示节点大小
node_color表示节点颜色
node_shape表示节点形状
with_labels=True表示节点是否带标签
'''
color_list = ['brown','orange','r','g','b','y','m','gray','black','c','pink']
# node_shape = ['s','o','H','D']
print(len(b))
for i in range(len(b)):
# nx.draw_networkx_nodes(G, pos, nodelist=b[i], node_color=color_list[i], node_shape=node_shape[i], with_labels=True)
print (b[i])
nx.draw_networkx_nodes(G, pos, nodelist=b[i], node_color=color_list[i], with_labels=True)
plt.show()
Louvain算法的实现
借助python中的networkx、community库,可以快速实现Louvain算法。
1)导入网络数据
2)调用community库里的Louvain库
partition = community_louvain.best_partition(G)
在Louvain算法过程中,每个阶段分为两步:
-
Step 1:模块度优化
通过对局部的节点社团进行改变,优化模块度,计算模块度