2021-06-15

本文介绍了图论的基础概念,包括图、无向图与有向图、邻接矩阵、节点度和拉普拉斯矩阵。接着讲解了环境配置,如PyTorch和PyG的安装,并展示了PyG的Data类和Dataset类的使用。通过实例展示了如何创建和操作图数据。最后,设计了一个专门表示‘机构-作者-论文’网络的数据类,具备统计不同节点数量的功能。
摘要由CSDN通过智能技术生成

简单图论

图论是数学的一个分支。它以图为研究对象。图论中的图是由若干给定的点及连接两点的线所构成的图形,这种图形通常用来描述某些事物之间的某种特定关系,用点代表事物,用连接两点的线表示相应两个事物间具有这种关系。

图论常见的定义

定义一:图

一些元素及它们之间的某种关系称为图。一个图被记作G={ ν \nu ν, ε \varepsilon ε}。其中 ν \nu ν={ ν i \nu_i νi},i ∈ \in N,N为节点个数。 ε \varepsilon ε={ e i e_i ei},i ∈ \in M,M为边个数。
如给定G={ ν \nu ν, ε \varepsilon ε}。 ν \nu ν={ ν 1 \nu_1 ν1, ν 2 \nu_2 ν2, ν 3 \nu_3 ν3}, ε \varepsilon ε={ e 1 e_1 e1, e 2 e_2 e2, e 3 e_3 e3}={( ν 1 \nu_1 ν1, ν 2 \nu_2 ν2),( ν 2 \nu_2 ν2, ν 3 \nu_3 ν3),( ν 3 \nu_3 ν3, ν 1 \nu_1 ν1)},这便定义了一个图。

定义二:无向图与有向图

有向与无向直接去区别是,节点与节点直接连接的边是不是有方向的。无方向称为无向图。反之亦然。

定义三:邻接矩阵

邻接矩阵(Adjacency Matrix)是表示顶点之间相邻关系的矩阵。其对应的邻接矩阵被记为A。A的大小为 N × N\times N× N N N a i j a_{ij} aij的值为基于 ν i \nu_i νi ν j \nu_j νj的关系自己定义的值。如常见的定义连接为1,不连接为0。即A ∈ { 0 , 1 } N × N \in\{0,1\}^{N\times N} {0,1}N×N

定义四:节点的度

节点度是指和该节点相关联的边的条数,又称关联度。对于有向图,节点的入度是指进入该节点的边的条数。节点的出度是指从该节点出发的边的条数。节点 ν i \nu_i νi的度记 d ( ν i ) d(\nu_i) d(νi)

定义五:拉普拉斯矩阵

图的拉普拉斯矩阵定义为: L = D − A L=D-A L=DA。其中D为对角矩阵, D = d i a g ( d ( ν 1 ) , . . . , d ( ν n ) ) D=diag(d(\nu_1) ,...,d(\nu_n) ) D=diag(d(ν1),...,d(νn))。A为邻接矩阵。归一化的拉普拉斯矩阵为 L = D − 1 2 ( D − A ) D − 1 2 L=D^{-\frac{1}{2}}(D-A)D^{-\frac{1}{2}} L=D21(DA)D21

图的基本分类

同质图:只有一种类型的节点和一种类型的边的图。
异质图:存在多种类型的节点和多种类型的边的图。
二部图:节点分为两类,只有不同类的节点之间存在边。

环境的配置

安装pytorch

进入pytorch官网下载选择合适的版本安装即可。
pytorch安装

安装PyG

进入PyG的文档介绍,选择合适版本,安装PyG文档指导安装即可。
PyG

PyG-Data类

PyG-Data类官方文档,Data类需要传递参数为:x=None, edge_index=None, edge_attr=None, y=None, pos=None, normal=None, face=None, **kwargs。通常,一个图至少包含x, edge_index, edge_attr, y, num_nodes 5个属性。简易版的Data构造类如下:

class Data(object):
    r"""A plain old python object modeling a single graph with various
    (optional) attributes:

    Args:
        x (Tensor, optional): Node feature matrix with shape :obj:`[num_nodes,
            num_node_features]`. (default: :obj:`None`)
        edge_index (LongTensor, optional): Graph connectivity in COO format
            with shape :obj:`[2, num_edges]`. (default: :obj:`None`)
        edge_attr (Tensor, optional): Edge feature matrix with shape
            :obj:`[num_edges, num_edge_features]`. (default: :obj:`None`)
        y (Tensor, optional): Graph or node targets with arbitrary shape.
            (default: :obj:`None`)

    The data object is not restricted to these attributes and can be extented
    by any other additional data.

    Example::
        data = Data(x=x, edge_index=edge_index)
    """
    def __init__(self, x=None, edge_index=None, edge_attr=None, y=None, **kwargs):
        self.x = x
        self.edge_index = edge_index
        self.edge_attr = edge_attr
        self.y = y
        for key, item in kwargs.items():
            if key == 'num_nodes':
                self.__num_nodes__ = item
            else:
                self[key] = item

        if edge_index is not None and edge_index.dtype != torch.long:
            raise ValueError(
                (f'Argument `edge_index` needs to be of type `torch.long` but '
                 f'found type `{edge_index.dtype}`.'))

