[DGL基础系列]-在DGL中,如何创建一个图?

文摘   2024-07-15 20:29   浙江  
大家好,我是小伍哥,现在图神经网络用的也是越来越多,我自己也需要体系化的整理学习下,这里写个基础系列的,后面会慢慢更新。
dgl.DGLGraph是对图的统一抽象,它存储了图的结构信息、节点/边的属性信息。一般有如下3个生成来源:
  • 通过dgl.graph()创建同构图
  • 通过dgl.heterograph()创建异构图
  • 借助dgl.*工具包和其他数据源生成图,如dgl.from_networkx等
备注:在DGL眼中图都是有向的。对于无向图,用户需要为每条边创建两个方向的边,具体需调用dgl.to_bidirected()方法。

1、两个节点数创建图

这是最常见和基础的方法之一,dgl.graph((src, dst)),通过指定源节点和目标节点的列表来创建图。源节点和目标节点需要构建成一对元组(u, v):分别保存源节点和目标节点,可以是numpy或者是tensor类型或者其他可迭代类型。
import dglimport torch
#基于 tensor 创建src = torch.tensor([0, 1, 2, 3])dst = torch.tensor([1, 2, 3, 4])g = dgl.graph((src, dst))
#基于 numpy 创建src = np.array([0, 1, 2, 3])dst = np.array([1, 2, 3, 4])g = dgl.graph((src, dst))
#基于 ;list 创建src = [0, 1, 2, 3]dst = [1, 2, 3, 4]g = dgl.graph((src, dst))g

2、从networkx创建图

可以从networkx 的图直接创建:dgl.from_networkx(nx_g),可以利用 NetworkX 提供的图生成函数,并将其转换为 DGL 图。
import dglimport networkx as nx
# 创建一个 networkx 图nx_g = nx.karate_club_graph()
# 转换为 DGL 图g = dgl.from_networkx(nx_g)

import networkx as nxnx_g = nx.path_graph(5) # 一条链路0-1-2-3-4dgl.from_networkx(nx_g) # 来自NetworkX
Graph(num_nodes=5, num_edges=8, ndata_schemes={} edata_schemes={})
注意:当使用 nx.path_graph(5) 进行创建时, DGLGraph 对象有8条边,而非4条。这是由于 nx.path_graph(5) 构建了一个无向的NetworkX图 networkx.Graph ,而 DGLGraph 的边总是有向的。所以当将无向的NetworkX图转换为 DGLGraph 对象时,DGL会在内部将1条无向边转换为2条有向边。使用有向的NetworkX图 networkx.DiGraph 可避免该行为。
nxg = nx.DiGraph([(2, 1), (1, 2), (2, 3), (0, 0)])dgl.from_networkx(nxg)
Graph(num_nodes=4, num_edges=4, ndata_schemes={} edata_schemes={})

3、使用稀疏矩阵创建图

Scipy 提供了高效的稀疏矩阵表示方法,可以很方便地转换为 DGL 图。
import dglimport scipy.sparse as spimport torch
# 创建一个稀疏邻接矩阵adj = sp.coo_matrix([ [0, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1], [0, 0, 0, 0, 0]])
# 转换为 DGL 图g = dgl.graph((torch.tensor(adj.row), torch.tensor(adj.col)))

# 从稀疏矩阵转换spmat = sp.rand(100, 100, density=0.05) # 5%非零项dgl.from_scipy(spmat) # 来自SciPy


4、从DataFrame创建图

在数据分析和处理过程中,可能使用 Pandas DataFrame 表示图数据,可以从 dataframe 创建 DGL 图。
import dglimport pandas as pd
# 创建一个 dataframedf = pd.DataFrame({ 'source': [0, 1, 2, 3], 'target': [1, 2, 3, 4]})
# 转换为 DGL 图g = dgl.graph((df['source'].values, df['target'].values))g
如果是csv,读取出来就是DataFrame,可以按照类似的方法创建就行。

