Node2Vec

术语表

有向

有向图特性。该算法在有向图上定义良好。

有向

有向图特性。该算法忽略图的方向。

有向

有向图特性。该算法不适用于有向图。

无向

无向图特性。该算法在无向图上定义良好。

无向

无向图特性。该算法忽略图的无向性。

异构节点

异构节点完全支持。该算法具有区分不同类型节点的能力。

异构节点

异构节点允许使用。无论标签如何,该算法对所有选定节点的处理方式相同。

异构关系

异构关系完全支持。该算法具有区分不同类型关系的能力。

异构关系

异构关系允许使用。无论类型如何,该算法对所有选定关系的处理方式相同。

加权关系

加权特性。该算法支持将关系属性用作权重,通过 relationshipWeightProperty 配置参数指定。

加权关系

加权特性。该算法将每种关系视为同等重要,丢弃任何关系权重值。

节点属性

节点属性特性。该算法利用节点属性。

Node2Vec 是一种节点嵌入算法,它基于图中的随机游走计算节点的向量表示。通过随机游走对邻域进行采样。利用大量的随机邻域样本,该算法训练一个单隐层神经网络。神经网络经过训练,可以根据另一个节点的出现情况,预测某个节点在游走中出现的可能性。

有关此算法的更多信息,请参阅

随机游走 (Random Walks)

Node2Vec 算法的一个主要概念是二阶随机游走。随机游走模拟了对图的遍历,其中遍历的路径关系是随机选择的。在经典的随机游走中,每种关系被选中的概率相同(可能加权)。这种概率不受之前访问节点的影响。然而,二阶随机游走的概念试图根据当前访问的节点 v、之前访问的节点 t 以及候选关系的搜索目标节点 x 来建模转移概率。因此,Node2Vec 随机游走受两个参数影响:returnFactorinOutFactor

  • 如果 t 等于 x,即随机游走返回到之前访问的节点时,使用 returnFactor

  • 如果从 tx 的距离等于 2,即游走进一步远离节点 t 时,使用 inOutFactor

Visuzalition of random walk parameters

在随机游走期间遍历关系的概率可以通过指定 relationshipWeightProperty 进一步受到影响。大于 1 的关系属性值将增加遍历该关系的概率,介于 0 和 1 之间的属性值将降低该概率。

对于图中的每个节点,Node2Vec 都会生成一系列以该特定节点为起点的随机游走。每个节点的随机游走次数可以通过 walkPerNode 配置参数来影响,游走长度由 walkLength 参数控制。

在机器学习流水线中的使用

目前,在机器学习流水线(如 链接预测流水线节点属性预测)中将 Node2Vec 作为节点属性步骤的使用支持力度不够,至少在最终目标是使用其嵌入来应用预测模型的情况下是这样。

为了使机器学习模型能够做出有用的预测,预测过程中产生的特征与模型训练过程中产生的特征具有相似的分布非常重要。此外,添加到流水线中的节点属性步骤(无论是否为 Node2Vec)在训练期间和训练后的模型预测期间都会执行。因此,当流水线包含一个在训练和预测期间产生过于迥异的嵌入的嵌入步骤时,就会出现问题。

Node2Vec 产生的最终嵌入取决于生成初始节点嵌入向量时的随机性,以及计算中所采用的随机游走。目前,即使设置了 randomSeed 配置参数,Node2Vec 也会产生非确定性的结果。因此,由于嵌入在多次运行之间无法保持确定性,目前不应将 Node2Vec 用作流水线中的节点属性步骤,除非其目的是实验性的且仅使用训练模式。

如果 Node2Vec 节点嵌入是在流水线之外生成的,那么将其作为流水线中的特征仍然可能是有用的,只要使用者了解不使用流水线内数据集拆分所带来的数据泄露风险。

语法

Node2Vec 各模式语法
在命名图上以流模式运行 Node2Vec。
CALL gds.node2vec.stream(
  graphName: String,
  configuration: Map
) YIELD
  nodeId: Integer,
  embedding: List of Float
表 1. 参数
名称 类型 默认 可选 描述

graphName

字符串

不适用

存储在目录中的图的名称。

配置

Map

{}

