【DGL学习4】使用DGL构造异构图

使用DGL都早异构图
参考:https://docs.dgl.ai/guide_cn/graph-heterogeneous.html

import dgl
import torch
Using backend: pytorch

使用DGL创建异构图

下面一个异构图示例。该图具有两种类型的节点(“用户”和”游戏”)和两种类型的边(“关注”和”玩”)。
我们将按照这个例子来创建一个异构图。

在这里插入图片描述

graph_data = {
    ('user', 'follows', 'user') : (torch.tensor([0]), torch.tensor([1])),
    ('user', 'plays', 'game') : (torch.tensor([0, 0, 1, 1]), torch.tensor([0, 1, 1, 2]))
}
g = dgl.heterograph(graph_data)
print(g)
Graph(num_nodes={'game': 3, 'user': 2},
      num_edges={('user', 'follows', 'user'): 1, ('user', 'plays', 'game'): 4},
      metagraph=[('user', 'user', 'follows'), ('user', 'game', 'plays')])

查看异构图的各种属性

print(g.ntypes)
print(g.etypes)
print(g.canonical_etypes)  # 查看关系类型三元组
['game', 'user']
['follows', 'plays']
[('user', 'follows', 'user'), ('user', 'plays', 'game')]
# 查看图的模式
print(g.metagraph().edges)
[('user', 'user', 'follows'), ('user', 'game', 'plays')]
print(g.num_nodes())
print(g.num_edges())
print(g.num_nodes('game'))  # 获取某一特定类型节点数量
print(g.num_edges('plays'))
5
5
3
4

查看图的节点和边

print(g.nodes('user'))  #必须指定是哪种类型的节点
print(g.edges(etype='plays'))  #必须指定是哪种类型的边
tensor([0, 1])
(tensor([0, 0, 1, 1]), tensor([0, 1, 1, 2]))

设置属性或特征信息

g.nodes['user'].data['x'] = torch.randn(g.num_nodes('user'), 4)
g.nodes['game'].data['x'] = torch.randn(g.num_nodes('game'), 5)
print(g.nodes['user'])
NodeSpace(data={'x': tensor([[ 0.3505, -1.4983, -1.0730,  0.5282],
        [-0.2750,  0.5387,  0.2102,  0.1434]])})
g.edges['follows'].data['w'] = torch.randn(g.num_edges('follows'), 3)
g.edges['plays'].data['w'] = torch.randn(g.num_edges('plays'), 3)
print(g.edges['plays'])
EdgeSpace(data={'w': tensor([[-1.1410, -1.6737,  0.7064],
        [ 1.2126, -0.5300,  0.2150],
        [-1.9890,  1.8472, -1.1371],
        [ 0.4387, -1.3494, -0.1445]])})

构造边类型子图

sg = dgl.edge_type_subgraph(g, [('user', 'plays', 'game')])
print(sg)
Graph(num_nodes={'game': 3, 'user': 2},
      num_edges={('user', 'plays', 'game'): 4},
      metagraph=[('user', 'game', 'plays')])
print(sg.nodes['user'].data['x'])
print(sg.edges(etype='plays'))
tensor([[ 0.3505, -1.4983, -1.0730,  0.5282],
        [-0.2750,  0.5387,  0.2102,  0.1434]])
(tensor([0, 0, 1, 1]), tensor([0, 1, 1, 2]))

异构图转化为同构图

默认情况下DGL不进行特征合并
对于要拷贝的特征,DGL假定不同类型的节点或边的需要合并的特征具有相同的大小和数据类型

# 拷贝边的特征
hg1 = dgl.to_homogeneous(g)
hg2 = dgl.to_homogeneous(g, edata=['w'])
print(hg1)
print(hg2)
Graph(num_nodes=5, num_edges=5,
      ndata_schemes={'_ID': Scheme(shape=(), dtype=torch.int64), '_TYPE': Scheme(shape=(), dtype=torch.int64)}
      edata_schemes={'_ID': Scheme(shape=(), dtype=torch.int64), '_TYPE': Scheme(shape=(), dtype=torch.int64)})
Graph(num_nodes=5, num_edges=5,
      ndata_schemes={'_ID': Scheme(shape=(), dtype=torch.int64), '_TYPE': Scheme(shape=(), dtype=torch.int64)}
      edata_schemes={'w': Scheme(shape=(3,), dtype=torch.float32), '_ID': Scheme(shape=(), dtype=torch.int64), '_TYPE': Scheme(shape=(), dtype=torch.int64)})
print(hg2.edata['w'])
tensor([[ 0.2964,  0.9229,  1.1623],
        [-1.1410, -1.6737,  0.7064],
        [ 1.2126, -0.5300,  0.2150],
        [-1.9890,  1.8472, -1.1371],
        [ 0.4387, -1.3494, -0.1445]])

查看转化后图的属性

print(g.ntypes)
print(hg2.ndata[dgl.NTYPE])  # 原始节点类型
print(hg2.ndata[dgl.NID])  # 原始的特定类型节点ID
['game', 'user']
tensor([0, 0, 0, 1, 1])
tensor([0, 1, 2, 0, 1])
print(g.etypes)
print(hg2.edata[dgl.ETYPE])
print(hg2.edata[dgl.EID])
['follows', 'plays']
tensor([0, 1, 1, 1, 1])
tensor([0, 0, 1, 2, 3])

出于建模的目的,用户可能需要将一些关系合并,并对它们应用相同的操作。为了实现这一目的,可以先抽取异构图的边类型子图,然后将该子图转换为同构图。

  • 12
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值