CDLIB库NMI(归一化互信息)函数运行报错 社区检测评估求助
问题根因
该报错的核心原因是传入normalized_mutual_information函数的两个社区划分(算法输出的检测社区、真实标注社区)覆盖的节点集合不完全一致,存在节点仅出现在其中一个划分中的情况,CDLIB的NMI计算要求两个划分必须覆盖完全相同的节点才能正常运算。
排查&解决步骤
- 第一步:先定位两个划分的节点差异
运行以下代码提取两边的节点集合,查看不一致的节点:
# 提取算法输出社区的所有节点,若你直接传入社区列表而非CDLIB的NodeClustering对象,替换res_omega_nmi.communities为你的社区列表变量 pred_nodes = set() for comm in res_omega_nmi.communities: pred_nodes.update(comm) # 提取真实标注社区的所有节点,同上可根据你的入参类型调整取值逻辑 true_nodes = set() for comm in communities_omega_nmi.communities: true_nodes.update(comm) # 输出差异节点 print("仅在预测社区中存在的节点:", pred_nodes - true_nodes) print("仅在真实标注中存在的节点:", true_nodes - pred_nodes)
- 第二步:根据差异原因对应处理
- 若差异来自算法输出:检查你的社区检测代码逻辑,确认所有输入图的节点都被分到了对应社区,没有遗漏孤立节点、也没有混入图中不存在的无效节点
- 若差异来自数据集预处理:DBLP数据集场景下该情况最为常见,如果跑算法前你对图做了低度数节点过滤、采样等裁剪操作,需要同步把真实标注里对应被裁剪的节点删除,保证两边节点完全对齐
- 若差异来自节点ID格式不匹配:比如一边节点ID是整数、另一边是字符串(
1和"1"被判定为不同节点),统一两边的ID数据类型即可
- 第三步:如果确实存在无标注节点不需要纳入评估,过滤两个划分仅保留共有节点后再计算NMI:
# 取两边的共有节点集合 common_nodes = pred_nodes & true_nodes # 过滤预测社区,仅保留共有节点,同时删除过滤后为空的社区 filtered_pred = [] for comm in res_omega_nmi.communities: filtered_comm = [n for n in comm if n in common_nodes] if filtered_comm: filtered_pred.append(filtered_comm) # 过滤真实社区,逻辑同上 filtered_true = [] for comm in communities_omega_nmi.communities: filtered_comm = [n for n in comm if n in common_nodes] if filtered_comm: filtered_true.append(filtered_comm) # 包装为CDLIB要求的NodeClustering格式后计算NMI,若你直接传社区列表入参可跳过包装步骤 from cdlib import NodeClustering filter_pred_obj = NodeClustering(filtered_pred, graph=None, method_name="filtered_pred") filter_true_obj = NodeClustering(filtered_true, graph=None, method_name="filtered_true") nmi = evaluation.normalized_mutual_information(filter_pred_obj, filter_true_obj)
内容的提问来源于stack exchange,提问作者Motaz ben hassine
相关产品推荐
相关产品推荐

