GraphSAGE 节点嵌入训练

GraphSAGE 可用作无监督算法,用于为图中的节点生成嵌入。本页面提供了关于如何使用 GraphSAGE 节点嵌入训练端点的说明。

语法

本节涵盖了用于执行 GraphSAGE 节点嵌入训练算法的语法。

运行 GraphSAGE 节点嵌入训练。
CALL graph.gs_unsup_train(
  'CPU_X64_XS',                    (1)
  {
    ['defaultTablePrefix': '...',] (2)
    'project': {...},              (3)
    'compute': {...},              (4)
  }
);
1 计算池选择器。
2 表引用的可选前缀。
3 项目配置。
4 计算配置。
表 1. 参数
名称 类型 默认 可选 描述

computePoolSelector

字符串

不适用

用于运行 GraphSAGE 节点嵌入训练任务的计算池选择器。

配置

Map

{}

用于图项目、算法计算和结果回写的配置。

对于此算法,我们强烈建议使用 GPU 计算池,除非数据集非常小且模型层数较浅。

配置映射由以下三个条目组成。

有关下方项目(Project)配置的更多详细信息,请参阅 项目文档
表 2. 项目配置
名称 类型

nodeTables

节点表列表。

relationshipTables

关系类型到关系表的映射。

请注意,为了使 GraphSAGE 能够正确传播节点嵌入(node embeddings)的更新,每种类型的节点必须至少是某种关系类型的目标。`orientation` 参数有助于为仅作为关系源的节点类型添加反向关系(使用 "REVERSE" 或 "UNDIRECTED" 方向)。

表 3. 计算配置
名称 类型 默认 可选 描述

numWalks

整数

10

对图中每个节点执行的随机游走次数

walkDepth

整数

3

每次随机游走的步数

negSamplingRatio

浮点数

1.0

训练时负样本与正样本的采样比例

modelname

字符串

不适用

要训练的模型名称(必须唯一)

numEpochs

整数

不适用

训练模型的轮数(epoch)

numSamples

整数列表

不适用

每一层采样的邻居数量。注意,这也决定了层数

hiddenChannels

整数

256

模型层输出的节点嵌入维度

activation

字符串

"relu"

要使用的激活函数。有效值为 "relu" 和 "sigmoid"

aggregator

字符串

"mean"

要使用的邻域嵌入聚合器。有效值为 "mean" 和 "max"

learningRate

浮点数

0.001

优化器的学习率

dropout

浮点数

0.1

每一层的丢弃(dropout)概率。必须是 >= 0.0 且 < 1.0 的值

layerNormalization

布尔值

true

是否在模型层之间应用层归一化

epochsPerCheckpoint

整数

max(numEpochs / 10, 1)

保存模型检查点之间的轮数

randomSeed

整数

随机整数

用于初始化计算中所有随机性的数字

batchSize

整数

自动推断

每个批次训练的目标节点数量。如果不提供,算法将根据可用内存的限制自动推断允许的最大批次大小

lossReduction

字符串

自动推断

应用于损失函数的缩减方法。有效值为 "mean" 和 "sum"。如果不提供,若显式指定了 batchSize,则缩减方法默认为 "mean",否则为 "sum"

示例

在我们的示例中,我们将使用包含演员、导演、电影和类型(genre)的 IMDB 数据集。这些实体都有与之关联的关键词,我们将把这些关键词用作节点的特征。它们通过电影演员关系(演员出演电影)和电影导演关系(导演执导电影)连接。

我们有一个名为 imdb 的数据库,其中包含以下表:

  • actor,具有 nodeidplot_keywords

  • 具有 nodeidplot_keywords 列的 movie

  • director,具有 nodeidplot_keywords

  • acted_in,具有 sourcenodeidtargetnodeid 列,代表 actormovie 节点的 ID

  • directed_in,具有 sourcenodeidtargetnodeid 列,代表 directormovie 节点的 ID

