图数据挖掘:重叠和非重叠社区检测算法
最近需要学习图结构中的社区检测算法,在阅读相关论文的同时跟了Stanford CS246: Mining Massive Datasets课程[1]的第11讲Community Detection in Graphs,以下是我做的笔记。
1. 网络和社区(networks & communities)
我们通常认为网络中存在某种模块(modules)/簇(clusters)/社区(communitis)结构,我们常常需要从网络中提取这些结构。
而提取这些结构的关键在于发现密集连接的簇,而这常常可以转化为一个优化关于簇的目标函数的问题,即所谓最小化类簇之间的边数或最大化簇的质量(例如后面提到的模块度)。这类算法我们通常称为社区检测(community detection) [2]算法。社区检测算法和传统聚类算法的主要不同点在于:社区检测算法更关注节点分布的密度,且无需设置簇的先验个数\(k\),可以重叠划分。
不过,两者的界限没那么明显。比如在普通的聚类算法中也有不需要指定先验类簇数\(k\)、考察样本分布紧密程度的DBSCAN密度聚类算法[3],该算法可以看做社区检测算法思想的雏形。还有一点细节需要注意,社区检测中节点之间权重越大越容易划分到一起,传统聚类算法中距离越小越容易划分到一起,正好是反着的。
2.重叠(overlapping)和非重叠(non-overlapping)社区检测
按照图的社区划分之间是否重叠,可分为重叠社区检测和非重叠社区检测。非重叠社区检测是指图的社区划分之间没有重叠,而重叠社区检测则允许有重叠。
3.基于conductance(电导)的图划分方法
3.1 割分数(cut score)
设有一个无向图\(G(V,E)\),我们将其节点划分为两个组\(A, B\),其中\(B = V\backslash A\),我们如何判断我们划分的质量呢?
我们运用直觉思考,好的划分有什么特性?一般而言,好的划分有两个特点:
- 使单个簇内部的连接数量最大化
- 使不同簇之间的连接最小化
接下来我们需要定量地将簇的质量表示为该簇的边割(edge cut)的函数。边割是指跨越簇的边集合,该边集满足:如果将该边集去除,则图变得不连通。注意,这和割边(cut edge)是两码事。割边特指跨越簇的一条边,该边满足:如果将该边去除,则图变得不连通。也就是说,割边是去掉一条边,可以使图的连通分量个数变大;而边割则是去掉好几条边,可以使图的连通分量个数变大。
割分数(cut score) 为只有一个节点在簇中的边的边权之和(如果为无权图,则权值计为1)。用公式表达如下:
对于下面这张无权图,则我们有\(cut(A) = 2\):
也就是说,对于一个簇\(A\),若\(cut(A)\)越小,则我们说这个簇的质量越好。那么所谓的簇划分,是否意味着我们只需要找到一组能够时\(cut(A)\)尽量小的节点就可以呢?
光这样还不够,因为我们事实上只考虑了簇外部的联系,但是没有考虑簇内部的联系,这样容易导致很多问题。我们看下面这个退化的情形。很明显,就下面这张图而言,红色的所谓“mimimum cut”确实做到使\(cut(A)\)最小了,但是明显另外一种划分方法才是我们想要的。
那么我们如何进一步考虑到簇内部的联系呢?这时就要引出簇的volume(体积)和conductance(好像翻译成电导?)的概念了。
3.2 电导(conductance)
conductance是指一个簇和剩余网络的联系,它和这个簇的的密度(体积)有关系。它在某种意义上可以理解为表面积和体积比(surface-to-volume ratio)。直观地理解,它等于这个簇的割分数除以这个簇自身的密度(体积),这个值越小说明划分得越好。
接下来我们再来看conductance这个有点可怕的公式(其实理解了它的意义后就会发现并不可怕):
此公式中\(m\)指图中边的数量,\(2m\)即图中所有点的度数之和,\(E\)指图的边集。\(vol(A)\)定义为簇\(A\)中所有点的度之和:
(也可以写作\(vol(A)= 2\cdot \sharp\text{edges inside } A + \sharp \text{edges pointing out of } A\))
\(\phi(A)\)定义式的分母部分实质上就相当于从割边分开的两个簇的\(vol\)值中选小的那个。
我们再来用conductance重新审视图的划分。
很明显,若我们关注红色的簇,边的那种划分方式\(\phi = 2/(3+1)=0.5\)(其中\(2\)为红色簇跨出去的边数之和,\(3+1=4\)为红色簇的度数之和),右边的那种划分方式\(\phi = 6/92=0.065\),很明显右边的那种划分方式更好。
根据这个划分标准,有许多论文已经提出了相关的簇划分算法,如[4][5],大家可以参考论文,此处略过不表。
4.基于模块性(modularity)的图划分方法
4.1 模块性
对于一个网络社区,我们定义其模块性(modularity)\(Q\)做为一个网络被划分为社区的好坏度量。给定一个网络的划分,该划分将网络划分为由多个组\(s\)组成的集合\(S\),我们有:
我们给定一个有\(n\)个节点和\(m\)条边的图,我们据此构建重布线的(rewired)网络\(G^{'}\)。该网络\(G^{'}\)满足:有同样的度分布但是有着随机的边连接;是多重图(multigraph)(即允许有多重边的图);节点\(i\)(度为\(k_i\))和\(j\)(度为\(k_j\))之间的期望边数量为:\(k_i \cdot \frac{k_j}{2m} = \frac{k_i k_j}{2m}\)。
我们根据以上信息,进一步图\(G\)被划分为组\(S\)的模块性写为
这里\(m\)为一个标准化常数,使得\(-1<Q<1\)。\(A_{ij}\)为节点\(i\)和节点\(j\)之间的边权,若无连接则为0。
如果在簇内部的边数量超过了其期望的边数量,则模块性\(Q\)为正。比\(0.3-0.7\)大的\(Q\)意味着非常重要的社区结构。
等效地,模块性公式还能够被写作:
这里\(A_{ij}\)仍然指节点\(i\)和\(j\)之间的边权,\(k_i\)分别\(k_j\)指以节点\(i\)和\(j\)做为端点的边权之和,\(2m\)是凸中所有边的权值之和,\(c_i\)和\(c_j\)是节点组成的社区,\(\delta\)是一个示性函数。此时,我们有一个想法: 我们能够通过最大化模块性\(Q\)来识别社区。
4.2 Louvain(鲁汶)方法
我们可以采用一个启发式方法,也就是Louvain方法[6]来解决最大化模块性的问题。该算法常常用于非重叠(nonoverlapping) 的社区检测。这个算法是一个贪心算法,时间复杂度为\(O(n log n)\),它支持带权图,能够提供层次化的划分方法(比如我们熟知的层次聚类)。该方法运行效率高、收敛快、输出结果模块性高(也即输出的社区划分质量较好),被广泛地应用于大规模网络。
Louvain算法贪心地最大化模块性,它会进行多轮的迭代,每一轮迭代都由两个步骤组成:
- 步骤 1(划分):在只允许对社区做局部改变(local changes)的情况下优化模块性,得到一个初步的社区划分。
- 步骤 2(重构):对已划分出的社区做聚合,建立新的社区网络。
我们接下来详细地叙述步骤1和步骤2。
步骤1(划分)
对于步骤1,算法先将图中的每个节点(后面我们会提到算法会将社区也缩为一个超节点)视为一个独立的社区。然后对每个节点\(i\),算法执行两步计算:首先,对节点\(i\)的每个邻居\(j\),计算将\(i\)从其现在的社区中放入\(j\)所在的社区时可获得的模块性增益(modularity gain)\(\Delta Q\);然后,将\(i\)移入能够获得最大\(\Delta Q\)的社区。
注:
当我们将节点\(i\)移入社区\(C\)中时,其模块性增益\(\Delta Q\)计算方式如下:
\[\Delta Q(i \rightarrow C)=\left[\frac{\sum_{i n}+k_{i, i n}}{2 m}-\left(\frac{\sum_{t o t}+k_{i}}{2 m}\right)^{2}\right]-\left[\frac{\sum_{i n}}{2 m}-\left(\frac{\sum_{t o t}}{2 m}\right)^{2}-\left(\frac{k_{i}}{2 m}\right)^{2}\right] \]这里\(\sum_{in}\)对\(C\)中所有节点的"簇内"邻边(不包括边割)的边权进行求和;\(\sum_{tot}\)对\(C\)中所有节点的邻边(包括边割)边权进行求和;\(k_{i, in}\)是节点\(i\)和簇\(C\)之间的所有边的权重之和;\(k_i\)指节点\(i\)所有邻边的权重之和(若权值为1的话就是节点的度)。
同理,我们可以得到\(\Delta Q(D\rightarrow i)\),这表示将节点\(i\)移出社区\(D\)所得的增益。
接下来,我们有\(\Delta Q=\Delta Q(i \rightarrow C)+\Delta Q\left(D\rightarrow i\right)\)
步骤2(重构)
将第一阶段中划分而成的社区缩为超节点(super-nodes),然后我们按照以下的步骤来构建新的带权网络:如果在两个社区的节点之间至少有一条边,那么对应的两个超节点之间就是连接的;在两个超节点之间的边的权值是其对应社区之间所有边割的权值之和。
最后,我们将Louvain方法用流程示意图描述如下:
5.重叠(overlapping)社区检测方法
上面我们介绍的Louvain算法是一种用于非重叠(nonoverlapping)社区检测的方法。然而,有时社区的潜在结构并不明显,不同的社区之前很可能存在某种关联。此时,我们就需要采用重叠(overlapping)社区检测算法了[7]。重叠社区检测算法包括以下几个大类:以CPM[8]为代表的Clique Percolation(团渗透)类方法、以LinkComm[9]为代表的的边划分(Link partition)类方法,以SLPA[10]为代表的动态(dynamic)方法,以LEMON[11]为代表的的种子扩张方法。我们下面介绍LinkComm方法和LEMON方法。
5.1 LinkComm方法
LinkComm方法为典型的采用划分边来发现社区结构的方法,它基于这样一个思想:一个在原始图中的节点是重叠的话,则连接它的边会被放入大于一个的簇中。
该算法基于和Louvain算法类似的思想,首先迭代地按照边的相似度进行层次化聚类(即每轮迭代选取相似度最大的一对边,将它们的社区合并),构造一个层次化聚类的树状图(dendrogram)。如下图所示:
在上图中,\(a\)为按照节点进行社区划分,\(b\)为按照边进行社区划分,\(c\)为最后的边相似度矩阵与边树状图。
已知边\(e_{ik}\)和边\(e_{jk}\)共享节点\(k\),则它们的相似度采用Jaccard index来度量:
此处\(n_{+}(i)\)指的是节点\(i\)的邻居节点(包括节点\(i\)自身)。
边相似度的计算如下图所示:
A图中\(S\left(e_{i k}, e_{j k}\right)\)度量了共享节点\(k\)的边\(e_{ik}\)和\(e_{jk}\)之间的距离,\(|n_{+}(i) \cup n_{+}(j)|=12\),\(|n_{+}(i) \cap n_{+}(j)|=4\),\(S=\frac{1}{3}\)。在B图中,\(S=\frac{1}{3}\)。C图中\(S=1\)。
在非重叠划分中的louvain算法中,层次聚类的停止通常由modularity来决定(如果目前划分结果的modularity不再增加则停止),否则最终会默认聚类为一个社区。modularity虽然广泛用于非重叠的节点层次化划分操作,但是对于重叠社区却不好定义。文中采用了一种新的量化方式,即划分密度(partition density)\(D\),来度量边划分的质量。划分密度沿着聚类树状图会有一个全局最大值,聚类过程就在该处停下。
5.2 Lemon方法
LEMON全称Local Expansion via Minimum One Norm(最小化一范数的局部扩张),它要解决的问题是:给定图\(G=(V,E)\),已知少部分节点集合\(S\)以及其所属社区的划分情况(称为seed),如何找到这些社区的其他成员?该算法基于seed set expansion(种子集合扩张)的思想,从初始化的几个seed节点开始逐渐探索其周围的邻域。具体而言,是通过寻找局部谱张成空间中的稀疏向量(该稀疏向量使得初始化seed在其支撑集里)来发现社区(该算法可以看做是谱方法[12]基础上的改进)。注意这种方法可以看 与全局的社区检测算法[13][14]大不相同。其运行时间由社区大小而不是整个图决定,该算法易于实现且可高度并行化。
算法分为以下3个步骤:
步骤1(生成局部谱)
使\(\mathbf{\bar{A}}=\mathbf{D}^{-1/2}(\mathbf{A}+\mathbf{I})\mathbf{D}^{-1/2}\)为标准化后的邻接矩阵(此处\(\mathbf{D}\)为顶点度构成的对角阵)。考虑从\(\mathcal{S}\)节点开始的随机游走。我们使\(\mathbf{p}_0\)代表初始概率向量(所有概率在seed members间均匀分布)。考虑由\(l\)维概率向量在\(l\)次连续的随机游走中的张成空间
初始化的不变子空间由计算张成空间\(\mathbf{P}_{0, l}\)的正交基获得,表示为\(\mathbf{V}_{0, l}\),我们接下来使用下列递推式迭代地计算经过\(k\)次随机游走的\(l\)维标准正交基
这里\(\mathbf{R}_{k,l}\in \mathbb{R}^{n\times l}\)被选择来使\(\mathbf{V}_{k,l}\)是正交的。正交基\(\mathbf{V}_{k,l}\)会被用于局部谱聚类。
步骤2 (寻找稀疏向量)
在局部谱\(\mathbf{V}_{k,l}\)的基础上,我们接下来解决下列线性规划问题[15]:
这里\(\textbf{e}\)是全1的向量,\(\textbf{x}\)和\(\textbf{y}\)都是未知的向量。第一个约束表明\(\textbf{y}\)在空间\(\textbf{V}_{k,l}\)里。\(\textbf{y}\)中的元素表示相应顶点属于目标社区的可能性,一定是非负的。第三个约束使seed在稀疏向量\(\textbf{y}\)的支撑集里。
在对\(\textbf{y}\)中的元素按照非降序排列后得到向量\(\hat{\textbf{y}}\),\(\hat{\textbf{y}}\)中top的\(|\mathcal{C}|\)个元素对应的节点会被做为和seed 集合\(\mathcal{S}\)相关的检测出的社区返回。
步骤3(重新播种)
在初始化的seed集合中增加与\(\hat{\textbf{y}}\)中top的\(t\)个元素相对应的节点,将增加后的seed集合表示为\(\mathcal{S}'\)。
该算法迭代轮数由终止准则(stop criteria)决定,如果有做为ground truth的社区划分结果,算法会返回F1分数最高的(关于F1分数具体可见第6部分)。
7. 常见社区检测结果评估方法
7.1 有ground truth情况
F1 score是常见的度量预测的社区\(\mathcal{C}\)和ground truth社区\(\mathcal{C}^*\)相似度的一种方法,\((\mathcal{C}, \mathcal{C}^*)\)的F1 Score定义为:
这里Precision(精度)和recall(召回率)定义为:
7.2 无ground truth情况
对于非重叠社区,最常见无ground truth评价标准的便是采用上文提到的模块性modularity了,一般认为modularity在0.3-0.7之间就算是好的划分。此外,对于overlapping划分,也可以采用所谓的划分密度(详见LinkComm论文[9])。
8. 代码实现
Louvain算法的代码的Python开源实现可参见Github项目[16],LinkComm、Lemon等重叠划分方法的Python开源实现可参见Github项目[17]。
参考文献
-
[2] Girvan M, Newman M E J. Community structure in social and biological networks[J]. Proceedings of the national academy of sciences, 2002, 99(12): 7821-7826.
-
[3] Ester M, Kriegel H P, Sander J, et al. A density-based algorithm for discovering clusters in large spatial databases with noise[C]//kdd. 1996, 96(34): 226-231.
-
[4] Lu Z, Sun X, Wen Y, et al. Algorithms and applications for community detection in weighted networks[J]. IEEE Transactions on Parallel and Distributed Systems, 2014, 26(11): 2916-2926.
-
[5] Staudt C L, Meyerhenke H. Engineering parallel algorithms for community detection in massive networks[J]. IEEE Transactions on Parallel and Distributed Systems, 2015, 27(1): 171-184.
-
[6] Blondel V D, Guillaume J L, Lambiotte R, et al. Fast unfolding of communities in large networks[J]. Journal of statistical mechanics: theory and experiment, 2008, 2008(10): P10008.
-
[7] Xie J, Kelley S, Szymanski B K. Overlapping community detection in networks: The state-of-the-art and comparative study[J]. Acm computing surveys (csur), 2013, 45(4): 1-35.
-
[8] Kumpula J M, Kivelä M, Kaski K, et al. Sequential algorithm for fast clique percolation[J]. Physical review E, 2008, 78(2): 026109.
-
[9] Ahn Y Y, Bagrow J P, Lehmann S. Link communities reveal multiscale complexity in networks[J]. nature, 2010, 466(7307): 761-764.
-
[10] Xie J, Szymanski B K, Liu X. Slpa: Uncovering overlapping communities in social networks via a speaker-listener interaction dynamic process[C]//2011 ieee 11th international conference on data mining workshops. IEEE, 2011: 344-349.
-
[11] Li Y, He K, Bindel D, et al. Uncovering the small community structure in large networks: A local spectral approach[C]//Proceedings of the 24th international conference on world wide web. 2015: 658-668.
-
[12] Ng A, Jordan M, Weiss Y. On spectral clustering: Analysis and an algorithm[J]. Advances in neural information processing systems, 2001, 14.
-
[13] Coscia M, Rossetti G, Giannotti F, et al. Demon: a local-first discovery method for overlapping communities[C]//Proceedings of the 18th ACM SIGKDD international conference on Knowledge discovery and data mining. 2012: 615-623.
-
[14] Lancichinetti A, Radicchi F, Ramasco J J, et al. Finding statistically significant communities in networks[J]. PloS one, 2011, 6(4): e18961.
MLA -
[15] GNU linear programming kit.
http://www.gnu.org/software/glpk. -
[17] https://github.com/RapidsAtHKUST/CommunityDetectionCodes