Python案例如何用Networkx做社区发现

wen python案例 1

本文目录导读:

Python案例如何用Networkx做社区发现

  1. 安装所需库
  2. 基础案例:使用Girvan-Newman算法
  3. 使用Louvain算法(推荐)
  4. 使用Label Propagation算法
  5. 实战案例:社交网络分析
  6. 性能评估与比较

我来为您介绍使用NetworkX进行社区发现的几种常见方法:

安装所需库

pip install networkx
pip install python-louvain  # 用于Louvain算法
pip install community       # 社区检测工具包

基础案例:使用Girvan-Newman算法

import networkx as nx
from networkx.algorithms.community import girvan_newman
import matplotlib.pyplot as plt
# 创建示例图
G = nx.karate_club_graph()  # 使用经典的Zachary空手道俱乐部图
# 应用Girvan-Newman算法
communities = girvan_newman(G)
first_level = next(communities)  # 获取第一层划分
# 可视化结果
def plot_communities(G, communities):
    pos = nx.spring_layout(G, seed=42)
    colors = ['red', 'blue', 'green', 'yellow', 'purple', 'orange']
    for i, community in enumerate(communities):
        nx.draw_networkx_nodes(G, pos, 
                             nodelist=list(community),
                             node_color=colors[i % len(colors)],
                             node_size=100,
                             label=f'社区 {i+1}')
    nx.draw_networkx_edges(G, pos, alpha=0.5)
    nx.draw_networkx_labels(G, pos, font_size=8)
    plt.legend()
    plt.title("Girvan-Newman社区发现")
    plt.axis('off')
    plt.show()
plot_communities(G, first_level)
print(f"发现的社区数量: {len(first_level)}")
for i, community in enumerate(first_level):
    print(f"社区 {i+1}: {sorted(community)}")

使用Louvain算法(推荐)

import networkx as nx
import community as community_louvain
import matplotlib.pyplot as plt
# 创建复杂网络
G = nx.karate_club_graph()
# 应用Louvain算法
partition = community_louvain.best_partition(G)
# 可视化
def plot_louvain_partition(G, partition):
    pos = nx.spring_layout(G, seed=42)
    # 为每个节点分配颜色
    colors = [partition[node] for node in G.nodes()]
    plt.figure(figsize=(10, 8))
    nx.draw(G, pos, 
            node_color=colors,
            node_size=100,
            cmap=plt.cm.Set1,
            with_labels=True,
            font_size=8,
            font_color='white')
    plt.title("Louvain社区发现")
    plt.show()
plot_louvain_partition(G, partition)
# 打印社区信息
print("\n社区划分结果:")
for com in set(partition.values()):
    members = [node for node in partition.keys() if partition[node] == com]
    print(f"社区 {com}: {members}")
# 计算模块度
modularity = community_louvain.modularity(partition, G)
print(f"\n模块度: {modularity}")

使用Label Propagation算法

import networkx as nx
from networkx.algorithms.community import label_propagation_communities
import matplotlib.pyplot as plt
# 创建图
G = nx.karate_club_graph()
# 应用Label Propagation算法
communities = list(label_propagation_communities(G))
# 可视化
def plot_label_propagation(G, communities):
    pos = nx.spring_layout(G, seed=42)
    colors = ['red', 'blue', 'green', 'yellow', 'purple']
    plt.figure(figsize=(10, 8))
    # 为每个社区分配颜色
    node_colors = {}
    for i, community in enumerate(communities):
        for node in community:
            node_colors[node] = colors[i % len(colors)]
    nx.draw(G, pos,
            node_color=[node_colors[node] for node in G.nodes()],
            node_size=100,
            with_labels=True,
            font_size=8)
    plt.title("Label Propagation社区发现")
    plt.show()
plot_label_propagation(G, communities)
print(f"\n发现的社区数量: {len(communities)}")
for i, community in enumerate(communities):
    print(f"社区 {i+1}: {sorted(community)}")

实战案例:社交网络分析

