KL社区发现算法概述与源码

本文在实现KL算法的过程中实现了社区划分结果,同时实现了不同社区的可视化结果。


GN社区发现算法传送门


author:xiao黄
缓慢而坚定的生长
公众号:Community Detection
本人更新在csdn关于社区发现(Community Detection)方面的知识会同步更新到公众号中。


KL算法介绍

Kernighan-Lin算法是一种试探优化的方法,其基本的思想是为网络引入一个试探函数Q,Q代表某两个准社团内部的边数减去两个准社团之间的边数的差值,然后得到使Q值最大的划分方法。

首先将整个网络的节点随机的或根据网络的现有信息分为两个部分,在两个社团之间考虑所有可能的节点对,试探交换每对节点并计算交换后的ΔQ,ΔQ=Q交换后-Q交换前,记录ΔQ最大的交换节点对,并将这两个节点互换,记录此时的Q值。规定每个节点只能交换一次,重复这个过程直至网络中的所有节点都被交换一次为止。需要注意的是不能在Q值发生下降时就停止,因为Q值不是单调增加的,既使某一步交换会使Q值有所下降,但其后的一步交换可能会出现一个更大的Q值。在所有的节点都交换过之后,对应Q值最大的社团结构即被认为是该网络的理想社团结构。

KL算法是将网络分成两个指定规模大小的社区。

算法参数介绍

kernighan_lin_bisection(G, partition=None, max_iter=10, weight=‘weight’, seed=None)
G:图
partition:(元组格式)一对包含初始分区的iterables。如果未指定,则使用随机平衡分区。
max_iter:尝试交换在放弃前找到改进的最大次数。
weight:权重。如果没有,则所有权重都设置为1。
seed:随机数生成状态的指示器。
return:表示两个社区的一对节点。
返回类型:tuple(元组)

代码

import networkx as nx
import matplotlib.pyplot as plt
from networkx.algorithms import community  
from networkx.algorithms.community import kernighan_lin_bisection



def draw_spring(G,com):
    '''
    G:图
    com:划分好的社区
    node_size表示节点大小
    node_color表示节点颜色
    node_shape表示节点形状
    with_labels=True表示节点是否带标签
    '''
    pos = nx.spring_layout(G) # 节点的布局为spring型
    NodeId = list(G.nodes())
    node_size = [G.degree(i)**1.2*90 for i in NodeId] # 节点大小

    plt.figure(figsize = (8,6)) # 图片大小
    nx.draw(G,pos, with_labels=True, node_size =node_size, node_color='w', node_shape = '.')
    
    color_list = ['pink','orange','r','g','b','y','m','gray','black','c','brown']
    # node_shape = ['s','o','H','D']

    for i in range(len(com)):
        nx.draw_networkx_nodes(G, pos, nodelist=com[i], node_color=color_list[i],  with_labels=True)
    plt.show()

if __name__ == "__main__":
    G = nx.karate_club_graph() # 空手道俱乐部

    # KL算法
    com = list(kernighan_lin_bisection(G))
    print('社区数量', len(com))
    print(com)
    draw_spring(G,com)

结果:
这就是KL算法划分的结果,分为两个社区,用不同的颜色表示出来。
可以用print(com)语句查看划分后社区中的节点。
在这里插入图片描述
参考文献:Kernighan B W, Lin S. A efficient heuristic procedure for partitioning graphs. Bell System Technical Journal, 1970 (49): 291-307.
论文地址:传送门

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
KL信息与FCM算法都是聚类算法,但它们的实现方式有所不同。以下是KL信息与FCM算法的MATLAB程序示例。 KL信息聚类算法: ```matlab % 数据准备 data = [1.2 2.0; 1.4 1.6; 1.6 1.2; 2.0 1.4; 3.0 3.0; 3.2 2.6; 3.6 2.0; 4.0 3.0]; % 初始化中心点 center = [1.2 2.0; 4.0 3.0]; % 设置聚类个数 k = 2; % 迭代次数 iter_num = 10; for iter = 1:iter_num % 计算数据点与中心点之间的KL散度 D = pdist2(data, center, 'KL'); % 使用KL散度进行聚类 [~, label] = min(D, [], 2); % 更新中心点 for i = 1:k center(i, :) = mean(data(label == i, :)); end end % 绘制聚类结果 figure; scatter(data(label == 1, 1), data(label == 1, 2), 'r'); hold on; scatter(data(label == 2, 1), data(label == 2, 2), 'b'); scatter(center(:, 1), center(:, 2), 100, 'k', 'filled'); ``` FCM聚类算法: ```matlab % 数据准备 data = [1.2 2.0; 1.4 1.6; 1.6 1.2; 2.0 1.4; 3.0 3.0; 3.2 2.6; 3.6 2.0; 4.0 3.0]; % 设置聚类个数 k = 2; % 迭代次数 iter_num = 10; % 初始化隶属度矩阵 U = rand(k, size(data, 1)); U = bsxfun(@rdivide, U, sum(U, 1)); for iter = 1:iter_num % 更新聚类中心点 center = (U.^2 * data) ./ sum(U.^2, 2); % 计算隶属度矩阵 D = pdist2(data, center, 'euclidean'); U = bsxfun(@rdivide, 1./D, sum(1./D, 2)); % 控制隶属度矩阵的范围 U = max(U, eps); U = bsxfun(@rdivide, U, sum(U, 1)); end % 计算聚类标签 [~, label] = max(U, [], 1); % 绘制聚类结果 figure; scatter(data(label == 1, 1), data(label == 1, 2), 'r'); hold on; scatter(data(label == 2, 1), data(label == 2, 2), 'b'); scatter(center(:, 1), center(:, 2), 100, 'k', 'filled'); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiao黄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值