蛋白质相互作用系列:GN快速算法

 通过前两篇博客,我们知道GN算法的时间复杂度并不理想,当网络中包含上千个顶点时,这个算法会耗费大量时间。鉴于此,Newman(2004)[1]描述了一个快速算法。经测试,该算法能很好的分析生成的网络和真实世界的网络,并比原先算法快了近千倍!
 快速算法的时间复杂度为O((m+n)n),当时稀疏网络时是O(n2),其中m是顶点数,n是边数。此算法是凝聚法的一种,并且是基于模块度Q。既然Q值越大,则划分的社区结构越好,那么可不可以将一个网络所有的划分情况都罗列出来,然后计算Q值,找出Q值最大的那种划分情况,这个划分无疑是最好的。但罗列出所有的划分情况是非常耗时!即如果有n个顶点,划分为g个社团(0<=g<=n),则根据第二类斯特林数,共有Sn(g)
1 g ! ∑ k = 0 g ( − 1 ) k ( g k ) ( g − k ) n \frac { 1 } { g ! } \sum _ { k = 0 } ^ { g} ( - 1 ) ^ { k } \left( \begin{array} { c } g \\ k \end{array} \right) ( g - k ) ^ { n } g!1k=0g(1)k(gk)(gk)n,所以总情况数为 ∑ g = 1 n S n ( g ) \sum _ { g = 1 } ^ { n } S _ { n } ^ { ( g ) } g=1nSn(g)
S n ( 1 ) + S n ( 2 ) = 2 n − 1 S _ { n } ^ { ( 1 ) } + S _ { n } ^ { ( 2 ) } = 2 ^ { n - 1 } Sn(1)+Sn(2)=2n1,可知总情况数目是指数型增长的,所以当网络中有20以上的顶点时,计算总情况数是不可行的。故我们可以转而求局部最优解,而快速算法是基于贪婪算法的寻求局部最大Q值。
 在正式介绍快速算法之前,我们先明确一个概念,即 e i j e _ { i j } eij,当表示社团i和社团j之间的边数占总边数的比例。Newman做了特别的声明:一条边的计数不能同时出现在e矩阵的对角线的上方和下方,例如当总边数为17,而i,j之间有5条边,则 e i j e _ { i j } eij= e j i e _ { ji } eji= 1 2 × 5 17 \frac { 1 } { 2 } \times \frac { 5 } { 17 } 21×175,即将i,j之间边数分为两份,一份计入 e i j e _ { i j } eij,一份计入 e j i e _ { ji } eji。故 e i j e _ { i j } eij+ e j i e _ { ji } eji为社团i和社团j之间的边数占总边数的比例(我们先记下这点,下文会用到。)
 快速算法的步骤如下:
 1,将网络每个顶点均看做一个社团,初始的顶点i和j之间有边相连,则 e i j e _ { i j } eij= 1 2 m \frac { 1 } { 2 m } 2m1,否则为0。
a i = k i 2 m a _ { i } = \frac { k _ { i } } { 2 m } ai=2mki, k i k_{i} ki是顶点i的度。
 2,依次合并有边相连的社团对,并计算合并后的Q值的增量 Δ Q \Delta Q ΔQ :
Δ Q = e i j + e j i − 2 a i a j \Delta Q = e _ { i j } + e _ { j i } - 2 a _ { i } a _ { j } ΔQ=eij+eji2aiaj
 下面解释一下 Δ Q \Delta Q ΔQ的由来:根据上篇博客给出的Q值定义,则可知 Δ Q \Delta Q ΔQ定义为(新增的内部边数)-(该类边的期望边数)
两个社团i,j合并后,之前社团i、j内部的仍是新社团内部的边,而之前社团i,j之间连接的边也成了新社团内部的边。所以整个网络的内部边的增量为 e i j + e j i e _ { i j } + e _ { j i } eij+eji,而i,j间边数期望值是 k i k j 2 m \frac { k i k j } { 2 m } 2mkikj= 2 a i a j 2 a _ { i } a _ { j } 2aiaj

 虽然快速算法在时间复杂度方面由于GN算法,但是据实验表明,它的准确度是差于GN算法的。
