精华内容
下载资源
问答
  • 模糊谱聚类重叠社区发现算法.pdf
  • 针对目前基于种子节点选择的社区发现算法在准确性和复杂度等方面存在的不足, 提出了一种基于Node2Vec的重叠社区发现算法. 首先, 使用Node2Vec算法学习到网络中每个节点的向量表示, 用以计算节点间的相似度, 其次, ...
  • 基于节点优化复制的重叠社区发现算法
  • 基于标签传播的语义重叠社区发现算法
  • 基于链接密度聚类的重叠社区发现算法.pdf
  • 基于二阶段聚类的重叠社区发现算法.pdf
  • 基于图熵聚类的重叠社区发现算法.pdf
  • 基于边密度聚类的重叠社区发现算法.pdf
  • 基于拓扑结构的密度峰值重叠社区发现算法
  • 基于局部语义聚类的语义重叠社区发现算法.pdf
  • Hadoop下基于边聚类的重叠社区发现算法研究.pdf
  • 基于节点的中心度和节点对社区的适应度,提出了一种新的重叠社区发现算法。该算法以中心度很大的节点作为初始社区,然后访问社区的邻居节点,把对社区适应度最大的节点加入到社区。如果节点对多个社区都具有很大的...
  • 基于完全图的局部扩展类重叠社区发现算法,赵亮,朱征宇,根据复杂网络完全图中节点属于同一社区的特点,提出一种基于完全图的重叠社区发现算法。该算法通过K-核分解算法找出核心节点,以�
  • 采用PageRank和节点聚类系数的标签传播重叠社区发现算法.pdf
  • 针对多标签传播重叠社区发现算法COPRA存在的随机性强、鲁棒性差等问题,提出一种基于多标签传播思想的重叠社区发现算法。该算法通过LeaderRank算法来量化网络中节点的重要性,再根据量化值大小对节点进行团扩展,...
  • 随着社区规模的不断扩大,基于标签传播思想的重叠社区发现算法得到较大发展。经典重叠社区发现算法虽然很好地利用了标签随机传播特性实现了重叠社区发现,但是也导致该算法输出结果很不稳定、社区生成质量较差。为...
  • 一种多目标动态社交网络重叠社区发现算法,王俊玲,左兴权,近年来,动态网络社区发现算法的研究逐渐受到人们关注,并取得了一些成果,但国内外关于动态社交网络的研究还只处于起步阶段,所
  • 针对GN算法发现重叠社区时存在的不足, 以及为了降低算法时间复杂度, 提出一种基于网络图中连边相似度划分连边集的重叠社区发现算法EGN。算法依据网络图的连边集进行划分, 每一条边被划分到某个特定的社区, 而一个...
  • 一种移动网络中的重叠社区发现算法,龚胜芳,孟祥武,该文针对移动通信网中的社区发现问题,结合传统社区发现方法的思想提出一种移动网络中的重叠社区发现算法。利用移动用户行为来构
  • 针对目前从局部社区扩展成全局社区时有关算法的种子节点选择不合理的情形,提出了一种基于种子节点选择的重叠社区发现算法。首先根据影响力函数找出局部影响力最大的节点,由这些节点构成的种子集合较好地分布在整个...
  • 为了提高网络中重叠社区发现的时间效率,提出一种基于边图的线性流重叠社区发现算法LBSA。算法首先对于边图网络中的边进行随机的依次处理,完成节点的初步社区划分,再将其中重叠小社区合并到相似度最大的其他大社区...
  • python中的自适应重叠社区发现算法包。 ASLPAw可用于不相交和重叠的社区检测,并在加权/未加权和有向/无向网络上工作。 ASLPAw是自适应的,几乎没有配置参数。 这是一个易于理解的参考实现,未针对效率进行优化,...
  • 基于信息熵和局部相关性的多标签传播重叠社区发现算法 摘要:是一种对COPRA算法进一步改善的算法。本文提出一种基于信息熵和局部相关性的多标签传播重叠社区发现算法。该算法在标签传播阶段,采用异步更新策略,...

                                                           基于信息熵和局部相关性的多标签传播重叠社区发现算法

    摘要:是一种对COPRA算法进一步改善的算法。本文提出一种基于信息熵和局部相关性的多标签传播重叠社区发现算法。该算法在标签传播阶段,采用异步更新策略,利用信息熵产生更新序列指导标签更新,解决社区划分结果不稳定问题。同时在标签选择阶段,根据节点与自我网络中其他节点的相关程度选择标签,提高所发现社区的质量。

     

    引言

    COPRA算法能够适应当前大规模社会网络的社区发现工作[2],但是由于标签传播算法的随机性,导致多次运行结果会有较大程度的差异,且社区划分质量不高,甚至出现错误的社区划分。因此,本文针对现有基于标签传播思想的重叠社区发现算法存在的问题进行改进,提高社区划分精度和生成社区的质量。

     

    基于信息熵和局部相关性的多标签传播重叠社区发现算法(COPRA-EP

     

    2.1  COPRA-EP的算法描述

     

     

    2.2  COPRA-EP的预备知识及定义

    (1)   即为式(1)

                                            

    其中,L{v,N(v)}表示节点v及其邻居节点拥有的标签集合;N(v)表示节点v的邻居节点;p(l)表示标签l在集合中出现的概率

    注意:节点v的熵值[3]越小,该节点越可能处于社区内部;反之亦然。本文采用社区背部节点先于社区边缘节点进行更新的策略[4]。(可以避免由于随机更新序列带来的结果不稳定性以及错误的社区划分,也加快了迭代的收敛速度)

     

    (2)其中基于自我网络随机游走[5]获取节点v与其邻居节点相关性的LPR算法,其算法

    描述如下:

    最终的PR值表示为起始节点访问其他节点的概率,即起始节点与其他节点之间的局部相关性。计算公式如下:

                                        

    其中,PR(vu,v)表示节点vu与节点v的局部相关性;

              vu表示此次游走的起始点,v表示游走过程中停留的节点;

              D(v‘)表示节点v’的度数;

              α是继续随机游走的概率(一般取值为0.85)

    (3)

                             

     

     

    实验

    3.1 在基于LFR基准的网络上

                                     

           表1 两种人工网络图的参数设置

     

     

    结果如下:

                                                              

                                                                     图1 算法在LFR-5000上的NMI比较

                                                            

                                                                    2 算法在LFR-20000上的NMI比较

     

    由图1、图2可知,除了在挖掘混合参数mu值为0.2的LFR-20000的社区结构时,BMLPA算法[6]的准确度由于COPRA-EP之外,在其它数据集上,COPRE-EP算法在准确度上的表现均优于其他三个算法。

                                                               

                                                                    图3 算法在LFR-5000上的Qov比较

                                                                   

                                                                          图4 算法在LFR-20000上的Qov比较

     

    由图3、图4可知,当mu值较低时,不同社区之间的连边就少。导致社区边缘节点和社区内部节点的标签差异被弱化,不能很好的区分他们,所以算法中用到的更新序列并不能达到理想中的效果;随着mu值得增大,COPRA-EP算法的挖掘出来的社区质量均优于其他算法。

     

    3.2 在真实数据集上

                                           

                                                                         表2 数据集基本信息

     

                                            

                                                                   表3 算法在真实数据集上的NMI比较

    从表3中得知,在挖掘Karate和football数据集上,本文提出的COPRO-EP算法核BMLPA算法在准确性上相同,并且优于其他算法;而本文算法在挖掘Amazon的社区结构时的准确度优于其他算法。

                                             

                                                                     表4 算法在真实数据集上的Qov比较

     

     

    从表4中,可以看出本文算法得到的社区结构模块度值较高,表现较好。

    算法时间复杂度分析

                  在一个具有m条边,n个节点的社会网络中,节点的平均度数记为d

                  COPRA算法的时间复杂度为

                 因此COPRA-EP各阶段时间复杂度如下:

                                      与COPRA算法相同部分:

                                      计算所有节点熵值:

                                      根据熵值产生更新序列:O(n)

                                      计算所有节点的PR值:O(nd2

    • 所以COPRA-EP算法总的时间复杂度约为:O(γmlogγmn)

     

     

    参考文献

     

    [1]张昌理,王一蕾,吴英杰,苏斌勇,王晓东. 基于信息熵和局部相关性的多标签传播重叠社区发现算法[J]. 小型微型计算机系统,2016,37(08):1645-1650. [2017-09-28].

    [2] Gregory S. Finding overlapping communities in networks by label propagation[J]. New Journal of Physics,2010,12( 10) : 103018.

    [3] Zhao Y,Li S,Chen X. Community detection using label propagation in entropic order[C]. Computer and Information Technology ( CIT) ,2012 IEEE 12th International Conference on,IEEE,2012: 18-24.

    [4] Leung I X Y,Hui P,Lio P,et al. Towards real-time community detection in large networks[J]. Physical Review E,2009,79 ( 6) : 66-107.

    [5] Haveliwala T H. Topic-sensitive pagerank[C]. Proceedings of the 11th International Conference on World Wide Web,ACM,2002: 517-526.

    [6] Wu Z H,Lin Y F,Gregory S,et al. Balanced multi-label propagation for overlapping community detection in social networks[J]. Journal of Computer Science and Technology,2012,27 ( 3) : 468- 479.

     

    展开全文
  • 基于LFM的重叠社区发现算法python代码实现 import random import networkx as nx import matplotlib.pyplot as plt import zipfile #import urllib.request as urllib class Community(): ''' use set operation to...

    基于LFM的重叠社区发现算法python代码实现

    import random
    import networkx as nx
    import matplotlib.pyplot as plt
    import zipfile
    #import urllib.request as urllib
    class Community():
        ''' use set operation to optimize calculation '''
        
        def __init__(self,G,alpha=1.0):
            self._G = G
            self._alpha = alpha
            self._nodes = set()
            self._k_in = 0
            self._k_out = 0
        def add_node(self,node):
            neighbors = set(self._G.neighbors(node))
            #print("添加令居节点",neighbors , self._nodes,neighbors & self._nodes)
            node_k_in = len(neighbors & self._nodes)#neighbor和self._nodes公有节点的数目存入node_k_in
            #print("node_k_in",node_k_in)
            node_k_out = len(neighbors) - node_k_in
            #print("node_k_out",node_k_out)
            self._nodes.add(node)
            self._k_in += 2*node_k_in
            self._k_out = self._k_out+node_k_out-node_k_in
            
        def remove_node(self,node):
            neighbors = set(self._G.neighbors(node))
            community_nodes = self._nodes
            #print("community_nodes",community_nodes)
            node_k_in = len(neighbors & community_nodes)
            node_k_out = len(neighbors) - node_k_in
            self._nodes.remove(node)
            self._k_in -= 2*node_k_in
            self._k_out = self._k_out - node_k_out+node_k_in
            
        def cal_add_fitness(self,node):#fitness适应度
            neighbors = set(self._G.neighbors(node))
            old_k_in = self._k_in
            old_k_out = self._k_out
            vertex_k_in = len(neighbors & self._nodes)#vertex顶点
            vertex_k_out = len(neighbors) - vertex_k_in 
            new_k_in = old_k_in + 2*vertex_k_in
            new_k_out = old_k_out + vertex_k_out-vertex_k_in
            new_fitness = new_k_in/(new_k_in+new_k_out)**self._alpha#幂次
            old_fitness = old_k_in/(old_k_in+old_k_out)**self._alpha
            return new_fitness-old_fitness
        
        def cal_remove_fitness(self,node):
            neighbors = set(self._G.neighbors(node))
            new_k_in = self._k_in
            new_k_out = self._k_out
            node_k_in = len(neighbors & self._nodes)
            node_k_out = len(neighbors) - node_k_in
            old_k_in = new_k_in - 2*node_k_in
            old_k_out = new_k_out - node_k_out + node_k_in
            old_fitness = old_k_in/(old_k_in+old_k_out)**self._alpha 
            new_fitness = new_k_in/(new_k_in+new_k_out)**self._alpha
            return new_fitness-old_fitness
        
        def recalculate(self):
            for vid in self._nodes:
                fitness = self.cal_remove_fitness(vid)
                if fitness < 0.0:
                    return vid
            return None
        
        def get_neighbors(self):
            neighbors = set()
            for node in self._nodes:
                neighbors.update(set(self._G.neighbors(node)) - self._nodes)
            return neighbors
        
        def get_fitness(self):
            return float(self._k_in)/((self._k_in+self._k_out) ** self._alpha)
    
    class LFM():
        
        def __init__(self, G, alpha):
            self._G = G
            self._alpha = alpha
            
        def execute(self):
            communities = []
            print("嘿嘿",list(self._G.node.keys()))
            print("---------------------")
            node_not_include = list(self._G.node.keys())
            while(len(node_not_include) != 0):
                c = Community(self._G, self._alpha)
                #print("self._alpha",self._alpha)#0.9
                # randomly select a seed node
                seed = random.choice(node_not_include)
                c.add_node(seed)
                print("随机选取节点是:",seed)
                to_be_examined = c.get_neighbors()
                print("c.get_neighbors()",c.get_neighbors())
                while(to_be_examined):
                    #largest fitness to be added
                    m = {}
                    for node in to_be_examined:
                        fitness = c.cal_add_fitness(node)#计算点的适应度》0加入,小于0删除
                        m[node] = fitness
                    to_be_add = sorted(m.items(),key=lambda x:x[1],reverse = True)[0]#啥意思???
                     #适应度降序排列
                    #stop condition
                    if(to_be_add[1] < 0.0):
                        break
                    c.add_node(to_be_add[0])
                    to_be_remove = c.recalculate()
                    while(to_be_remove != None):
                        c.remove_node(to_be_remove)
                        to_be_remove = c.recalculate()
                        
                    to_be_examined = c.get_neighbors()
                                         
                for node in c._nodes:
                    if(node in node_not_include):
                        node_not_include.remove(node)
                communities.append(c._nodes)
            return communities
            
    if(__name__ == "__main__"):
          #G = nx.karate_club_graph()#一个边集一个点集
          # G = nx.florentine_families_graph()
          zf = zipfile.ZipFile('football.zip')  # zipfile object
          txt = zf.read('football.txt').decode()  # read info file
          gml = zf.read('football.gml').decode()  # read gml data
          # throw away bogus first line with # from mejn files
          gml = gml.split('\n')[1:]
          G = nx.parse_gml(gml)  # parse gml data
    
          print(txt)
          # print degree for each team - number of games
          for n, d in G.degree():
             print('%s %d' % (n, d))
    
          options = {
           'node_color': 'red',
           'node_size': 50,
           'line_color': 'grey',
           'linewidths': 0,
           'width': 0.1,
          }
          nx.draw(G, **options)
         #networkx.draw(G, with_labels=True)
          plt.show()
          algorithm = LFM(G,0.9)
          communities = algorithm.execute()
          for c in communities:
              print (len(c),sorted(c))
    

    社区网络:
    初步社区网络结构图
    重叠社区划分结果:
    社区划分结果

    展开全文
  • 针对以上问题,提出一种基于最大团的层次化重叠社区发现算法。该算法以最大团为扩展对象,然后利用最大团扩展策略生成层次树图,最后采用重叠模块度函数对层次树图进行剪枝得到社区划分结果。在真实网络以及LFR人工...
  • LFM算法是来源于论文《Detecting the overlapping and hieerarchical community structure in complex networks》,文档中包含该算法的python的源码,以及用到的数据集,仅供大家学习参考。
  • 行业分类-作业装置-一种基于多标签传播的半监督重叠社区发现算法.7z
  • COPRA算法对RAK算法的最大改进在于其可以进行重叠社区发现,而RAK算法只能用于非重叠社区发现。 COPRA算法 COPRA算法在执行之初会为网络中每一个节点设置一个唯一的社区编号,一般这个社区编号就是节点的...

    前言

    COPRA算法[1]是Gregory在2010年提出的一种基于标签传递的社区发现算法,该算法可以看作是RAK算法[2]的改进算法。COPRA算法对RAK算法的最大改进在于其可以进行重叠社区的发现,而RAK算法只能用于非重叠社区的发现。

    COPRA算法

    COPRA算法在执行之初会为网络中每一个节点设置一个唯一的社区编号,一般这个社区编号就是节点的自身的ID;之后,节点会根据自己的邻居节点的社区分布决定自己的社区,简单的来说就是自己的邻居节点倾向于选择哪个社区,自己就选择哪个社区。算法在执行时会使用隶属度(Belonging Coefficient)来帮助节点决定选择哪一个社区。如果节点对于邻居节点所在社区的隶属度都低于阈值,那么节点就随机选择一个社区;最后,算法会根据一些条件来决定是否停止算法。停止条件一般分为两种:第一种是连续两次迭代社区标签数量相同;第二种是连续两次迭代社区内节点数目不变。伪代码如下:

    输入:图graph(V,E),K
    输出:节点的社区信息partition
    1: 为每一个节点设置唯一的社区标签
    2: 在没有达到终止条件前,对每一个节点重复执行:
    3:     更新节点对其邻居节点所在社区的隶属度bc
    4:     如果 bc < 1/K5:         排除社区标签
    6:     如果所有社区标签 bc < 1/K :
    7:         随机选取一个社区标签

    Java代码

    建立图

    图的数据结构选取了邻接表

    package util;
    
    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.util.*;
    
    public class Graph {
        /**
         * 图数据结构:邻接表
         * */
        private Map<String, ArrayList<String>> adjT;
        /**
         * 节点属性列表,维护节点的id和社区信息
         * */
        private Map<String, HashSet<String>> nodeCommunityInfoPast = new HashMap<>();
        private Map<String, HashSet<String>> nodeCommunityInfoNew = new HashMap<>();
    
        public Graph(){
            this.adjT = new HashMap<>();
        }
    
        public Graph(String edgePath){
            this.adjT = new HashMap<String, ArrayList<String>>();
            try{
                BufferedReader reader = new BufferedReader(new FileReader(edgePath));
                String line = null;
                while((line=reader.readLine())!=null){
                    String item[] = line.split(",");//CSV格式文件为逗号分隔符文件,这里根据逗号切分
    //                System.out.println(item[1]);
    
                    if (! this.adjT.containsKey(item[0])){
                        this.adjT.put(item[0], new ArrayList<>());
                        this.nodeCommunityInfoNew.put(item[0], new HashSet<>());
                    }
                    if (! this.adjT.containsKey(item[1])){
                        this.adjT.put(item[1], new ArrayList<>());
                        this.nodeCommunityInfoNew.put(item[1], new HashSet<>());
                    }
    
                    if (! this.adjT.get(item[0]).contains(item[1])){
                        this.adjT.get(item[0]).add(item[1]);
                    }
                    if (! this.adjT.get(item[1]).contains(item[0])){
                        this.adjT.get(item[1]).add(item[0]);
                    }
    
                }
            }catch(Exception e){
                e.printStackTrace();
            }
    
        }
    
        /**
         * 判断节点之间是否有边
         * */
        public boolean hasEdge(String v, String w){
            return this.adjT.get(v).contains(w);
        }
    
        /**
         * 获取节点的邻居节点
         * */
        public ArrayList<String> neighbors(String node){
            return this.adjT.get(node);
        }
    
        /**
         * 获取网络中的所有节点
         * */
        public Iterable<String> nodes(){
            return this.adjT.keySet();
        }
    
        /**
         * 获取所有节点的社区信息
         * */
        public Map<String, HashSet<String>> getNodeCommunityInfo() {
            return this.nodeCommunityInfoPast;
        }
    
        /**
         * 获取节点的社区信息
         * */
        public HashSet<String> getCommnityLabel(String node){
            return this.nodeCommunityInfoPast.get(node);
        }
    
        /**
         * 更新节点的社区信息
         * */
        public void updateNodeCommunityLabel(String node, String cLabel){
            this.nodeCommunityInfoNew.get(node).add(cLabel);
        }
    
        /**
         * 在社区信息一轮更新完成后,将原始的社区信息进行覆盖
         * */
        public void coverCommunityInfo(){
            this.nodeCommunityInfoPast.clear();
            for (Map.Entry<String, HashSet<String>> entry : this.nodeCommunityInfoNew.entrySet()){
                nodeCommunityInfoPast.put(entry.getKey(), new HashSet<>(entry.getValue()));
            }
            for (Map.Entry<String, HashSet<String>> entry : this.nodeCommunityInfoNew.entrySet()){
                entry.getValue().clear();
            }
        }
    
    }
    

    使用COPRA算法进行社区发现

    由于在项目中要处理的网络规模非常的巨大,所以算法的终止条件设置为“当连续两次迭代的社区数量不发生变化时,停止算法”。当然这样的设置并不能保证算法真正的收敛。如果网络规模较小,可以将算法的终止条件设置为“在连续两次迭代中,各个社区规模不发生变化时,停止算法”,但是这样做迭代过程会非常的长。

    package community;
    
    import util.Graph;
    import java.util.*;
    
    public class COPRA {
    
        public static List<String> getRandomList(List<String> paramList,int count){
            /**
             * @function: 从list中随机抽取若干不重复元素
             * @param paramList:被抽取list
             * @param count:抽取元素的个数
             * @return: 由抽取元素组成的新list
             * */
            if(paramList.size()<count){
                return paramList;
            }
            Random random=new Random();
            List<Integer> tempList=new ArrayList<Integer>();
            List<String> newList=new ArrayList<>();
            int temp=0;
            for(int i=0;i<count;i++){
                temp=random.nextInt(paramList.size());//将产生的随机数作为被抽list的索引
                if(!tempList.contains(temp)){
                    tempList.add(temp);
                    newList.add(paramList.get(temp));
                }
                else{
                    i--;
                }
            }
            return newList;
        }
    
        public Map<String, HashSet<String>> divide_community(Graph graph, int v, int maxIterations){
            /**
             * @function: 使用COPRA算法划分社区
             * @graph :图
             * @v :一个节点可以属于的最大社区数
             * @maxIteration :最大迭代次数
             * */
    
            /**
             * 初始,为每一个节点附上唯一的社区编号
             * */
            Iterable nodes = graph.nodes();
            for (Object id : nodes){
                graph.updateNodeCommunityLabel((String)id, (String)id);
            }
            graph.coverCommunityInfo();
    
            Random random = new Random();
            /**
             * 更新节点社区信息
             * */
            int interations = 0;
            Map<String, Integer> communitySizePast = new HashMap<>();
            Map<String, Integer> communitySizeNow = new HashMap<>();
            Integer flag = 0;
            while (interations < maxIterations){
                for (Object id : nodes){
                    /**
                     * 统计节点的邻居节点的社区分布
                     * */
                    Map<String, Integer> labels_freq = new HashMap<>();
                    ArrayList<String> neighbors = graph.neighbors((String)id);
                    for (String n : neighbors){
                        HashSet<String> n_labels = graph.getCommnityLabel(n);
                        for (String label : n_labels){
                            if (labels_freq.keySet().contains(label)){
                                labels_freq.put(label, labels_freq.get(label) + 1);
                            }else{
                                labels_freq.put(label, 1);
                            }
                        }
                    }
    
                    int temp_count = 0;
                    List<String> label_list = new ArrayList<>();
                    List<String> label_list_add = new ArrayList<>();
                    /**
                     * 计算节点与社区的隶属度
                     * 节点将被分配隶属度大于阈值的社区标签
                     * */
                    for (Map.Entry<String, Integer> entry : labels_freq.entrySet()){
    
                        if (entry.getValue() / (float)neighbors.size() >= 1 / (float)v) { //
                            temp_count += 1;
                            label_list.add(entry.getKey());
    //                        graph.updateNodeCommunityLabel((String)id, entry.getKey());
                        }
                    }
                    // 隶属度大于阈值的社区数量超过v,则随机选取v个隶属度大于阈值的社区
                    if (temp_count >= v){
                        label_list_add = getRandomList(label_list, v);
                        for (String l : label_list_add){
                            graph.updateNodeCommunityLabel((String)id, l);
                        }
                    //隶属度大于阈值的社区数量不超过v,则选取所有的隶属度大于阈值的社区
                    }else if (temp_count > 0){
                        for (String l : label_list){
                            graph.updateNodeCommunityLabel((String)id, l);
                        }
                    }
                    //节点对于每一个社区的隶属度都低于阈值,随机选择一个社区
                    if (temp_count == 0){
                        int maxNum = labels_freq.keySet().size();
                        int index = random.nextInt(maxNum)%(maxNum+1);
                        List<String> labels_list = new ArrayList<>(labels_freq.keySet());
                        graph.updateNodeCommunityLabel((String)id, labels_list.get(index));
                    }
                }
                graph.coverCommunityInfo();
                interations += 1;
    
                /**
                 * 前后两次社区的数量不变,则停止算法
                 * */
                Map<String, HashSet<String>> partitions = graph.getNodeCommunityInfo();
                for (Map.Entry<String, HashSet<String>> entry : partitions.entrySet()){
                    for (String label : entry.getValue()){
                        if (communitySizeNow.containsKey(label)){
                            communitySizeNow.put(label, communitySizeNow.get(label) + 1);
                        }else{
                            communitySizeNow.put(label, 1);
                        }
                    }
                }
    
                Integer community_num_now = communitySizeNow.keySet().size();
                Integer community_num_past = communitySizePast.keySet().size();
                if (community_num_now.equals(community_num_past)){
                    flag = 1;
                }
    
                // 社区数量不变,停止迭代
                if (flag.equals(1)){
                    interations = maxIterations;
                }
                // 更新过去的社区信息,清空当前的社区信息
                communitySizePast.clear();
                for (Map.Entry<String, Integer> entry : communitySizeNow.entrySet()){
                    communitySizePast.put(entry.getKey(), new Integer(entry.getValue()));
                }
                communitySizeNow.clear();
            }
    
            return graph.getNodeCommunityInfo();
        }
    }

    执行社区发现

    程序的输入格式为csv格式,数据以边的形式组织,比如:

    a,b
    a,d
    a,e
    a,g
    b,d
    b,c
    c,d
    e,g
    e,f
    f,g

    test.csv中的图就是文献[1]中的例子。在运行程序前,设置K为2,即节点最多可以属于两个社区;最大迭代次数为10000。
    这里写图片描述

    import community.COPRA;
    import util.Graph;
    import java.io.IOException;
    import java.util.*;
    
    
    public class Main {
        public static void main(String[] args) throws IOException {
            Graph graph = new Graph("./data/test.csv");
            COPRA copra = new COPRA();
            Map<String, HashSet<String>> partitions = copra.divide_community(graph, 2, 10000);
            System.out.println(partitions);
    
            /**
             * 统计社区数量
             * */
            Set<String> community = new HashSet<>();
            for (Map.Entry<String, HashSet<String>> entry : partitions.entrySet()){
                community.addAll(entry.getValue());
            }
            System.out.println("社区数量: " + community.size());
        }
    }

    程序执行后,得到的结果为:

    {a=[b, g], b=[b], c=[b], d=[b], e=[g], f=[g], g=[g]}
    社区数量: 2

    但是该算法也具有明显的缺陷:随机性太强。几乎每一次的社区发现结果都不相同,以上的结果是正确的输出,但是这个输出是执行多次才得到的,中间很多次的社区发现结果都是错误的。在这个过程中,我也使用了第二种算法终止条件,使用该终止条件后,算法输出的结果明显可靠多了,但是因为要划分的网络过于庞大,只能选择第一种终止条件。当然,出现这种状况的原因也可能是我的程序中存在Bug,欢迎大家指正!

    引用

    [1]Gregory S. Finding overlapping communities in networks by label propagation[J]. New Journal of Physics, 2009, 12(10):2011-2024.
    [2]Raghavan U N, Albert R, Kumara S. Near linear time algorithm to detect community structures in large-scale networks[J]. Physical Review E Statistical Nonlinear & Soft Matter Physics, 2007, 76(2):036106.

    展开全文
  • 上,少数情况下,初始节点的不同会导致算法最终结果的不同,即使算法的结果不依赖于研究表明,很多真实网络具有层次结构和重叠结构。传统的层次聚类算法通常以节点为对象进行扩展形成 层次树图从而得到网络的层次...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,365
精华内容 2,146
关键字:

重叠社区发现算法