使用环境:python3.7
平台:Windows10
IDE:PyCharm
dgl版本: 0.5.3
网上关于dgl-0.4.x版本的资料相对较多,但是dgl在0.4到0.5版本发生了很大的改变,在0.4版本中常用的从稀疏矩阵中转换到graph诸多API已经不能使用了,这也是写本文的目的,如下:
比如:data为ACM数据集,数据集下载链接如下:
链接:https://pan.baidu.com/s/1wQK2VhbRlktT8G3H8-FkMA
提取码:k255
在Python中读入此数据:
import dgl.function as fn
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import scipy.io
import urllib.request
import dgl
import pygraphviz as pgv
import matplotlib.pyplot as plt
import scipy.sparse as sp
data_file_path = 'ACM.mat'
data = scipy.io.loadmat(data_file_path)
通过dgl.heterograph()
创建graph
G = dgl.heterograph({
('paper', 'written-by', 'author') : data['PvsA'],
('author', 'writing', 'paper') : data['PvsA'].transpose(),
('paper', 'citing', 'paper') : data['PvsP'],
('paper', 'cited', 'paper') : data['PvsP'].transpose(),
('paper', 'is-about', 'subject') : data['PvsL'],
('subject', 'has', 'paper') : data['PvsL'].transpose(),
})
会出现如下报错:
raise DGLError("dgl.heterograph no longer supports graph construction from a SciPy "
dgl._ffi.base.DGLError: dgl.heterograph no longer supports graph construction from a SciPy sparse matrix, use dgl.from_scipy instead.
意思是从稀疏矩阵传入数据不再支持dgl.heterograph()
,要用dgl.from_scipy instead
进行转换
命令如下:
g = dgl.from_scipy(sp_mat,eweight_name='w')
官方的解释如下:
当然,英文读起来或许有点吃力,不是很容易搞清楚,下面对每个参数进行解释:
start
dgl.from_scipy()
中参数一般为:
dgl.from_scipy(sp_mat, eweight_name=None, idtype=None, device=None)
用法为:g = dgl.from_scipy(sp_mat, eweight_name=None, idtype=None, device=None)
sp_mat
为coo_matrix类型的稀疏矩阵,稀疏矩阵不理解可以参考此文章eweight_name
可以省略,如果省略的话则忽略稀疏矩阵中的所有值,只是创建和稀疏矩阵shape对应的graph;如果设置eweight_name,如:eweight_name='w'
(其中‘w’也可以为任意字符串),则表示将稀疏矩阵中非零值视为graph中的edge(边)的特征值。idtype
也可省略,省略的话dgl就默认边权重的数据类型为int64
,当然也可以设置为torch.int32
等数据类型device
表示数据存储的位置,一般有CPU或者CUDA:0等可以选择end
其中重要的是1、2参数,也是最难理解的,为方便理解,上代码:
以此例说明:
import scipy.sparse as sp
import dgl.function as fn
import numpy as np
import torch
import scipy.io
import urllib.request
import dgl
# Source nodes for edges (2, 1), (3, 2), (4, 3)
src_ids = np.array([2, 3, 4])
# Destination nodes for edges (2, 1), (3, 2), (4, 3)
dst_ids = np.array([1, 2, 3])
# Weight for edges (2, 1), (3, 2), (4, 3)
eweight = np.array([0.2, 0.3, 0.5])
sp_mat = sp.coo_matrix((eweight, (src_ids, dst_ids)), shape=(5, 5))
sp_array = sp_mat.toarray()
print(sp_array)
g1 = dgl.from_scipy(sp_mat)
g = dgl.from_scipy(sp_mat,eweight_name='w')
print(g)
out:
[[0. 0. 0. 0. 0. ]
[0. 0. 0. 0. 0. ]
[0. 0.2 0. 0. 0. ]
[0. 0. 0.3 0. 0. ]
[0. 0. 0. 0.5 0. ]]
Graph(num_nodes=5, num_edges=3,
ndata_schemes={
}
edata_schemes={
})
Graph(num_nodes=5, num_edges=3,
ndata_schemes={
}
edata_schemes={
'w': Scheme(shape=(), dtype=torch.float64)})
通过debug对比g1和g中的数据也可以看到:
g
g1
可以看到,g中因为多了eweight_name='w'
g = dgl.from_scipy(sp_mat,eweight_name='w')
所以graph中包换edata
项:{'w': tensor([0.2000, 0.3000, 0.5000], dtype=torch.float64)}
在新版本中一般不再用这个方法来导入数据了,但是这个函数还是可以使用的,使用方法如下:
import dgl
import torch as th
#创建一个具有3种节点类型和3种边类型的异构图
graph_data = {
('drug', 'interacts', 'drug'): (th.tensor([0, 1]), th.tensor([1, 2])),
('drug', 'interacts', 'gene'): (th.tensor([0, 1]), th.tensor([2, 3])),
('drug', 'treats', 'disease'): (th.tensor([1]), th.tensor([2]))
}
g = dgl.heterograph(graph_data)
dgl.heterograph()
函数的传入参数为dict
字典类型数据,
字典的key数据结构为:(源节点类型, 边类型, 目标节点类型)
key中的数据为graph边的起始节点,graph边的中止节点
,如上例所示创建的就是
('drug', 'interacts', 'drug')
边的类型下的两条边:0->1; 1->2
('drug', 'interacts', 'gene')
边的类型下的两条边:0->2; 1->3
('drug', 'treats', 'disease')
边的类型下的一条边:1->2
如果本文对你有帮助的话还请点赞、收藏一键带走哦,你的支持是我最大的动力!(づ。◕ᴗᴗ◕。)づ