plot_keywords 列包含与节点关联的关键词,编码为浮点数向量。

您可以按照 GitHub 上的说明将此数据集上传到您的 Snowflake 账户:neo4j-product-examples/snowflake-graph-analytics

训练查询

在以下查询中,我们针对该数据集训练了一个用于节点嵌入的 GraphSAGE 模型 [1]

我们训练 10 个 epoch,并使用两个隐藏层。

要运行查询,需要为应用程序、消费者角色和环境进行必要的权限授予设置。请参阅 入门 页面以了解更多信息。

我们还假设应用程序名称为默认的 Neo4j_Graph_Analytics。如果您在安装过程中选择了不同的应用程序名称,请将其替换为该名称。

CALL Neo4j_Graph_Analytics.graph.gs_unsup_train('GPU_NV_S', {
    'defaultTablePrefix': 'imdb.gml',
    'project': {
        'nodeTables': ['actor', 'director', 'movie'],
        'relationshipTables': {
            'acted_in': {
                'sourceTable': 'actor',
                'targetTable': 'movie',
                'orientation': 'UNDIRECTED'
            },
            'directed_in': {
                'sourceTable': 'director',
                'targetTable': 'movie',
                'orientation': 'UNDIRECTED'
            }
        }
    },
    'compute': {
        'modelname': 'unsup-imdb',
        'numEpochs': 10,
        'numSamples': [20, 20]
    }
});

上述查询应产生包含以下任务结果的行。

JOB_ID JOB_STATUS JOB_START JOB_END JOB_RESULT

job_ad80ec62c6d14d35af903b1a1de719b6

SUCCESS

2025-11-28T15:00:19.283957

2025-11-28T15:04:35.928856

 {
  "gs_unsup_train": {
    "train_ms": 247120
  },
  "project": {
    "graphName": "snowgraph",
    "nodeCount": 12772,
    "nodeLabels": {
      "ACTOR": {
        "count": 5841,
        "nodeId": {
          "dataType": "int16"
        },
        "properties": {
          "plot_keywords": {
            "dataType": "ndarray[float32]",
            "dimension": 1256
          }
        },
        "table": "IMDB.GML.ACTOR"
      },
      "DIRECTOR": {
        "count": 2270,
        "nodeId": {
          "dataType": "int16"
        },
        "properties": {
          "plot_keywords": {
            "dataType": "ndarray[float32]",
            "dimension": 1256
          }
        },
        "table": "IMDB.GML.DIRECTOR"
      },
      "MOVIE": {
        "count": 4661,
        "nodeId": {
          "dataType": "int16"
        },
        "properties": {
          "plot_keywords": {
            "dataType": "ndarray[float32]",
            "dimension": 1256
          }
        },
        "table": "IMDB.GML.MOVIE"
      }
    },
    "nodeMillis": 2252,
    "relationshipCount": 18644,
    "relationshipMillis": 269,
    "relationshipTypes": {
      "ACTED_IN": {
        "count": 13983,
        "direction": "UNDIRECTED",
        "sourceTable": "IMDB.GML.ACTOR",
        "table": "IMDB.GML.ACTED_IN",
        "targetTable": "IMDB.GML.MOVIE"
      },
      "DIRECTED_IN": {
        "count": 4661,
        "direction": "UNDIRECTED",
        "sourceTable": "IMDB.GML.DIRECTOR",
        "table": "IMDB.GML.DIRECTED_IN",
        "targetTable": "IMDB.GML.MOVIE"
      }
    },
    "totalMillis": 2521
  }
}

1. 在计算嵌入时,我们不希望使用电影的 genre 属性,因为并非所有电影都有类型,而且使用类型会使嵌入不适合用于预测电影类型。删除 genre 属性的方法是创建一个 movie 表的 Snowflake 视图,并仅选择 nodeidplot_keywords 列。此外,记得授予应用程序对更新后的电影视图的 SELECT 权限。为了简单起见,我们保留名称 movie 并假设它没有 genre 列。