import networkx as nx
import community as community_louvain
import matplotlib.pyplot as plt
import numpy as np
# 创建模拟社交网络
def create_social_network():
    G = nx.Graph()
    # 添加用户节点
    users = ['Alice', 'Bob', 'Charlie', 'David', 'Eve', 'Frank',
             'Grace', 'Henry', 'Ivy', 'Jack', 'Kate', 'Leo',
             'Mary', 'Nick', 'Olivia', 'Paul']
    G.add_nodes_from(users)
    # 添加社交关系(边)
    edges = [
        # 社区1:科技圈
        ('Alice', 'Bob'), ('Alice', 'Charlie'), ('Bob', 'Charlie'),
        ('Bob', 'David'), ('Charlie', 'David'), ('David', 'Eve'),
        # 社区2:艺术圈
        ('Frank', 'Grace'), ('Frank', 'Henry'), ('Grace', 'Henry'),
        ('Grace', 'Ivy'), ('Henry', 'Ivy'), ('Ivy', 'Jack'),
        # 社区3:体育圈
        ('Kate', 'Leo'), ('Kate', 'Mary'), ('Leo', 'Mary'),
        ('Leo', 'Nick'), ('Mary', 'Nick'), ('Nick', 'Olivia'),
        # 跨社区连接
        ('Alice', 'Frank'), ('Charlie', 'Kate'), ('David', 'Paul'),
        ('Grace', 'Leo'), ('Ivy', 'Mary'), ('Paul', 'Olivia')
    ]
    G.add_edges_from(edges)
    return G
# 主函数
def analyze_social_network():
    # 创建网络
    G = create_social_network()
    print(f"节点数量: {G.number_of_nodes()}")
    print(f"边数量: {G.number_of_edges()}")
    # 社区发现
    partition = community_louvain.best_partition(G)
    communities = {}
    for node, com_id in partition.items():
        if com_id not in communities:
            communities[com_id] = []
        communities[com_id].append(node)
    # 结果分析
    print(f"\n发现的社区数量: {len(communities)}")
    print("\n社区构成:")
    for com_id, members in communities.items():
        print(f"社区 {com_id}: {members}")
    # 计算网络指标
    modularity = community_louvain.modularity(partition, G)
    print(f"\n模块度: {modularity:.3f}")
    # 可视化
    pos = nx.spring_layout(G, seed=42)
    plt.figure(figsize=(12, 8))
    # 绘制社区
    colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4']
    for com_id in communities:
        nodes = communities[com_id]
        nx.draw_networkx_nodes(G, pos, 
                             nodelist=nodes,
                             node_color=colors[com_id % len(colors)],
                             node_size=300,
                             label=f'社区 {com_id}')
    nx.draw_networkx_edges(G, pos, alpha=0.5, width=1.5)
    nx.draw_networkx_labels(G, pos, font_size=10, font_color='white')
    plt.title(f"社交网络社区发现 (模块度: {modularity:.3f})")
    plt.legend()
    plt.axis('off')
    plt.tight_layout()
    plt.show()
    return G, partition
# 运行分析
G, partition = analyze_social_network()

性能评估与比较

import networkx as nx
from networkx.algorithms.community import girvan_newman, label_propagation_communities
import community as community_louvain
import time
def compare_algorithms(G):
    algorithms = {}
    # Girvan-Newman
    start = time.time()
    communities = girvan_newman(G)
    first_level = next(communities)
    algorithms['Girvan-Newman'] = {
        'time': time.time() - start,
        'communities': first_level
    }
    # Louvain
    start = time.time()
    partition = community_louvain.best_partition(G)
    algorithms['Louvain'] = {
        'time': time.time() - start,
        'partition': partition
    }
    # Label Propagation
    start = time.time()
    communities_lp = list(label_propagation_communities(G))
    algorithms['Label Propagation'] = {
        'time': time.time() - start,
        'communities': communities_lp
    }
    # 打印比较结果
    print("算法性能比较:")
    print("-" * 50)
    for name, data in algorithms.items():
        print(f"\n{name}:")
        print(f"  运行时间: {data['time']:.4f} 秒")
        if 'communities' in data:
            print(f"  社区数量: {len(data['communities'])}")
        else:
            print(f"  社区数量: {len(set(data['partition'].values()))}")
# 使用较大的图进行测试
G = nx.karate_club_graph()
compare_algorithms(G)
  1. Louvain算法:速度最快,适合大型网络
  2. Girvan-Newman:理论基础好,但计算复杂度高
  3. Label Propagation:简单高效,但结果可能不稳定
  4. 模块度:用于评估社区划分质量的指标

这些案例展示了NetworkX社区发现的基本用法,您可以根据实际需求选择适合的算法。

抱歉,评论功能暂时关闭!