5、 随机图生成

DGL 提供了一些接口,可以快速生成随机图,如二分图、完全图、树结构等。
# 随机生产图g = dgl.rand_graph(100, 10)
#转换为networkxnx_g = dgl.to_networkx(g)
#可视化看fig = plt.figure(figsize=(4,3.5),dpi=1000)nx.draw(nx_graph,with_labels=True, width=0.2,node_color='skyblue',node_size=800, font_size=13)plt.show()
可以看到,生成的图为双向的有向图。我们再来生产个二部图试试
import dgl# 生成一个二分图g = dgl.rand_bipartite('user', 'buys', 'game', 50, 100, 10)gGraph(num_nodes={'game': 100, 'user': 50},      num_edges={('user', 'buys', 'game'): 10},      metagraph=[('user', 'game', 'buys')])
g.edges()(tensor([38, 19, 16, 37, 10, 35, 7, 26, 3, 27]), tensor([50, 84, 53, 34, 75, 76, 69, 68, 80, 24]))


6、从其他图格式导入

DGL 支持从多个常见的图数据格式中导入图数据,如 GraphML、GML 等。
import dglimport networkx as nx
# 从 GraphML 文件读取图数据nx_g = nx.read_graphml('path_to_graph_file.graphml')g = dgl.from_networkx(nx_g)

7、边索引创建异构图

在DGL中,一个异构图由一系列子图构成,一个子图对应一种关系。每个关系由一个字符串三元组定义(源节点类型,边类型,目标节点类型)。
在处理包含多种节点和边类型的图时,可以使用边索引来创建异构图。
import dgl
data_dict = { ('user', 'follows', 'user'): ([0, 1], [1, 2]), ('user', 'writes', 'post'): ([0, 1], [0, 1]), ('post', 'mentions', 'user'): ([0, 1], [1, 2])}
hetero_g = dgl.heterograph(data_dict)

8、二分图

二分图:顶点集合可划分为两个互不相交的子集,图中的每条边依附的两个顶点分别属于这两个互不相交的子集。二分图可以看做一种特殊类型的异构图,它只包含一种关系。
在DGL中关于二分图的约定与上述定义稍有不同。在DGL中有两种二分图,一种是符合上述定义的uni-directional bipartite;另一种是起点有多种类型、终点有多种类型,但是起点类型与终点类型无交集的uni-bipartite。
# uni-directional bipartite举例graph_data1 = {    ('drug', 'interacts2', 'gene'): (th.tensor([0, 1]), th.tensor([2, 3]))}g1 = dgl.heterograph(graph_data1)
# uni-bipartite举例graph_data2 = { ('drug', 'interacts2', 'gene'): (th.tensor([0, 1]), th.tensor([2, 3])), ('drug', 'treats', 'disease'): (th.tensor([1]), th.tensor([2]))}g2 = dgl.heterograph(graph_data2)
DGL中graph的is_unibipartite属性用来判断一个图对象是否为uni-bipartite,若是则返回true。注:uni-directional bipartite是uni-bipartite的一种特例。

9、总  结

通过以上多种方法,可以灵活地创建 DGL 图,以满足不同数据源和应用场景的需求。DGL 提供了丰富的接口和工具,支持从多个数据来源构建图,具备极高的灵活性展性。

往期精彩:

[课程]万物皆网络-风控中的网络挖掘方法

风控中的复杂网络-学习路径图

【实战】从原始数据开始构建GCN算法

信用卡欺诈孤立森林实战案例分析,最佳参数选择、可视化等

风控策略的自动化生成-利用决策树分分钟生成上千条策略

SynchroTrap-基于松散行为相似度的欺诈账户检测算法

20大风控文本分类算法之6-基于BERT的文本分类实战

长按关注本号             长按加我进群
      

小伍哥聊风控
风控策略&算法,内容风控、复杂网络挖掘、图神经网络、异常检测、策略自动化、黑产挖掘、反欺诈、反作弊等
 最新文章