Louvain算法是一种基于图数据的社区发现算法,算法的优化目标为最大化整个数据的模块度,模块度的计算以下:算法
其中m为图中边的总数量,k_i表示全部指向节点i的连边权重之和,k_j同理。A_{i,j} 表示节点i,j之间的连边权重。有一点要搞清楚,模块度的概念不是Louvain算法发明的,而Louvain算法只是一种优化关系图模块度目标的一种实现而已。sql
Louvain算法的两步迭代设计:
最开始,每一个原始节点都当作一个独立的社区,社区内的连边权重为0.
算法扫描数据中的全部节点,针对每一个节点遍历该节点的全部邻居节点,衡量把该节点加入其邻居节点所在的社区所带来的模块度的收益。并选择对应最大收益的邻居节点,加入其所在的社区。这一过程化重复进行指导每个节点的社区归属都不在发生变化。
对步骤1中造成的社区进行折叠,把每一个社区折叠成一个单点,分别计算这些新生成的“社区点”之间的连边权重,以及社区内的全部点之间的连边权重之和。用于下一轮的步骤1。
该算法的最大优点就是速度很快,步骤1的每次迭代的时间复杂度为O(N),N为输入数据中的边的数量。步骤2 的时间复杂度为O(M + N), M为本轮迭代中点的个数。
迭代过程:优化
1, 假设咱们最开始有5个点,互相之间存在必定的关系(至于什么关系,先无论),以下:spa
2. 假设在进过了步骤1的充分迭代以后发现节点2,应该加入到节点1所在的社区(最开始每一个点都是一个社区,而本身就是这个社区的表明),新的社区由节点1表明,以下:.net
此时节点3,4,5之间以及与节点1,2之间没有任何归属关系。设计
3. 此时应该执行步骤2,将节点1,2组合成的新社区进行折叠,折叠以后的社区当作一个单点,用节点1来表明,以下:blog
此时数据中共有4个节点(或者说4个社区),其中一个社区包含了两个节点,而社区3,4,5都只包含一个节点,即他们本身。get
4. 从新执行步骤1,对社区1,3,4,5进行扫描,假设在充分迭代以后节点5,4,3分别前后都加入了节点1所在的社区,以下:社区
5. 进行步骤2,对新生成的社区进行折叠,新折叠而成的社区当作一个单点,由节点1表明,结构以下:遍历
此时因为整个数据中只剩下1个社区,即由节点1表明的社区。再进行步骤1时不会有任何一个节点的社区归属发生变化,此时也就不须要再执行步骤2,至此, 迭代结束。
转自: https://blog.csdn.net/xsqlx/article/details/79078867