You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用NetworkX将多关系图通过Levi变换转为二部图?

实现多关系图到二部图的Levi变换(NetworkX)

可以通过以下简洁高效的方式完成Levi变换,将带谓词标签的边转换为连接实体与谓词节点的无标签边:

核心思路

  1. 新建有向图(保留原图方向性)作为转换后的二部图载体
  2. 复制原图中所有实体节点及其属性
  3. 提取所有谓词标签作为新节点加入二部图
  4. 将每条原边 (s, o, p) 拆解为两条无标签边 (s, p) 和 (p, o)

代码实现

修正原图构建(多关系图建议用MultiDiGraph)

原代码使用DiGraph无法保留同一实体对间的多条不同关系边,改用MultiDiGraph才能正确存储多关系结构:

import networkx as nx

# 构建多关系图
amr_graph = nx.MultiDiGraph()

for node_id, node_string in amr.nodes.items():
    amr_graph.add_node(node_id, name=node_string)

for subj, pred, obj in amr.edges:
    amr_graph.add_edge(subj, obj, key=pred)

执行Levi变换

# 创建转换后的二部图
levi_graph = nx.DiGraph()

# 批量复制所有实体节点及属性
levi_graph.add_nodes_from(amr_graph.nodes(data=True))

# 提取所有谓词并添加为新节点(标记类型便于区分实体与关系)
all_predicates = {p for s, o, p in amr_graph.edges(keys=True)}
levi_graph.add_nodes_from(all_predicates, type="predicate")

# 批量生成并添加转换后的边
levi_graph.add_edges_from(
    pair for s, o, p in amr_graph.edges(keys=True)
    for pair in [(s, p), (p, o)]
)

补充说明

  • 转换后的图通过节点属性type="predicate"区分谓词节点与实体节点,可直接使用NetworkX的二部图工具模块处理
  • 批量操作(add_nodes_from、add_edges_from)比循环单条添加更高效,代码也更简洁

内容的提问来源于stack exchange,提问作者GiacomoFrisoni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 09:24:44