算法特定配置和/或图过滤配置。

表 2. 配置
名称 类型 默认 可选 描述

nodeLabels

字符串列表

['*']

使用给定的节点标签过滤命名图。具有任何给定标签的节点都将被包含。

relationshipTypes

字符串列表

['*']

使用给定的关系类型过滤命名图。具有任何给定类型的关系都将被包含。

concurrency

整数

4 [1]

用于运行算法的并发线程数。

jobId

字符串

内部生成

可以提供一个 ID 以更轻松地跟踪算法的进度。

logProgress

布尔值

true

如果禁用,进度百分比将不会被记录。

walkLength

整数

80

单次随机游走的步数。

walksPerNode

整数

10

为每个节点生成的随机游走次数。

inOutFactor

浮点数

1.0

随机游走倾向于停留在起始节点附近还是在图中向外扩散。值越大,越倾向于局部停留。

returnFactor

浮点数

1.0

随机游走倾向于返回上次访问的节点的程度。低于 1.0 的值表示倾向性更高。

relationshipWeightProperty

字符串

null

用作权重的关系属性名称,用于影响随机游走的概率。权重需要 >= 0。如果未指定,算法将以无权重方式运行。

windowSize

整数

10

训练神经网络时上下文窗口的大小。

negativeSamplingRate

整数

5

为每个正样本生成的负样本数量。

positiveSamplingFactor

浮点数

0.001

影响正样本分布的因子。值越高,高频节点被下采样的概率就越大。

negativeSamplingExponent

浮点数

0.75

应用于节点频率以获得负采样分布的指数。值为 1.0 时与频率成比例采样。值为 0.0 时对每个节点进行等概率采样。

embeddingDimension

整数

128

计算出的节点嵌入的大小。

embeddingInitializer

字符串

NORMALIZED

初始化嵌入的方法。值从 [-a, a] 范围内均匀采样。使用 NORMALIZED 时,a=0.5/embeddingDimension;而使用 UNIFORM 时,a=1

iterations (迭代次数)

整数

1

训练迭代次数。迭代次数越高,采样的随机游走就越多,因此游走集通常会更能代表整个图。

initialLearningRate

浮点数

0.01

最初用于训练神经网络的学习率。学习率在每次训练迭代后会降低。

minLearningRate

浮点数

0.0001

训练期间学习率降低时的下限。

randomSeed

整数

random

用于生成随机游走的种子值,这些游走被用作神经网络的训练集。请注意,生成的嵌入仍然是非确定性的。

walkBufferSize

整数

1000

开始训练前要完成的随机游走次数。

1. 在 GDS 会话 中,默认值为可用处理器数量。

表 3. 结果
名称 类型 描述

nodeId

整数

Neo4j 节点 ID。

embedding

浮点数列表

计算出的节点嵌入。

在存储于目录中的图上以变更模式 (mutate mode) 运行 Node2Vec。
CALL gds.node2vec.mutate(
  graphName: String,
  configuration: Map
)
YIELD
  preProcessingMillis: Integer,
  computeMillis: Integer,
  postProcessingMillis: Integer,
  mutateMillis: Integer,
  nodeCount: Integer,
  nodePropertiesWritten: Integer,
  lossPerIteration: List of Float,
  configuration: Map
表 4. 参数
名称 类型 默认 可选 描述

graphName

字符串

不适用

存储在目录中的图的名称。

配置

Map

{}

算法特定配置和/或图过滤配置。

表 5. 配置
名称 类型 默认 可选 描述

mutateProperty

字符串

不适用

GDS 图中写入嵌入的节点属性。

nodeLabels

字符串列表

['*']

使用给定的节点标签过滤命名图。

relationshipTypes

字符串列表

['*']

使用给定的关系类型过滤命名图。

concurrency

整数

4

用于运行算法的并发线程数。

logProgress

布尔值

true

如果禁用,进度百分比将不会被记录。

jobId

字符串

内部生成

可以提供一个 ID 以更轻松地跟踪算法的进度。

walkLength

整数

80

单次随机游走的步数。

walksPerNode

整数

10

为每个节点生成的随机游走次数。

inOutFactor

浮点数

1.0

