拆分关系

简介

“拆分关系”算法是一种用于预处理图以进行模型训练的工具算法。它将关系拆分为保留集 (holdout set) 和剩余集 (remaining set)。保留集被分为两类:正样本(即现有的关系)和负样本(即不存在的关系)。类别通过关系上的 label 属性来指示。这使得保留集能够用于训练或测试机器学习模型。保留集和剩余集中的关系都会被添加到投影图中。

如果指定了配置选项 relationshipWeightProperty,则相应的关系属性会保留在剩余集的关系中。但请注意,保留集仅包含 label 属性;由于保留集还包含负样本,因此无法在保留集上导出关系权重。

语法

本节介绍在每种执行模式下运行“拆分关系”算法所使用的语法。此处描述的是命名图变体的语法。要了解有关通用语法变体的更多信息,请参阅 语法概述

各模式下的拆分关系语法
在命名图上以 mutate 模式运行“拆分关系”。
CALL gds.splitRelationships.mutate(
  graphName: String,
  configuration: Map
)
YIELD
  preProcessingMillis: Integer,
  computeMillis: Integer,
  mutateMillis: Integer,
  relationshipsWritten: Integer,
  configuration: Map
表 1. 参数
名称 类型 默认 可选 描述

graphName

字符串

不适用

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

配置

Map

{}

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

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

sourceNodeLabels(源节点标签)

字符串列表

['*']

过滤 sourceNode 至少具有其中一个 sourceNodeLabels 的关系。

targetNodeLabels(目标节点标签)

字符串列表

['*']

过滤 targetNode 至少具有其中一个 targetNodeLabels 的关系。

relationshipTypes

字符串列表

['*']

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

concurrency

整数

4 [1]

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

jobId

字符串

内部生成

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

logProgress

布尔值

true

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

holdoutFraction

浮点数

不适用

用作保留集的有效关系的比例。剩余的 1 - holdoutFraction 的有效关系将被添加到剩余集中。

negativeSamplingRatio

浮点数

不适用

保留集中负样本与正样本的期望比例。

holdoutRelationshipType

字符串

不适用

用于保留集的关系类型。每种关系都有一个 label 属性,用于指示它是正样本还是负样本。

remainingRelationshipType

字符串

不适用

节点不包含任何源标签或目标标签的关系将被忽略。所有无效关系都将添加到剩余集中。

nonNegativeRelationshipTypes

字符串列表

不适用

不用于负采样的其他关系类型。

relationshipWeightProperty

字符串

null

remainingRelationshipType 继承的关系属性名称。

randomSeed

整数

不适用

用于随机选择关系的可选种子值。

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

表 3. 结果
名称 类型 描述

preProcessingMillis

整数

预处理数据的毫秒数。

computeMillis

整数

运行算法的毫秒数。

mutateMillis

整数

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

relationshipsWritten

整数

算法创建的关系数量。

配置

Map

用于运行算法的配置。

示例

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

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

在本节中,我们将展示在具体图上运行“拆分关系”算法的示例。目的是说明结果的样子,并提供在实际环境中使用该算法的指南。我们将在一个由少数节点按特定模式连接的小型图上进行演示。示例图如下所示

Visualization of the example graph

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

CREATE
    (n0:Label),
    (n1:Label),
    (n2:Label),
    (n3:Label),
    (n4:Label),
    (n5:Label),

    (n0)-[:TYPE { prop: 0} ]->(n1),
    (n1)-[:TYPE { prop: 1} ]->(n2),
    (n2)-[:TYPE { prop: 4} ]->(n3),
    (n3)-[:TYPE { prop: 9} ]->(n4),
    (n4)-[:TYPE { prop: 16} ]->(n5)

给定上述图,我们希望将 20% 的关系用作保留集。保留集将被分为两个大小相等的类别:正类和负类。正关系将从现有关系中随机选择,并标记为 label: 1。负关系将随机生成(即它们在输入图中不存在),并标记为 label: 0

MATCH (source:Label)-[r:TYPE]->(target:Label)
RETURN gds.graph.project(
  'graph',
  source,
  target,
  {
    sourceNodeLabels: ['Label'],
    targetNodeLabels: ['Label'],
    relationshipType: 'TYPE'
  },
  { undirectedRelationshipTypes: ['TYPE'] }
)

现在,我们可以通过指定适当的比例和输出关系类型来运行该算法。我们使用随机种子值以产生确定性的结果。

CALL gds.splitRelationships.mutate('graph', {
    holdoutRelationshipType: 'TYPE_HOLDOUT',
    remainingRelationshipType: 'TYPE_REMAINING',
    holdoutFraction: 0.2,
    negativeSamplingRatio: 1.0,
    randomSeed: 1337
}) YIELD relationshipsWritten
表 4. 结果
relationshipsWritten

10

输入图由 5 个关系组成。我们使用 20%(1 个关系)的关系来创建 'TYPE_HOLDOUT' 关系类型(保留集)。这创建了 1 个带有正标签的关系。由于 negativeSamplingRatio 的设置,还会创建一个带有负标签的关系。最后,使用剩余的 80%(4 个关系)形成 TYPE_REMAINING 关系类型。这些关系以 UNDIRECTED(无向)方向写入,这相当于写入了 8 个关系。

当按 TESTTRAIN 关系过滤时,变异后的图将如下所示。
CREATE
    (n0:Label),
    (n1:Label),
    (n2:Label),
    (n3:Label),
    (n4:Label),
    (n5:Label),

    (n2)-[:TYPE_HOLDOUT { label: 0 } ]->(n5), // negative, non-existing
    (n3)-[:TYPE_HOLDOUT { label: 1 } ]->(n2), // positive, existing

    (n0)<-[:TYPE_REMAINING { prop: 0} ]-(n1),
    (n1)<-[:TYPE_REMAINING { prop: 1} ]-(n2),
    (n3)<-[:TYPE_REMAINING { prop: 9} ]-(n4),
    (n4)<-[:TYPE_REMAINING { prop: 16} ]-(n5),
    (n0)-[:TYPE_REMAINING { prop: 0} ]->(n1),
    (n1)-[:TYPE_REMAINING { prop: 1} ]->(n2),
    (n3)-[:TYPE_REMAINING { prop: 9} ]->(n4),
    (n4)-[:TYPE_REMAINING { prop: 16} ]->(n5)