社区发现算法——COPRA算法

COPRA算法是基于LPA的社区检测算法,解决了稳定性差和无法处理重叠社区的问题。它引入了从属系数(c,b),允许节点同时属于多个社区。在每次迭代中,节点的标签由邻居节点的标签加权平均得到,并根据阈值删除低隶属度的社区信息。Dolphin数据集的实验表明,尽管COPRA仍存在不确定性,但其模块化效果通常优于其他算法。代码实现中展示了COPRA的执行过程,包括初始化、标签传播和社区构建步骤。
摘要由CSDN通过智能技术生成

COPRA算法

LPA 算法简单直观 ,易于理解。而且求解准确性很高(指的是运气好的时候,毕竟随机性太大了hh)无需指定社区个数等其他任何参数.最主要是算法时间复杂度很低.接近线性但是 LPA 算法存在两个问题 :

  • 第一,其稳定性较差,原因是社区间标签易传播 ,当一个节点存在多个可选标签时.随机地选择其中一个 . 对于不同的随机选择会产生不同的社区发现结果
  • 第二 ,在现实生活中,很多节点可能同时属于多个标签 .而 LPA 算法是无法挖掘出重叠社区结构的.

对此,基于LPA算法,引入了新的标签结构(c,b),其中,c表示社区标识符(它可能属于哪个社区),b表示节点x在社区c中的从属系数(它属于该社区的可能性),且0≤b≤1。顶点x的所有从属系数之和等于1,通过 b t b_t bt(c,b)表示迭代次数t时的顶点x对于社区c的从属系数,N(x)表示顶点x的邻接顶点集。具体计算公式为:

b t ( c , x ) = ∑ y ∈ N ( x ) b t − 1 ( c , y ) ∣ N ( x ) ∣ b_t(c,x) = {{\displaystyle \sum_{y\in N(x)}b_{t-1}(c,y)}\over{|N(x)|}} bt(c,x)=N(x)yN(x)bt1(c,y)

每次传播过程都是将邻居节点的归属系数取并集进行归一化。

其中,N(x)是节点x的所有邻居节点。t是迭代次数。该公式的意义是计算x节点所有邻居节点属于c社区的隶属度之和与邻居节点数的比值。

迭代t中一个顶点的标签总是基于迭代t−1中它相邻的标签。

因为我们需要一个节点保存多个社区标识符信息,而不是所有的社区标识符信息。所以我们会删除那些低于阈值1/v的社区信息,v是超参数,表示一个节点最多可以属于几个社区。

从标签向量中删除社区对之后,将剩余的隶属度进行归一化(分别乘(除)以一个常数,使其之和为1)。

在这里插入图片描述

假设v为2,故阈值为1/v=0.5,低于此阈值的标签信息都会被删除,如果一个节点中所有的标签都低于此阈值就随机选择一个。删除标签后的网络信息为:
比如上图节点b三个从属系数都为1/3,都小于阈值1/2,所以都删除,并且随机选择一个,这里假如选择了c,然后归一化,从属系数为1,b的标签变为(c,1)。
对于节点c,从属系数都为1/2大于阈值,都合格,按公式计算{(c,1)+(c,1)}/2 所以结果为{(c,1}.
其它节点也类似,然后网络信息就变成了下图。

在这里插入图片描述

对于v<2时,COPRA算法就变成了LPA算法。

与LPA算法一样,COPRA可能具有高度的不确定性,一个顶点的社区通常是由随机选择决定的。然而,在真实的网络中,COPRA通常比其他测试算法产生更好的结果(就模块化而言)。

算法流程如下:

在这里插入图片描述

评价指标:扩展Q函数

在这里插入图片描述

Dolphin 数据集是 D.Lusseau 等人使用长达 7 年的时间观察新西兰 Doubtful Sound海峡 62 只海豚群体的交流情况而得到的海豚社会关系网络。这个网络具有 62 个节点,159 条边。节点表示海豚,而边表示海豚间的频繁接触

代码与数据下载github

Python代码如下:

class COPRA:
    def __init__(self, G, T, v):
        """
        :param G:图本身
        :param T: 迭代次数T
        :param r:满足社区次数要求的阈值r
        """
        self._G = G
        self._n = len(G.nodes(False))  # 节点数目
        self._T = T
        self._v = v

    def execute(self):
        # 建立成员标签记录
        # 节点将被分配隶属度大于阈值的社区标签
        lablelist = {i: {i: 1} for i in self._G.nodes()}
        for t in range(self._T):
            visitlist = list(self._G.nodes())
            # 随机排列遍历顺序
            np.random.shuffle(visitlist)
            # 开始遍历节点
            for visit in visitlist:
                temp_count = 0
                temp_label = {}
                total = len(self._G[visit])
                # 根据邻居利用公式计算标签
                for i in self._G.neighbors(visit):
                    res = {key: value / total for key, value in lablelist[i].items()}
                    temp_label = dict(Counter(res) + Counter(temp_label))
                temp_count = len(temp_label)
                temp_label2 = temp_label.copy()
                for key, value in list(temp_label.items()):
                    if value < 1 / self._v:
                        del temp_label[key]
                        temp_count -= 1
                # 如果一个节点中所有的标签都低于阈值就随机选择一个
                if temp_count == 0:
                    b = random.sample(temp_label2.keys(), 1)
                    temp_label = {b[0]: 1}
                # 否则标签个数一定小于等于v个 进行归一化即可
                else:
                    tsum = sum(temp_label.values())
                    temp_label = {key: value / tsum for key, value in temp_label.items()}
                lablelist[visit] = temp_label

        communities = collections.defaultdict(lambda: list())
        # 扫描lablelist中的记录标签,相同标签的节点加入同一个社区中
        for primary, change in lablelist.items():
            for label in change.keys():
                communities[label].append(primary)
        # 返回值是个数据字典,value以集合的形式存在
        return communities.values()```

参考结果:
>D:\anaconda3\python.exe D:/APTX-4869/CommunityDetection/CORPA.py
0 [0, 40, 10, 14, 47, 15, 42, 36, 28, 2, 44, 61, 3, 8, 59, 4, 51, 30, 37, 45, 20, 29, 11, 12, 33, 34, 38, 43, 16, 50, 52, 24, 18, 55, 21, 23, 35, 49, 39, 58, 46, 53]
1 [1, 41, 17, 19, 54, 26, 27, 5, 56, 9, 13, 57, 6, 7, 30, 32, 22, 25, 31, 60, 39, 48]
2 [4, 51, 11, 24, 55, 21, 23, 35]
0.3655
算法执行时间0.028006553649902344
  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值