【问题标题】:How to load in graph from networkx into PyTorch geometric and set node features and labels?如何从networkx将图形加载到PyTorch几何中并设置节点特征和标签?
【发布时间】:2022-01-23 21:06:19
【问题描述】:

目标:我正在尝试将图 FROM networkx 导入 PyTorch 几何并设置标签和节点特征

(这是在 Python 中)

问题

  1. 我该怎么做[从 networkx 到 PyTorch 几何的转换]? (大概是使用from_networkx函数)
  2. 如何转移节点特征和标签?(更重要的问题)

我看过一些其他/以前的帖子,但没有回答(如果我错了,请纠正我)。

尝试:(我只是在下面使用了一个不切实际的例子,因为我不能在这里发布任何真实的东西)

让我们想象一下,我们正在尝试在一组汽车上执行图学习任务(例如节点分类)(正如我所说的不太现实)。也就是说,我们有一组汽车、一个邻接矩阵和一些特征(例如年底的价格)。我们要预测节点标签(即汽车的品牌)。

我将使用以下邻接矩阵:(抱歉,不能使用乳胶来格式化)

A = [(0, 1, 0, 1, 1), (1, 0, 1, 1, 0), (0, 1, 0, 0, 1), (1, 1, 0, 0 , 0), (1, 0, 1, 0, 0)]

这是代码(适用于 Google Colab 环境):

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import networkx as nx
from torch_geometric.utils.convert import to_networkx, from_networkx
import torch

!pip install torch-scatter torch-sparse torch-cluster torch-spline-conv torch-geometric -f https://data.pyg.org/whl/torch-1.10.0+cpu.html

# Make the networkx graph
G = nx.Graph()

# Add some cars (just do 4 for now)
G.add_nodes_from([
      (1, {'Brand': 'Ford'}),
      (2, {'Brand': 'Audi'}),
      (3, {'Brand': 'BMW'}),
      (4, {'Brand': 'Peugot'}),
      (5, {'Brand': 'Lexus'}),
])

# Add some edges
G.add_edges_from([
                  (1, 2), (1, 4), (1, 5),
                  (2, 3), (2, 4),
                  (3, 2), (3, 5), 
                  (4, 1), (4, 2),
                  (5, 1), (5, 3)
])

# Convert the graph into PyTorch geometric
pyg_graph = from_networkx(G)

因此,这可以正确地将 networkx 图转换为 PyTorch Geometric。但是,我仍然不知道如何正确设置标签。

每个节点的品牌价值已经转换并存储在:

pyg_graph.Brand

下面,我刚刚为每个节点制作了一些长度为 5 的随机 numpy 数组(假装这些是真实的)。

ford_prices = np.random.randint(100, size = 5)
lexus_prices = np.random.randint(100, size = 5)
audi_prices = np.random.randint(100, size = 5)
bmw_prices = np.random.randint(100, size = 5)
peugot_prices = np.random.randint(100, size = 5)

这让我想到了主要问题:

  • 如何将价格设置为该图的节点特征?
  • 如何设置节点的标签? (在训练网络时,我是否需要从 pyg_graph.Brand 中删除标签?)

提前致谢,节日快乐。

【问题讨论】:

    标签: python pytorch networkx pytorch-geometric


    【解决方案1】:

    最简单的方法是将所有信息添加到networkx图中,并以您需要的方式直接创建它。我猜你想使用一些图神经网络。然后你想要下面的东西。

    1. 您可能希望有一个分类表示,而不是作为标签的文本,例如1 代表福特。
    2. 如果你想匹配“通常的约定”。然后将输入特征命名为 x,将标签/基本事实命名为 y
    3. 将数据拆分为训练和测试是通过掩码完成的。所以该图仍然包含所有信息,但只有一部分用于训练。查看PyTorch Geometric introduction 的示例,它使用了 Cora 数据集。
    import networkx as nx
    import numpy as np
    import torch
    from torch_geometric.utils.convert import from_networkx
    
    
    # Make the networkx graph
    G = nx.Graph()
    
    # Add some cars (just do 4 for now)
    G.add_nodes_from([
          (1, {'y': 1, 'x': 0.5}),
          (2, {'y': 2, 'x': 0.2}),
          (3, {'y': 3, 'x': 0.3}),
          (4, {'y': 4, 'x': 0.1}),
          (5, {'y': 5, 'x': 0.2}),
    ])
    
    # Add some edges
    G.add_edges_from([
                      (1, 2), (1, 4), (1, 5),
                      (2, 3), (2, 4),
                      (3, 2), (3, 5),
                      (4, 1), (4, 2),
                      (5, 1), (5, 3)
    ])
    
    # Convert the graph into PyTorch geometric
    pyg_graph = from_networkx(G)
    
    print(pyg_graph)
    # Data(edge_index=[2, 12], x=[5], y=[5])
    print(pyg_graph.x)
    # tensor([0.5000, 0.2000, 0.3000, 0.1000, 0.2000])
    print(pyg_graph.y)
    # tensor([1, 2, 3, 4, 5])
    print(pyg_graph.edge_index)
    # tensor([[0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4],
    #         [1, 3, 4, 0, 2, 3, 1, 4, 0, 1, 0, 2]])
    
    
    # Split the data 
    train_ratio = 0.2
    num_nodes = pyg_graph.x.shape[0]
    num_train = int(num_nodes * train_ratio)
    idx = [i for i in range(num_nodes)]
    
    np.random.shuffle(idx)
    train_mask = torch.full_like(pyg_graph.y, False, dtype=bool)
    train_mask[idx[:num_train]] = True
    test_mask = torch.full_like(pyg_graph.y, False, dtype=bool)
    test_mask[idx[num_train:]] = True
    
    print(train_mask)
    # tensor([ True, False, False, False, False])
    print(test_mask)
    # tensor([False,  True,  True,  True,  True])
    

    【讨论】:

    • 非常感谢您的回复!这正是我一直在寻找的。你也正确地预测了我下一个关于训练面具的问题!一个快速的后续问题(也许我需要为此专门提出一个新问题?)是:您定义的掩码是否适合半监督分类任务(即我们可以访问整个图的那些,但仅限于一些标签),还是该方法在训练期间完全忽略了测试节点?
    • [EDIT:] 我们如何使用您创建的掩码来实际提取这些节点?文档使用 data.train_mask,但这不适用于此代码
    • 您可以直接使用变量test_mask/train_mask 或通过pyg_graph.train_mak = train_mask 简单地将它们“添加”到您的图表中。使用这些掩码,您将仅在训练期间使用那部分标签(但所有节点的特征)。
    猜你喜欢
    • 2023-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-26
    • 1970-01-01
    相关资源
    最近更新 更多