做者: peghoty node
出处: http://blog.csdn.net/peghoty/article/details/9286905 算法
社区发现(Community Detection)算法用来发现网络中的社区结构,也能够看作是一种聚类算法。网络
博客上看到一篇优秀的介绍社区发现的PPT,转载过来分享:框架
从上述定义能够看出:社区是一个比较含糊的概念,只给出了一个定性的刻画。dom
另外须要注意的是,社区是一个子图,包含顶点和边。.net
下面咱们以新浪微博用户对应的网络图为例,来介绍相应的社区发现算法。blog
这里在相互关注的用户之间创建链接关系,主要是为了简化模型,此时对应的图为无向图。get
固然,咱们也能够采用单向关注来建边,此时将对应有向图。博客
这个定义看起来很拗口,但经过层层推导,能够获得以下 (4.2)的数学表达式。定义中的随机网络也称为Null Model,其构造方法为:数学
the null model used has so far been a random graph with the same number of nodes, the same number of edges and the same degree distribution as in the original graph, but with links among nodes randomly placed.
注意,(4.2) 是针对无向图的,所以这里的 m 表示无向边的条数,即若节点 i 和节点 j 有边相连,则节点 (i, j) 对 m 只贡献一条边。
标签传播算法(LPA)的作法比较简单:
第一步: 为全部节点指定一个惟一的标签;
第二步: 逐轮刷新全部节点的标签,直到达到收敛要求为止。对于每一轮刷新,节点标签刷新的规则以下:
对于某一个节点,考察其全部邻居节点的标签,并进行统计,将出现个数最多的那个标签赋给当前节点。当个数最多的标签不惟一时,随机选一个。
注:算法中的记号 N_n^k 表示节点 n 的邻居中标签为 k 的全部节点构成的集合。
SLPA 中引入了 Listener 和 Speaker 两个比较形象的概念,你能够这么来理解:在刷新节点标签的过程当中,任意选取一个节点做为 listener,则其全部邻居节点就是它的 speaker 了,speaker 一般不止一个,一大群 speaker 在七嘴八舌时,listener 到底该听谁的呢?这时咱们就须要制定一个规则。
在 LPA 中,咱们以出现次数最多的标签来作决断,其实这就是一种规则。只不过在 SLPA 框架里,规则的选取比较多罢了(能够由用户指定)。
固然,与 LPA 相比,SLPA 最大的特色在于:它会记录每个节点在刷新迭代过程当中的历史标签序列(例如迭代 T 次,则每一个节点将保存一个长度为 T 的序列,如上图所示),当迭代中止后,对每个节点历史标签序列中各(互异)标签出现的频率作统计,按照某一给定的阀值过滤掉那些出现频率小的标签,剩下的即为该节点的标签(一般有多个)。
SLPA 后来被做者更名为 GANXiS,且软件包仍在不断更新中......
这里对上面的图作个简单介绍:带问号的节点是待肯定标签的节点,黑色实心点为其邻居节点,它们的标签是已知的,注意标签均是由二元数对的序列构成的,序列中每个元素的第一个份量表示其标签,第二个份量表示该节点属于该标签对应社区的可能性(或者说几率,叫作 belonging coefficent),所以对于每一个节点,其几率之和等于 1。
咱们按照如下步骤来肯定带问号节点的标签:
1. 获取邻居节点中全部的互异(distinct) 标签列表,并累加相应的 belonging coefficent 值。
2. 对 belonging coefficent 值列表作归一化,即将列表中每一个标签的 belonging coefficent 值除以 C1 (C1 为列表中 belonging coefficent 值的最大值)。
3. 过滤。若列表中归一化后的 belonging coefficent 值(已经介于 0,1 之间)小于某一阀值 p (事先指定的参数),则将对应的二元组从列表中删除。
4. 再一次作归一化。因为过滤后,剩余列表中的各 belonging coefficent 值之和不必定等于 1,所以,须要将每一个 belonging coefficent 值除以 C2 (C2 表示各 belonging coefficent 值之和)。
通过上述四步,列表中的标签即肯定为带问号节点的标签。
这里,咱们对 Fast Unfolding 算法作一个简要介绍,它分为如下两个阶段:
第一个阶段:首先将每一个节点指定到惟一的一个社区,而后按顺序将节点在这些社区间进行移动。怎么移动呢?以上图中的节点 i 为例,它有三个邻居节点 j1, j2, j3,咱们分别尝试将节点 i 移动到 j1, j2, j3 所在的社区,并计算相应的 modularity 变化值,哪一个变化值最大就将节点 i 移动到相应的社区中去(固然,这里咱们要求最大的 modularity 变化值要为正,若是变化值均为负,则节点 i 保持不动)。按照这个方法反复迭代,直到网络中任何节点的移动都不能再改善总的 modularity 值为止。
第二个阶段:将第一个阶段获得的社区视为新的“节点”(一个社区对应一个),从新构造子图,两个新“节点”之间边的权值为相应两个社区之间各边的权值的总和。
咱们将上述两个阶段合起来称为一个 pass,显然,这个 pass 能够继续下去。
从上述描述咱们能够看出,这种算法包含了一种 hierarchy 结构,正如对一个学校的全部初中生进行聚合同样,首先咱们能够将他们按照班级来聚合,进一步还能够在此基础上按照年级来聚合,两次聚合均可以看作是一个社区发现结果,就看你想要聚合到什么层次与程度。
DCLP 算法是 LPA 的一个变种,它引入了一个参数来限制每个标签的传播范围,这样可有效控制 Monster (很是大的 community,远大于其余 community)的产生。
最后,咱们给出一些实验结果。
对比上述两个表格可知:SDCLP 算法获得的 top 5 社区更为均匀。