随机游走倾向于停留在起始节点附近还是在图中向外扩散。值越大,越倾向于局部停留。

returnFactor

浮点数

1.0

随机游走倾向于返回上次访问的节点的程度。低于 1.0 的值表示倾向性更高。

relationshipWeightProperty

字符串

null

用作权重的关系属性名称,用于影响随机游走的概率。权重需要 >= 0。如果未指定,算法将以无权重方式运行。

windowSize

整数

10

训练神经网络时上下文窗口的大小。

negativeSamplingRate

整数

5

为每个正样本生成的负样本数量。

positiveSamplingFactor

浮点数

0.001

影响正样本分布的因子。值越高,高频节点被下采样的概率就越大。

negativeSamplingExponent

浮点数

0.75

应用于节点频率以获得负采样分布的指数。值为 1.0 时与频率成比例采样。值为 0.0 时对每个节点进行等概率采样。

embeddingDimension

整数

128

计算出的节点嵌入的大小。

embeddingInitializer

字符串

NORMALIZED

初始化嵌入的方法。值从 [-a, a] 范围内均匀采样。使用 NORMALIZED 时,a=0.5/embeddingDimension;而使用 UNIFORM 时,a=1

iterations (迭代次数)

整数

1

训练迭代次数。迭代次数越高,采样的随机游走就越多,因此游走集通常会更能代表整个图。

initialLearningRate

浮点数

0.01

最初用于训练神经网络的学习率。学习率在每次训练迭代后会降低。

minLearningRate

浮点数

0.0001

训练期间学习率降低时的下限。

randomSeed

整数

random

用于生成随机游走的种子值,这些游走被用作神经网络的训练集。请注意,生成的嵌入仍然是非确定性的。

walkBufferSize

整数

1000

开始训练前要完成的随机游走次数。

表 6. 结果
名称 类型 描述

nodeCount

整数

处理的节点数量。

nodePropertiesWritten

整数

写入的节点属性数。

preProcessingMillis

整数

预处理数据的毫秒数。

computeMillis

整数

运行算法的毫秒数。

mutateMillis

整数

向投影图添加属性的毫秒数。

postProcessingMillis

整数

结果后处理的耗时(毫秒)。

lossPerIteration

浮点数列表

每次训练迭代中记录的损失总和。

配置

Map

用于运行算法的配置。

在存储于目录中的图上以写入模式 (write mode) 运行 Node2Vec。
CALL gds.node2vec.write(
  graphName: String,
  configuration: Map
)
YIELD
  preProcessingMillis: Integer,
  computeMillis: Integer,
  writeMillis: Integer,
  nodeCount: Integer,
  nodePropertiesWritten: Integer,
  lossPerIteration: List of Float,
  configuration: Map
表 7. 参数
名称 类型 默认 可选 描述

graphName

字符串

不适用

存储在目录中的图的名称。

配置

Map

{}

算法特定配置和/或图过滤配置。

表 8. 配置
名称 类型 默认 可选 描述

nodeLabels

字符串列表

['*']

使用给定的节点标签过滤命名图。具有任何给定标签的节点都将被包含。

relationshipTypes

字符串列表

['*']

使用给定的关系类型过滤命名图。具有任何给定类型的关系都将被包含。

concurrency

整数

4 [2]

用于运行算法的并发线程数。

jobId

字符串

内部生成

可以提供一个 ID 以更轻松地跟踪算法的进度。

logProgress

布尔值

true

如果禁用,进度百分比将不会被记录。

writeConcurrency

整数

'concurrency' 的值

用于将结果写入 Neo4j 的并发线程数。

writeProperty

字符串

不适用

Neo4j 数据库中写入嵌入的节点属性。

walkLength

整数

80

单次随机游走的步数。

walksPerNode

整数

10

为每个节点生成的随机游走次数。

inOutFactor

浮点数

1.0

随机游走倾向于停留在起始节点附近还是在图中向外扩散。值越大,越倾向于局部停留。

returnFactor

浮点数

1.0

随机游走倾向于返回上次访问的节点的程度。低于 1.0 的值表示倾向性更高。

relationshipWeightProperty

字符串

null

