模块度与Louvain社区发现算法
Louvain算法是基于模块度的社区发现算法,该算法在效率和效果上都表现较好,并且能够发现层次性的社区结构,其优化目标是最大化整个社区网络的模块度。
模块度(Modularity)
模块度是评估一个社区网络划分好坏的度量方法,它的物理含义是社区内节点的连边数与随机情况下的边数只差,它的取值范围是 [−1/2,1),其定义如下:
$$Q = \frac{1}{2m}\sum_{i,j}[A_{ij} - \frac{k_ik_j}{2m}]\delta(c_i,c_j)$$
$$\delta(u,v) = \{_{0\ else}^{1 when\ u == v}$$
其中,$A_{ij}$节点i和节点j之间边的权重,网络不是带权图时,所有边的权重可以看做是1;$k_i = \sum_jA_{ij}$表示所有与节点i相连的边的权重之和(度数);$c_i$表示节点i所属的社区;$m=\frac{1}{2}\sum_{ij}A_{ij}$表示所有边的权重之和(边的数目)。
公式中$A_{ij} - \frac{k_ik_j}{2m}=A_{ij} - k_i\frac{k_j}{2m}$,节点j连接到任意一个节点的概率是$\frac{k_j}{2m}$,现在节点i有$k_i$的度数,因此在随机情况下节点i与j的边为$k_i\frac{k_j}{2m}$.
模块度的公式定义可以作如下简化:
$$Q = \frac{1}{2m}\sum_{i,j}[A_{ij} - \frac{k_ik_j}{2m}]\delta(c_i,c_j)$$
$$ = \frac{1}{2m}[\sum_{i,j}A_{ij} - \frac{\sum_ik_i\sum_jk_j}{2m}]\delta(c_i,c_j)$$
$$ = \frac{1}{2m}\sum_c[\Sigma in-\frac{{(\Sigma tot)}^2}{2m}]$$
其中$\Sigma in$表示社区c内的边的权重之和,$\Sigma tot$表示与社区c内的节点相连的边的权重之和。
上面的公式还可以进一步简化成:
$$Q = \sum_c[\frac{\Sigma in}{2m}-(\frac{\Sigma tot}{2m})^2]$$
$$ = \sum_c[e_c-{a_c}^2]$$
这样模块度也可以理解是社区内部边的权重减去所有与社区节点相连的边的权重和,对无向图更好理解,即社区内部边的度数减去社区内节点的总度数。
基于模块度的社区发现算法,都是以最大化模块度Q为目标。
Louvain算法
Louvain算法的思想很简单:
1)将图中的每个节点看成一个独立的社区,次数社区的数目与节点个数相同;
2)对每个节点i,依次尝试把节点i分配到其每个邻居节点所在的社区,计算分配前与分配后的模块度变化$\Delta Q$,并记录$\Delta Q$最大的那个邻居节点,如果$max\Delta Q>0$,则把节点i分配$\Delta Q$最大的那个邻居节点所在的社区,否则保持不变;
3)重复2),直到所有节点的所属社区不再变化;
4)对图进行压缩,将所有在同一个社区的节点压缩成一个新节点,社区内节点之间的边的权重转化为新节点的环的权重,社区间的边权重转化为新节点间的边权重;
5)重复1)直到整个图的模块度不再发生变化。
从流程来看,该算法能够产生层次性的社区结构,其中计算耗时较多的是最底一层的社区划分,节点按社区压缩后,将大大缩小边和节点数目,并且计算节点i分配到其邻居j的时模块度的变化只与节点i、j的社区有关,与其他社区无关,因此计算很快。在论文中,把节点i分配到邻居节点j所在的社区c时模块度变化为:
$$\Delta Q = [\frac{\sum_{in}+k_{i,in}}{2m}-(\frac{\sum_{tot}+k_i}{2m})^2]-[\frac{\sum_{in}}{2m}-(\frac{\sum_{tot}}{2m})^2-(\frac{k_i}{2m})^2]$$
其中$k_{i,in}$是社区c内节点与节点i的边权重之和,注意对$k_{i,in}$是对应边权重加起来再乘以2,这点在实现时很容易犯错。
$Delta Q$分了两部分,前面部分表示把节点i加入到社区c后的模块度,后一部分是节点i作为一个独立社区和社区c的模块度,这里有一个困惑我的地方,虽然我按照这个公式实现的分群算法效果很好,但是我认为$Delta Q$少了把节点i从其原来社区删除这一步,因为后面的划分时,节点i所在的社区可能有多个节点。
在实现的时候模块度变化还可以简化,把上面的公式展开,很多项就抵消了,化简之和:
$$\Delta Q = [\frac{k_{i,in}}{2m}-\frac{\sum_{tot}k_i}{2m^2}]$$
论文中指出,算法第2)步节点的顺序会对分群结果又一定影响,但分群效果差距不大,只是会影响算法的时间效率,还有论文指出按度数从到的小的顺序处理速度最快,不过我在1K边上的图测试,差距不大。
分布式实现
我实现了Louvain算法的Spark版本和单机版,单机版在算法的第2)步中,节点i的社区变更会在节点i+1的社区分配时可见,但分布式实现,这一点不能满足,因为在分布式环境下,节点i和节点i+1的社区变更可能是在不同机器上同时进行,不能进行实时传递,因此在分布式实现时,节点i+1看到只能是节点i的上一轮的社区,因为这个原因,会导致一些节点互换社区,比如1号节点分到了2号节点所在的社区,而2号节点又分配到了节点1所在的社区,解决这个问题我是参考淘宝的一个实现,用节点id和和社区id构成的边组成新图,再用联通图来调整节点的社区。
最后,工作了不能像上学的时候随意把代码放出来了,So.没有源代码分享~
欢迎评论,转账请注明出处:www.cnblogs.com/fengfenggirl
模块度与Louvain社区发现算法的更多相关文章
- 社区发现算法 - Fast Unfolding(Louvian)算法初探
1. 社团划分 0x1:社区是什么 在社交网络中,用户相当于每一个点,用户之间通过互相的关注关系构成了整个网络的结构. 在这样的网络中,有的用户之间的连接较为紧密,有的用户之间的连接关系较为稀疏.其中 ...
- GNN 相关资料记录;GCN 与 graph embedding 相关调研;社区发现算法相关;异构信息网络相关;
最近做了一些和gnn相关的工作,经常听到GCN 和 embedding 相关技术,感觉很是困惑,所以写下此博客,对相关知识进行索引和记录: 参考链接: https://www.toutiao.com/ ...
- 社区发现算法问题&&NetworkX&&Gephi
在做东西的时候用到了社区发现,因此了解了一下有关社区发现的一些问题 1,社区发现算法 (1)SCAN:一种基于密度的社团发现算法 Paper: <SCAN: A Structural Clust ...
- SLAP(Speaker-Listener Label Propagation Algorithm)社区发现算法
其中部分转载的社区发现SLPA算法文章 一.概念 社区(community)定义:同一社区内的节点与节点之间关系紧密,而社区与社区之间的关系稀疏. 设图G=G(V,E),所谓社区发现是指在图G中确定n ...
- Top Leaders社区发现算法(top leaders community detection approach in information networks)
一.概念 复杂网络:现实生活中各种系统都可以看做成复杂网络,复杂网络构成包括节点和边,节点是网络中的基本组成单元,节点之间的联系或者关系是网络中的边.例如 电力网络:基站代表节点,基站之间是否互通表示 ...
- 并行Louvain社区检测算法
因为在我最近的科研中需要用到分布式的社区检测(也称为图聚类(graph clustering))算法,专门去查找了相关文献对其进行了学习.下面我们就以这篇论文IPDPS2018的文章[1]为例介绍并行 ...
- LabelRank非重叠社区发现算法介绍及代码实现(A Stabilized Label Propagation Algorithm for Community Detection in Networks)
最近在研究基于标签传播的社区分类,LabelRank算法基于标签传播和马尔科夫随机游走思路上改装的算法,引用率较高,打算将代码实现,便于加深理解. 这个算法和Label Propagation 算法不 ...
- 社区发现的3个评估指标:标准化互信息NMI,ARI指标,以及模块度(modularity)
转载请注明出处:http://www.cnblogs.com/bethansy/p/6890972.html 一.已知真实社区划分结果 1.NMI指数,互信息和标准化互信息 具体公式和matlab代码 ...
- 社区发现(Community Detection)算法 [转]
作者: peghoty 出处: http://blog.csdn.net/peghoty/article/details/9286905 社区发现(Community Detection)算法用来发现 ...
随机推荐
- Tableau——BI software
Tableau 8权威指南 (权威的数据可视化实战手册,中国传媒大学教授沈浩.北京大学研究员袁晓如 联袂推荐) 触手可及的大数据分析工具——Tableau案例集 写给专业数据分析师的丛书,无门槛的大数 ...
- Java开发人员最常犯的10个错误
这个列表总结了10个Java开发人员最常犯的错误. Array转ArrayList 当需要把Array转成ArrayList的时候,开发人员经常这样做: List<String> list ...
- Java调用webservice接口方法
java调用webservice接口 webservice的 发布一般都是使用WSDL(web service descriptive langu ...
- [转]Shell中read的常用方式
原文:Linux Shell Scripting Tutorial V2.0 read命令的语法: read -p "Prompt" variable1 variable2 var ...
- js日期校验
当查询条件含有日期时,如"2012-3-4",查询前校验输入的日期字符串是否为有效的日期 var snapshot_createTime_begin=$(selector+&quo ...
- python异常
Std 异常 异常名 描述 1 Exception 所有的异常 2 StopIteration 迭代器的next()方法不指向任何对象 3 SystemExit sys.exit() 函数执行 4 S ...
- Ineedle驱动方式dpdk测试性能
这次主要是测试在dpdk方案下,ineedle的处理包的性能. 发包工具: 使用立永当时写的一个发包工具:linux_pcap 做法:大概是从网上抓取了一些数据包,将源ip替换为随即ip,sip替换为 ...
- Linux nm命令
一.简介 显示关于对象文件.可执行文件以及对象文件库里的符号信息. 二.选项 http://www.cnblogs.com/wangkangluo1/archive/2012/07/02/257243 ...
- 关于JavaScript继承的那些事
在JavaScript中,对象的创建可以脱离类型(class free),通过字面量的方式可以很方便的创建出自定义对象. 另外,JavaScript中拥有原型这个强大的概念,当对象进行属性查找的时候, ...
- LeetCode 笔记系列六 Reverse Nodes in k-Group [学习如何逆转一个单链表]
题目:Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. ...