社区发现FN算法Python实现

时间:2024-05-23 13:46:04

社区发现FN算法Python实现

​2004年,Newman在GN(Girvan and Newman, 2002)算法的基础上,提出了另外一种快速检测社区的算法,称为FN算法。该算法能得到和GN算法相似的结构,但是时间复杂度更低,GN算法的时间复杂度为O(m2n)O(m^2n),FN算法的时间复杂度为O((m+n)n)O((m+n)n),其中,mm是边的数量,nn是节点的数量。此处给出FN算法的Python实现,并给出对比实验以及社区发现的三种评价指标。

社区发现FN算法Python实现
Newman, M. E. J. ,2004. Fast algorithm for detecting community structure in networks. phys rev e stat nonlin soft matter phys, 69, 066133.

去看原文

算法原理

FN算法是一种层次聚类算法。起初每个节点都是一个类。每次合并让Q值增加(即ΔQ\Delta{Q})最大的一对节点,重复这个过程,直到所有节点都在一个社区为止。在这个合并的过程中,选择Q值(社区发现评估指标)最大的作为最终划分结果。

ΔQ=2(eijaiaj) \Delta{Q}=2(e_{ij}-a_ia_j)
其中,eije_{ij}表示连接社区ii和社区jj的边的比例;aia_i表示连接到社区ii的所有末端节点比例,ai=jeija_i=\sum_j{e_{ij}}。以下是一个合并的结构图,从下往上进行合并。
社区发现FN算法Python实现

评价指标

社区发现的评估指标主要有三个:互信息和标准化互信息(Normalized Mutual Information,NMI指数)、调整兰德指数(Adjusted Rand Index,ARI指数)、模块度Q(modularity Q)。

当无法获取真实社区划分结果时,可以采用模块度Q来评价。Modularity用于评判社区划分结果的优劣。模块度越大则表明社区划分效果越好,其范围在[0.5,1)[-0.5,1),论文(Newman, 2003)表示当Q值在0.3~0.7之间时,说明聚类的效果很好。

Q=i=1n(eiiai2) Q=\sum_{i=1}^{n}(e_{ii}-a_i^2)
其中eij=vwAvw2me_{ij}=\sum_{vw}\frac{A_{vw}}{2m}ai=ki2m=jeija_i=\frac{k_i}{2m}=\sum_je_{ij}
mm表示边的数量,eije_{ij}表示一个节点在社区ii内,另一个节点在社区jj内的边的比例。eiie_{ii}表示在社区ii内所有的边与整个网络所有的边的一个比值(一个社区内部的度比上整个网络的度),而aia_{i}则表示i社区内的节点的度(包含了一点在社区ii内一点在社区ii外的边的度)占整个网络的度比值。

可将模块度用矩阵形式表示,即
Q=12mTr(STBS) Q=\frac{1}{2m}Tr(S^TBS)
其中,Bij=Aijkikj2mB_{ij}=A_{ij}-\frac{k_ik_j}{2m}kik_i代表的是节点ii的度,AijA_{ij}为邻接矩阵; SS为每个节点所属社区的one-hot表示,Sir=1S_{ir}=1表示第ii个节点属于第rr社区。

