本文目录导读:

我来为您介绍使用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)
- Louvain算法:速度最快,适合大型网络
- Girvan-Newman:理论基础好,但计算复杂度高
- Label Propagation:简单高效,但结果可能不稳定
- 模块度:用于评估社区划分质量的指标
这些案例展示了NetworkX社区发现的基本用法,您可以根据实际需求选择适合的算法。