生物医学网络科学Biomedical Network Science
Example02 / 13

社团检测与已知分组的一致性

所属专题
结果呈现与研究前沿
下载
Notebook · .py

用 Louvain(seed=0)划分空手道网络并计算模块度 Q,再统计每个社团中两派成员各有多少。 解读:若社团几乎不跨派混合,说明拓扑划分与已知的社会分裂一致; 社团数多于两派时,表示算法把某一派进一步细分,这本身不意味着划分错误。

Output输出图

社团检测与已知分组的一致性:输出图 1

Output文字输出

社团数 = 4,Q = 0.444
社团0: 大小 11,Mr. Hi 派 11 人,Officer 派 0 人
社团1: 大小 5,Mr. Hi 派 5 人,Officer 派 0 人
社团2: 大小 14,Mr. Hi 派 1 人,Officer 派 13 人
社团3: 大小 4,Mr. Hi 派 0 人,Officer 派 4 人

Code代码

# 用 Louvain(seed=0)划分空手道网络并计算模块度 Q,再统计每个社团中两派成员各有多少。
# 解读:若社团几乎不跨派混合,说明拓扑划分与已知的社会分裂一致;
# 社团数多于两派时,表示算法把某一派进一步细分,这本身不意味着划分错误。
import networkx as nx

G = nx.karate_club_graph()
comms = nx.community.louvain_communities(G, seed=0)
Q = nx.community.modularity(G, comms)
print(f"社团数 = {len(comms)},Q = {Q:.3f}")
for i, c in enumerate(comms):
    hi = sum(1 for v in c if G.nodes[v]["club"] == "Mr. Hi")
    print(f"社团{i}: 大小 {len(c)},Mr. Hi 派 {hi} 人,Officer 派 {len(c) - hi} 人")

# 作图:颜色 = Louvain 社团,形状 = 实际所属派别(圆 = Mr. Hi,方 = Officer)
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(6.4, 4.2))
pos = nx.spring_layout(G, seed=3)
lab = {v: i for i, c in enumerate(comms) for v in c}
nx.draw_networkx_edges(G, pos, ax=ax, edge_color="0.6", alpha=0.4)
for club, shape in [("Mr. Hi", "o"), ("Officer", "s")]:
    vs = [v for v in G if G.nodes[v]["club"] == club]
    nx.draw_networkx_nodes(G, pos, nodelist=vs, ax=ax, node_shape=shape, node_size=90,
                           node_color=[lab[v] for v in vs], cmap="tab10", vmin=0, vmax=9)
ax.set_title(f"Louvain communities (color) vs actual factions (shape), Q = {Q:.2f}", fontsize=10); ax.axis("off")
plt.tight_layout(); plt.show()

Run在浏览器中运行

首次加载 Python 环境约需 20–40 秒;可以修改参数后重新运行。

社团检测与已知分组的一致性