模块识别的常用方法
🧠 学习目标:理解模块识别(社区检测)的核心思想与数学原理
🔬 任务场景:在构建好的细胞图(节点为细胞群,边表示相关性)中,自动识别高度内聚、外部联系稀疏的群体 —— 即“模块”或“社区”。
🔍 一、背景导入:什么是“模块识别”?
🧩 场景举例
- 细胞图谱:寻找免疫细胞簇
- 蛋白互作网络:识别功能蛋白复合物
- 社交网络:划分兴趣群体或社团结构
🎯 目标转化
我们希望从图中识别出若干模块,满足:
- 模块内部边密集;
- 模块之间边稀疏。
这个任务被称为:
- 社区检测(Community Detection)
- 模块识别(Module Identification)
- 是典型的无监督图聚类问题
📘 二、学习目录概览
| 算法名称 | 应用场景 | 数学核心 | 特点简述 |
|---|---|---|---|
| Louvain | 大图,速度优先 | 模块度(Modularity) | 贪心法 + 分层合并,效率高 |
| Leiden | 精度 & 稳定性 | 模块度 + 强连通性保障 | 优化 Louvain,避免孤立点 |
| Edge Betweenness | 小图,强调可解释性 | 边介数中心性 | 基于最短路径,能清晰看“桥” |
| Spectral Clustering | 对称结构 / 几何图 | 图拉普拉斯特征分解 | 高级数学方法,适合空间分析等图谱 |
🔢 三、四种经典算法详解
① Louvain Algorithm(鲁文算法)
🧭 直觉理解:
让“模块度”尽可能大:即图中模块内的边比预期多,则说明划分合理。
📐 模块度公式
$$
Q = \frac{1}{2m} \sum_{i,j} \left[ A_{ij} - \frac{k_i k_j}{2m} \right] \delta(c_i, c_j)
$$
- $A_{ij}$:邻接矩阵
- $k_i$:节点 $i$ 的度数
- $m$:图中边总数
- $\delta(c_i, c_j)$:若两节点在同一社区则为 1
🚀 算法流程:
- 每个节点初始自成一个社区
- 尝试移动每个节点到邻居社区,看是否能提升 $Q$
- 将得到的社区作为“超级节点”重新构图,回到步骤 2
- 直到 $Q$ 不再提升
🧪 Python 示例:
import networkx as nx
import community
G = nx.Graph() # 构建图
partition = community.best_partition(G)
② Leiden Algorithm(莱顿算法)
🌟 相比 Louvain 的改进:
| 问题 Louvain 有 | Leiden 的修正 |
|---|---|
| 模块不连通 | 加入“连通性检查”与模块细化 |
| 停留在局部最优 | 三阶段策略避免收敛过快 |
🧬 核心流程:
- 局部移动(改进)
- 检查模块连通性(切断“弱连接”)
- 超图压缩后再次循环
✅ 优点总结:
- 更精确(无孤立点)
- 收敛更快、更稳定
- 保留 Louvain 的速度优势
🔧 Python 用法:
import igraph as ig
g = ig.Graph(edges=[(0, 1), (1, 2), (2, 3), (0, 3)])
partition = g.community_leiden(objective_function='modularity')
③ Edge Betweenness Clustering(边介数法)
🔍 直觉理解:
图中跨社区的“桥”边,往往被很多最短路径经过,其“介数”就高。
📐 数学定义
$$
C_B(e) = \sum_{s \ne t} \frac{\sigma_{st}(e)}{\sigma_{st}}
$$
- $\sigma_{st}$:从节点 $s$ 到 $t$ 的最短路径数
- $\sigma_{st}(e)$:其中经过边 $e$ 的路径数
🚀 算法流程:
- 计算所有边的介数中心性
- 删除介数最高的边
- 网络断裂 → 社区出现
- 可选模块度最优断点,或指定模块数
✅ 特点总结:
- 优点:结构清晰、解释直观、适合小图
- 缺点:计算量大,$O(n^3)$ 级别复杂度
🧪 Python 示例:
import networkx as nx
from networkx.algorithms.community import girvan_newman
G = nx.karate_club_graph()
comp = girvan_newman(G)
first_level = next(comp)
④ Spectral Clustering(谱聚类)
🎯 直觉理解:
用“震动模式”来看图的结构,频率相近的节点可能属于同一模块。
📐 拉普拉斯矩阵
$$
L = D - A
$$
- $D$:度矩阵(对角线为节点度数)
- $A$:邻接矩阵
求解特征向量:
$$
Lu = \lambda u
$$
- 前 $k$ 个特征向量作为新坐标空间
- 对新坐标进行 KMeans 聚类
✅ 特点总结:
- 优点:理论稳健,适合对称图、空间分析、层次嵌套结构
- 缺点:特征分解成本高,对稀疏图不敏感
🧪 Python 示例:
from sklearn.cluster import SpectralClustering
sc = SpectralClustering(n_clusters=3, affinity='precomputed')
labels = sc.fit_predict(adj)
✅ 四、如何选择社区检测算法?
| 场景 / 目标 | 推荐算法 | 原因 |
|---|---|---|
| 网络节点多、需快速分析 | Louvain / Leiden | 模块度优化 + 层级合并策略 |
| 强调模块精度、避免孤点 | Leiden | 更精细、结构保证 |
| 想要解释每一步、图较小 | Edge Betweenness | 每条“桥”都可解释,结构直观 |
| 图结构具有对称性/空间特性 | Spectral | 拉普拉斯频谱,结构层次更清晰 |
🧩 五、可视化建议
- 用
networkx+matplotlib绘制社区划分图 - 用
graph-tool或pyvis进行交互式展示 - 用
Seabornheatmap 展示邻接矩阵 + 社区重排后的结构
🎓 六、延伸建议
- 深入了解:Infomap, Walktrap, Label Propagation
- 模块度不是唯一指标,试试Normalized Cut、Conductance
- 图神经网络(GNN)也能做社区识别(GraphSAGE, GCN + Clustering)
浙公网安备 33010602011771号