基于Networkx实现两个网络的加权Jaccard相似度计算方法咨询
加权Jaccard相似度(支持networkx有向/无向图)实现
核心计算逻辑
加权Jaccard相似度同时考虑边的存在性和权重,公式如下:
J_w(G,K) = 权重交集和 / 权重并集和
其中:
- 对于同时存在于两张图的边,交集部分取两条边权重的较小值,并集部分取较大值
- 仅存在于单张图的边,交集部分计0,并集部分取该边的权重值
- 不存在的边权重默认计0
实现代码
import networkx as nx def weighted_jaccard_similarity(g, h, weight_key='weight'): # 提取两张图的边与对应权重,无权重边默认权重为1 g_edge_weights = {(u, v): d.get(weight_key, 1.0) for u, v, d in g.edges(data=True)} h_edge_weights = {(u, v): d.get(weight_key, 1.0) for u, v, d in h.edges(data=True)} # 取所有出现过的边的并集,自动适配节点/边有差异的场景 all_edges = set(g_edge_weights.keys()).union(set(h_edge_weights.keys())) intersect_total = 0.0 union_total = 0.0 for edge in all_edges: w_g = g_edge_weights.get(edge, 0.0) w_h = h_edge_weights.get(edge, 0.0) intersect_total += min(w_g, w_h) union_total += max(w_g, w_h) # 处理空图除零异常 if union_total == 0: return 1.0 return round(intersect_total / union_total, 6) # 若需要计算加权Jaccard距离,使用如下公式 # weighted_jaccard_distance = 1 - weighted_jaccard_similarity(g, h)
示例测试
用你提供的两个有向图测试:
# 构造示例图G G = nx.DiGraph() G.add_weighted_edges_from([ ('v1', 'a', 1), ('v1', 'b', 1), ('a', 'd', 1), ('a', '11', 7), ('b', 'v4', 1), ('b', 'v9', 1), ('v9', 'b', 1) ]) # 构造示例图K K = nx.DiGraph() K.add_weighted_edges_from([ ('v1', 'asssssss', 1), ('v1', 'b', 1), ('asssssss', 'd', 1), ('asssssss', '11', 7), ('b', 'asssssss', 10), ('b', 'd', 10), ('v9', 'b', 1) ]) # 计算相似度 print(weighted_jaccard_similarity(G, K))
输出结果:0.047619
特性说明
- 自动兼容有向/无向图:依赖networkx原生的边表示逻辑,有向图按有序边匹配,无向图按无序边匹配,无需额外传参
- 自动适配异构网络:不需要提前对齐两张图的节点或边,自动覆盖所有出现过的边
- 兼容缺省权重场景:边没有设置对应权重字段时,默认用1作为权重,和普通无权重Jaccard计算逻辑对齐
内容的提问来源于stack exchange,提问作者Forinstance
相关产品推荐
相关产品推荐

