社团结构的划分及实现过程

社团结构的划分及实现过程

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:模块度优化

    通过对局部的节点社团进行改变,优化模块度,计算模块度

  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
GN算法是一种基于图论的社团发现算法,其实现主要包括以下几个步骤: 1. 读取图数据并构建邻接矩阵 2. 计算每个节点的度数 3. 初始化每个节点的社区为其自身 4. 对每条边进行计算,计算边的介数,并将介数最大的边移除 5. 更新节点的社区,合并介数最大的边所连接的两个社区 6. 重复步骤4和5,直到没有边可以移除为止 下面是基于Python实现GN算法的代码示例: ```python import numpy as np # 构建邻接矩阵 def build_adjacency_matrix(data): num_nodes = max([max(item) for item in data]) + 1 adjacency_matrix = np.zeros((num_nodes, num_nodes)) for item in data: adjacency_matrix[item[0], item[1]] = 1 adjacency_matrix[item[1], item[0]] = 1 return adjacency_matrix # 计算节点的度数 def compute_degree(adjacency_matrix): num_nodes = adjacency_matrix.shape[0] degree = np.sum(adjacency_matrix, axis=1) return degree # 初始化节点的社区 def init_community(num_nodes): community = np.arange(num_nodes) return community # 计算边的介数 def compute_betweenness_centrality(adjacency_matrix): num_nodes = adjacency_matrix.shape[0] betweenness_centrality = np.zeros((num_nodes, num_nodes)) for i in range(num_nodes): for j in range(num_nodes): if adjacency_matrix[i, j] == 1: betweenness_centrality[i, j] = 1 betweenness_centrality[j, i] = 1 for k in range(num_nodes): for i in range(num_nodes): for j in range(num_nodes): if i != j and i != k and j != k: if betweenness_centrality[i, j] == 0 and adjacency_matrix[i, k] * adjacency_matrix[k, j] != 0: betweenness_centrality[i, j] = betweenness_centrality[i, k] * betweenness_centrality[k, j] elif adjacency_matrix[i, k] * adjacency_matrix[k, j] != 0: betweenness_centrality[i, j] += betweenness_centrality[i, k] * betweenness_centrality[k, j] return betweenness_centrality # 合并社区 def merge_community(community, community_1, community_2): for i in range(len(community)): if community[i] == community_2: community[i] = community_1 return community # GN算法 def gn_algorithm(data): # 构建邻接矩阵 adjacency_matrix = build_adjacency_matrix(data) # 计算节点的度数 degree = compute_degree(adjacency_matrix) # 初始化节点的社区 community = init_community(adjacency_matrix.shape[0]) # GN算法迭代 while np.sum(adjacency_matrix) != 0: # 计算边的介数 betweenness_centrality = compute_betweenness_centrality(adjacency_matrix) # 获取介数最大的边 max_index = np.unravel_index(np.argmax(betweenness_centrality), betweenness_centrality.shape) # 移除介数最大的边 adjacency_matrix[max_index[0], max_index[1]] = 0 adjacency_matrix[max_index[1], max_index[0]] = 0 # 更新社区 community = merge_community(community, community[max_index[0]], community[max_index[1]]) return community ``` 该代码实现了GN算法的主要步骤,并在每次迭代中移除介数最大的边,并更新节点的社区。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值