用作权重的关系属性名称,用于影响随机游走的概率。权重需要 >= 0。如果未指定,算法将以无权重方式运行。

windowSize

整数

10

训练神经网络时上下文窗口的大小。

negativeSamplingRate

整数

5

为每个正样本生成的负样本数量。

positiveSamplingFactor

浮点数

0.001

影响正样本分布的因子。值越高,高频节点被下采样的概率就越大。

negativeSamplingExponent

浮点数

0.75

应用于节点频率以获得负采样分布的指数。值为 1.0 时与频率成比例采样。值为 0.0 时对每个节点进行等概率采样。

embeddingDimension

整数

128

计算出的节点嵌入的大小。

embeddingInitializer

字符串

NORMALIZED

初始化嵌入的方法。值从 [-a, a] 范围内均匀采样。使用 NORMALIZED 时,a=0.5/embeddingDimension;而使用 UNIFORM 时,a=1

iterations (迭代次数)

整数

1

训练迭代次数。迭代次数越高,采样的随机游走就越多,因此游走集通常会更能代表整个图。

initialLearningRate

浮点数

0.01

最初用于训练神经网络的学习率。学习率在每次训练迭代后会降低。

minLearningRate

浮点数

0.0001

训练期间学习率降低时的下限。

randomSeed

整数

random

用于生成随机游走的种子值,这些游走被用作神经网络的训练集。请注意,生成的嵌入仍然是非确定性的。

walkBufferSize

整数

1000

开始训练前要完成的随机游走次数。

2. 在 GDS 会话 中,默认值为可用处理器数量。

表 9. 结果
名称 类型 描述

nodeCount

整数

处理的节点数量。

nodePropertiesWritten

整数

写入的节点属性数。

preProcessingMillis

整数

预处理数据的毫秒数。

computeMillis

整数

运行算法的毫秒数。

writeMillis

整数

将结果数据写回 Neo4j 的毫秒数。

lossPerIteration

浮点数列表

每次训练迭代中记录的损失总和。

配置

Map

用于运行算法的配置。

示例

以下所有示例应在空数据库中运行。

这些示例均使用 Cypher 投影 作为标准。原生投影将在未来版本中被弃用。

考虑由以下 Cypher 语句创建的图

CREATE (alice:Person {name: 'Alice'})
CREATE (bob:Person {name: 'Bob'})
CREATE (carol:Person {name: 'Carol'})
CREATE (dave:Person {name: 'Dave'})
CREATE (eve:Person {name: 'Eve'})
CREATE (guitar:Instrument {name: 'Guitar'})
CREATE (synth:Instrument {name: 'Synthesizer'})
CREATE (bongos:Instrument {name: 'Bongos'})
CREATE (trumpet:Instrument {name: 'Trumpet'})

CREATE (alice)-[:LIKES]->(guitar)
CREATE (alice)-[:LIKES]->(synth)
CREATE (alice)-[:LIKES]->(bongos)
CREATE (bob)-[:LIKES]->(guitar)
CREATE (bob)-[:LIKES]->(synth)
CREATE (carol)-[:LIKES]->(bongos)
CREATE (dave)-[:LIKES]->(guitar)
CREATE (dave)-[:LIKES]->(synth)
CREATE (dave)-[:LIKES]->(bongos);
MATCH (source:Person)-[r:LIKES]->(target:Instrument)
RETURN gds.graph.project(
  'myGraph',
  source,
  target
)
myGraph 上运行 Node2Vec 算法
CALL gds.node2vec.stream('myGraph', {embeddingDimension: 2})
YIELD nodeId, embedding
RETURN nodeId, embedding
表 10. 结果
nodeId embedding

0

[-0.14295829832553864, 0.08884537220001221]

1

[0.016700705513358116, 0.2253911793231964]

2

[-0.06589698046445847, 0.042405471205711365]

3

[0.05862073227763176, 0.1193704605102539]

4

[0.10888434946537018, -0.18204474449157715]

5

[0.16728264093399048, 0.14098615944385529]

6

[-0.007779224775731564, 0.02114257402718067]

7

[-0.213893860578537, 0.06195802614092827]

8

[0.2479933649301529, -0.137322798371315]