其中edge_index需要注意是LongTensor,是coo格式

PyG-Dataset类

PyG内置了大量常用的基准数据集,接下来我们以PyG内置的Planetoid 数
据集
为例,来学习PyG中图数据集的表示及使用。

from torch_geometric.datasets import Planetoid
dataset = Planetoid(root='/dataset/Cora', name='Cora')
data = dataset[0]
data

结果显示为:Data(edge_index=[2, 10556], test_mask=[2708], train_mask=[2708], val_mask=[2708], x=[2708, 1433], y=[2708])。
通过以下命令可以查看节点、边等的个数。

print(len(dataset))
print(dataset.num_classes)
print(dataset.num_node_features)
print(data.train_mask.sum().item())
print(data.val_mask.sum().item())
print(data.test_mask.sum().item())

结果

结果图

看到该数据集包含的唯一的图,有2708个节点,节点特征为1433维,有10556条边,有140个用作训练集的节点,有500个用作验证集的节点,有1000个用作测试集的节点。

作业

请通过继承Data类实现一个类,专门用于表示“机构-作者-论文”的网
络。该网络包含“机构“、”机构“和”论文”三类节点,以及“作者-机构“和 “作者-论文“两类边。对要实现的类的要求:1)用不同的属性存储不同节点的属性;2)用不同的属性存储不同的边(边没有属性);3)逐一实现获取不同节点数量的方法。
假设:机构、机构、论文节点的值分别为[1,0,0]、[0,1,0]、[0,0,1]。
导入相关库和包:

import torch
from torch_geometric.data import Data

自定义一个图,有5个节点、2个机构、2个作者、1篇论文。

x = torch.tensor([[1,0,0],[0,1,0],[0,0,1],[0,1,0],[1,0,0]],dtype=torch.float)
edge_index = torch.tensor([[0,1,0,2,3],
              [1,4,3,1,4]],dtype=torch.long)
edge_attr = torch.tensor([[1,0],[1,0],[1,0],[0,1],[1,0]]) 

data = Data(x=x,edge_index=edge_index,edge_attr=edge_attr)
data
#Data(edge_attr=[5, 2], edge_index=[2, 5], x=[5, 3])

通过继承Data类构建一个类

class Mydata(Data):
  def __init__(self, x=None, edge_index=None, edge_attr=None,**kwargs):
    super(Mydata,self).__init__()
    self.x = x
    self.edge_index = edge_index
    self.edge_attr = edge_attr
    for key,item in kwargs.items():
      self[key] = item
  #统计不同的节点个数
  def get_note_num(self,str):
    num = 0
    for i in range(self.num_nodes):
      if torch.sum(torch.sqrt(self[str] - self.x[i]))==0:
        num += 1
    print('Number of '+str+' : %d'%(num))
    return num

测试如下:

note_in = {'agency':torch.tensor([1,0,0],dtype=torch.float),
           'author':torch.tensor([0,1,0],dtype=torch.float),
           'paper':torch.tensor([0,0,1],dtype=torch.float)}
data1 = Mydata(x=x,edge_index=edge_index,edge_attr=edge_attr,**note_in)
data1.get_note_num('agency')
#Number of agency : 2
data1.get_note_num('paper')
#Number of paper : 1

完整代码如下:

import torch
from torch_geometric.data import Data

x = torch.tensor([[1,0,0],[0,1,0],[0,0,1],[0,1,0],[1,0,0]],dtype=torch.float)
edge_index = torch.tensor([[0,1,0,2,3],
              [1,4,3,1,4]],dtype=torch.long)
edge_attr = torch.tensor([[1,0],[1,0],[1,0],[0,1],[1,0]]) 

class Mydata(Data):
  def __init__(self, x=None, edge_index=None, edge_attr=None,**kwargs):
    super(Mydata,self).__init__()
    self.x = x
    self.edge_index = edge_index
    self.edge_attr = edge_attr
    for key,item in kwargs.items():
      self[key] = item
  #统计不同的节点个数
  def get_note_num(self,str):
    num = 0
    for i in range(self.num_nodes):
      if torch.sum(torch.sqrt(self[str] - self.x[i]))==0:
        num += 1
    print('Number of '+str+' : %d'%(num))
    return num

note_in = {'agency':torch.tensor([1,0,0],dtype=torch.float),
           'author':torch.tensor([0,1,0],dtype=torch.float),
           'paper':torch.tensor([0,0,1],dtype=torch.float)}

data1 = Mydata(x=x,edge_index=edge_index,edge_attr=edge_attr,**note_in)

data1.get_note_num('agency')

参考文献

[1] https://pytorch-geometric.readthedocs.io/en/latest/index.html
[2] https://blog.csdn.net/stark_summer/article/details/49050079
[3] https://github.com/datawhalechina/team-learning-nlp/tree/master/GNN

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值