参考文献:
[1]:Newman M E . Fast algorithm for detecting community structure in networks[J]. Phys Rev E Stat Nonlin Soft Matter Phys, 2004, 69(6 Pt 2):066133.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我们可以使用Python中的networkx库来生成一个随机网络,并使用Python中的community库来进行社团划分。 首先,我们需要安装networkx和community库。可以使用以下命令进行安装: ``` pip install networkx pip install python-louvain ``` 接下来,我们可以使用networkx库生成一个随机网络,代码如下: ```python import networkx as nx import random # 生成一个包含n个节点、m条边的随机图 n = 100 # 节点数 m = 200 # 边数 G = nx.gnm_random_graph(n, m) ``` 然后,我们可以使用不同社团划分算法对这个随机网络进行社团划分,并计算对应的模块度Q值。下面是使用GN算法、Louvain算法、FN算法、标签传播算法的代码: ```python import community # GN算法 gn_partition = community.girvan_newman(G) gn_communities = tuple(sorted(c) for c in next(gn_partition)) gn_Q = community.modularity(nx.Graph(G), gn_communities) # Louvain算法 louvain_partition = community.best_partition(G) louvain_communities = {} for node, community_id in louvain_partition.items(): if community_id in louvain_communities: louvain_communities[community_id].append(node) else: louvain_communities[community_id] = [node] louvain_communities = tuple(sorted(c) for c in louvain_communities.values()) louvain_Q = community.modularity(G, louvain_partition) # FN算法 fn_communities = community.asyn_fluidc(G, 10) fn_Q = community.modularity(G, fn_communities) # 标签传播算法 label_propagation_communities = list(nx.algorithms.community.label_propagation_communities(G)) label_propagation_Q = community.modularity(G, label_propagation_communities) ``` 最后,我们可以输出每种算法对应的社团划分和模块度Q值: ```python print("GN算法:") print(f"社团划分:{gn_communities}") print(f"模块度Q值:{gn_Q}") print("Louvain算法:") print(f"社团划分:{louvain_communities}") print(f"模块度Q值:{louvain_Q}") print("FN算法:") print(f"社团划分:{fn_communities}") print(f"模块度Q值:{fn_Q}") print("标签传播算法:") print(f"社团划分:{label_propagation_communities}") print(f"模块度Q值:{label_propagation_Q}") ``` 完整代码如下: ```python import networkx as nx import community # 生成一个包含n个节点、m条边的随机图 n = 100 # 节点数 m = 200 # 边数 G = nx.gnm_random_graph(n, m) # GN算法 gn_partition = community.girvan_newman(G) gn_communities = tuple(sorted(c) for c in next(gn_partition)) gn_Q = community.modularity(nx.Graph(G), gn_communities) # Louvain算法 louvain_partition = community.best_partition(G) louvain_communities = {} for node, community_id in louvain_partition.items(): if community_id in louvain_communities: louvain_communities[community_id].append(node) else: louvain_communities[community_id] = [node] louvain_communities = tuple(sorted(c) for c in louvain_communities.values()) louvain_Q = community.modularity(G, louvain_partition) # FN算法 fn_communities = community.asyn_fluidc(G, 10) fn_Q = community.modularity(G, fn_communities) # 标签传播算法 label_propagation_communities = list(nx.algorithms.community.label_propagation_communities(G)) label_propagation_Q = community.modularity(G, label_propagation_communities) # 输出结果 print("GN算法:") print(f"社团划分:{gn_communities}") print(f"模块度Q值:{gn_Q}") print("Louvain算法:") print(f"社团划分:{louvain_communities}") print(f"模块度Q值:{louvain_Q}") print("FN算法:") print(f"社团划分:{fn_communities}") print(f"模块度Q值:{fn_Q}") print("标签传播算法:") print(f"社团划分:{label_propagation_communities}") print(f"模块度Q值:{label_propagation_Q}") ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值