当已知真实社区划分结果时,可采用NMI指数和ARI指数进行评价。
1.NMI指数
如果结果越相似NMI值应接近1;结果很差则NMI值接近0。
NMI(X,Y)=2MI(X,Y)H(X)+H(Y) NMI(X,Y)=\frac{2MI(X,Y)}{H(X)+H(Y)}
其中,MI(X,Y)=i=1Xj=1YP(i,j)log(P(i,j)P(i)P(j))MI(X,Y)=\sum_{i=1}^{|X|}\sum_{j=1}^{|Y|}P(i,j)log(\frac{P(i,j)}{P(i)P'(j)})H(X)=i=1XP(i)log(P(i))H(X)=-\sum_{i=1}^{|X|}P(i)log(P(i))H(Y)=j=1YP(j)log(P(j))H(Y)=-\sum_{j=1}^{|Y|}P'(j)log(P'(j))XYX,Y是划分类别唯一标签和真实类别唯一标签。

以下将用一个例子来介绍如何计算。
输出的划分结果:A=[1 2 1 1 1 1 1 2 2 2 2 3 1 1 3 3 3]
真实的划分结果:B=[1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3]

那么X=unique(A)=[1,2,3]Y=unique(B)=[1,2,3]X=unique(A)=[1,2,3],Y=unique(B)=[1,2,3]
P(i,j)P(i,j)表示同时属于社区ii和社区jj的节点的联合概率,P(i,j)=XiYjNP(i,j)=\frac{|X_i\bigcap{Y_j}|}{N},NN为节点数,iX,jYi\in{X},j\in{Y}
P(i),P(j)P(i),P(j)分别为类别i,ji,j的概率分布,P(i)=XiN,P(j)=YjNP(i)=\frac{|X_i|}{N},P'(j)=\frac{|Y_j|}{N}
H(X),H(Y)H(X),H(Y)分别为X,YX,Y的信息熵。
所以P(X)=[8/17,5/17,4/17]P(X)=[8/17,5/17,4/17]P(Y)=[6/17,6/17,5/17]P(Y)=[6/17,6/17,5/17]
P(X,Y)=[5/171/172/171/174/17001/173/17] P(X,Y)=\begin{bmatrix} 5/17 & 1/17 & 2/17 \\ 1/17 & 4/17 & 0 \\ 0 & 1/17 & 3/17 \\ \end{bmatrix}
因此,MI(X,Y)=sum(P(X,Y)log(P(X,Y)/(P(X)TP(Y))))MI(X,Y)=sum(P(X,Y) * log(P(X,Y)/(P(X)^TP(Y))))H(X)=P(X)log(P(X)T)H(X)=-P(X)log(P(X)^T)H(Y)=P(Y)log(P(Y)T)H(Y)=-P(Y)log(P(Y)^T),则NMI(X,Y)=0.3646NMI(X,Y)=0.3646

[1] Detecting the overlapping and hierarchical community structure in complex networks

2.ARI指数
兰德指数(RI指数)是两种划分X,YX,Y中顶点对正确分类的数量(顶点对在同一个社团中或者在不同的社团中)与总的顶点对的数量的比值,可以使用下式表示:
RI(X,Y)=a00+a11a00+a01+a10+a11=a00+a11C2n RI(X,Y)=\frac{a_{00}+a_{11}}{a_{00}+a_{01}+a_{10}+a_{11}}=\frac{a_{00}+a_{11}}{C_2^n}
其中,a00a_{00}表示在真实社团划分与实验得到的社团划分里都不属于同一社团的点对数目;a11a_{11}表示在真实社团划分与实验得到的社团划分里都属于同一社团的点对数目;C2nC_2^n指可以组成的总顶点对对数。RIRI取值范围为[0,1][0,1],值越大意味着两种划分结果越吻合。然而RIRI会存在区分度不高的情况。因此为了提高区分度,提出了ARI指数:
ARI=RIE(RI)max(RI)E(RI) ARI=\frac{RI-E(RI)}{max(RI)-E(RI)}
ARIARI取值范围为[1,1][−1,1],值越大意味着两种划分结果越吻合。从广义的角度来讲,ARI衡量的是两个数据分布的吻合程度。

结果对比

为了验证FN算法的结果质量和计算效率,采用了3个不同的测试案例来和GN算法进行对比实验。

自定义网络 dolphins football
节点数量 22 62 115
边数量 37 159 613

以下是实验结果(football网络有真实划分结果,分割线|前的为GN算法,后为FN算法,即GN | FN):

Q NMI ARI 计算时间(s)
自定义网络 0.528|0.528 / / 0.024|0.02
dolphins 0.519|0.495 / / 0.67|0.46
football 0.60|0.55 0.88|0.70 0.78|0.47 10.1|8.8

可以看出,FN算法的结果质量稍逊于GN算法,但是计算效率更高。

以下是dolphins网络中两个算法结果的可视化:
FN算法结果(4个社区):
社区发现FN算法Python实现
GN算法结果(5个社区):
社区发现FN算法Python实现

源码

原文有源码,去看原文

更多内容,请关注地学分析与算法。
社区发现FN算法Python实现