dgl.to_heterogeneous

dgl.to_heterogeneous(G, ntypes, etypes, ntype_field='_TYPE', etype_field='_TYPE', metagraph=None)[source]

将同构图转换为异构图并返回。

输入图应只有一种节点类型和边类型。每个节点和边都存储一个整数特征作为其类型 ID(由 ntype_fieldetype_field 指定)。DGL 使用此 ID 来检索给定 ntypesetypes 参数中存储的类型名称。

函数将自动区分具有相同给定类型 ID 但源类型 ID 和目标类型 ID 不同的边类型。例如,它允许边 A 和边 B 都具有相同的类型 ID 0,但一个的 (源, 目标) 类型 ID 是 (0, 1),另一个是 (2, 3)。在这种情况下,函数会将边类型 0“拆分”为两种类型:(0, ty_A, 1) 和 (2, ty_B, 3)。换句话说,这两条边共享相同的边类型名称,但可以通过边类型三元组来区分。

函数使用 dgl.NIDdgl.EID 名称将输入图中的节点和边 ID 存储到结果图的 ndataedata 中。它还将 G 中的所有节点/边特征复制到返回的异构图中,但用于存储类型 ID (dgl.NTYPEdgl.ETYPE) 和节点/边 ID (dgl.NIDdgl.EID) 的保留字段除外。

参数:
  • G (DGLGraph) – 同构图。

  • ntypes (list[str]) – 节点类型名称列表。

  • etypes (list[str]) – 边类型名称列表。

  • ntype_field (str, optional) – 用于存储节点类型的特征字段。(默认值:dgl.NTYPE

  • etype_field (str, optional) – 用于存储边类型的特征字段。(默认值:dgl.ETYPE

  • metagraph (networkx MultiDiGraph, optional) – 返回的异构图的元图。如果提供,DGL 假定 G 确实可以用给定的元图描述。如果为 None,DGL 将从给定输入推断元图,这对于大型图可能开销较大。

返回值:

一个异构图。

返回类型:

DGLGraph

注意事项

  • 返回的节点类型和边类型不一定与 ntypesetypes 的顺序相同。

  • 调用 to_homogeneous() 然后再次调用 to_heterogeneous() 会得到相同的结果。

示例

以下示例使用 PyTorch 后端。

>>> import dgl
>>> import torch
>>> hg = dgl.heterograph({
...     ('user', 'develops', 'activity'): (torch.tensor([0, 1]), torch.tensor([1, 2])),
...     ('developer', 'develops', 'game'): (torch.tensor([0, 1]), torch.tensor([0, 1]))
... })
>>> print(hg)
Graph(num_nodes={'activity': 3, 'developer': 2, 'game': 2, 'user': 2},
      num_edges={('developer', 'develops', 'game'): 2, ('user', 'develops', 'activity'): 2},
      metagraph=[('developer', 'game', 'develops'), ('user', 'activity', 'develops')])

我们首先将异构图转换为同构图。

>>> g = dgl.to_homogeneous(hg)
>>> print(g)
Graph(num_nodes=9, num_edges=4,
      ndata_schemes={'_TYPE': Scheme(shape=(), dtype=torch.int64),
                     '_ID': Scheme(shape=(), dtype=torch.int64)}
      edata_schemes={'_TYPE': Scheme(shape=(), dtype=torch.int64),
                     '_ID': Scheme(shape=(), dtype=torch.int64)})
>>> g.ndata
{'_TYPE': tensor([0, 0, 0, 1, 1, 2, 2, 3, 3]), '_ID': tensor([0, 1, 2, 0, 1, 0, 1, 0, 1])}
Nodes 0, 1, 2 for 'activity', 3, 4 for 'developer', 5, 6 for 'game', 7, 8 for 'user'
>>> g.edata
{'_TYPE': tensor([0, 0, 1, 1]), '_ID': tensor([0, 1, 0, 1])}
Edges 0, 1 for ('developer', 'develops', 'game'), 2, 3 for ('user', 'develops', 'activity')

现在将同构图转换回异构图。

>>> hg_2 = dgl.to_heterogeneous(g, hg.ntypes, hg.etypes)
>>> print(hg_2)
Graph(num_nodes={'activity': 3, 'developer': 2, 'game': 2, 'user': 2},
      num_edges={('developer', 'develops', 'game'): 2, ('user', 'develops', 'activity'): 2},
      metagraph=[('developer', 'game', 'develops'), ('user', 'activity', 'develops')])

检索原始节点/边 ID。

>>> hg_2.ndata[dgl.NID]
{'activity': tensor([0, 1, 2]),
 'developer': tensor([3, 4]),
 'game': tensor([5, 6]),
 'user': tensor([7, 8])}
>>> hg_2.edata[dgl.EID]
{('developer', 'develops', 'game'): tensor([0, 1]),
 ('user', 'develops', 'activity'): tensor([2, 3])}

另请参见

to_homogeneous