节点相似度

本节介绍 Neo4j 图数据科学库中的节点相似度算法。该算法基于 Jaccard 和 Overlap 相似度指标。

术语表

有向

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

有向

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

有向

有向特征。该算法不在有向图上运行。

无向

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

无向

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

异构节点

异构节点 充分支持。该算法能够区分不同类型的节点。

异构节点

异构节点 允许。该算法将所有选定的节点视为相同,而不管其标签。

异构关系

异构关系 充分支持。该算法能够区分不同类型的关系。

异构关系

异构关系 允许。该算法将所有选定的关系视为相同,而不管其类型。

加权关系

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

加权关系

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

介绍

节点相似度算法根据节点连接到的节点比较一组节点。如果两个节点共享许多相同的邻居,则认为这两个节点相似。节点相似度根据 Jaccard 指标(也称为 Jaccard 相似度得分)、Overlap 系数(也称为 Szymkiewicz–Simpson 系数)和 Cosine 相似度得分计算成对相似度。前两个最常与非加权集相关联,而 Cosine 与加权输入相关联。

给定两个集合 AB,Jaccard 相似度使用以下公式计算

jacard nodesim

Overlap 系数使用以下公式计算

overlap nodesim

加权情况下的公式可以在 下面的加权示例中找到

余弦相似度得分使用以下公式计算,其中当 A、B 非加权时,条目隐式地被赋予 1 的权重

cos

该算法的输入是一个包含两个不相交节点集的二部图。每个关系都从第一个节点集中的一个节点开始,并以第二个节点集中的一个节点结束。

节点相似度算法比较每个具有出站关系的节点与其他具有出站关系的节点。对于每个节点 n,我们收集该节点的出站邻域 N(n),即所有节点 m,其中存在从 nm 的关系。对于每对 nm,算法计算该对的相似度,该相似度等于 N(n)N(m) 的选定相似度度量的结果。

节点相似度的时间复杂度为 O(n3),空间复杂度为 O(n2)。我们在时间和空间 O(n2) 内计算和存储邻居集,然后在时间 O(n3) 内计算成对相似度得分。

为了限制内存使用,您可以指定每个节点输出的结果数量的显式限制,这就是“topK”参数。它可以设置为除 0 之外的任何值。当然,您会在整体计算中损失精度,运行时间不受影响 - 我们仍然需要在可能丢弃结果之前计算结果。

算法的输出是第一个节点集对之间的新关系。相似度得分通过关系属性表示。

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

也可以对产生的相似对中的源节点和/或目标节点应用过滤。您可以考虑使用 过滤后的节点相似度 算法来实现此目的。

运行此算法需要足够的可用内存。在运行此算法之前,建议您阅读 内存估计

语法

本节介绍在每种执行模式下执行节点相似度算法时使用的语法。我们正在描述命名的图语法变体。要了解有关一般语法变体的更多信息,请参见 语法概述

每种模式的节点相似度语法
在命名图上以流模式运行节点相似度。
CALL gds.nodeSimilarity.stream(
  graphName: String,
  configuration: Map
) YIELD
  node1: Integer,
  node2: Integer,
  similarity: Float
表 1. 参数
名称 类型 默认值 可选 描述

graphName

字符串

n/a

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

configuration

映射

{}

针对算法特定内容和/或图过滤的配置。

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

nodeLabels

字符串列表

['*']

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

relationshipTypes

字符串列表

['*']

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

concurrency

整数

4

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

jobId

字符串

内部生成

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

logProgress

布尔值

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

similarityCutoff

浮点数

1e-42

结果中存在的相似度得分的下限。值必须在 0 到 1 之间。

degreeCutoff

整数

1

节点度数的包含下限,用于在比较中考虑节点。此值不能低于 1。

upperDegreeCutoff

整数

2147483647

节点度数的包含上限,用于在比较中考虑节点。此值不能低于 1。

topK

整数

10

每个节点的得分限制。返回 K 个最大的结果。此值不能低于 1。

bottomK

整数

10

每个节点的得分限制。返回 K 个最小的结果。此值不能低于 1。

topN

整数

0

计算的得分总数的全局限制。返回 N 个最大的总结果。此值不能为负,值为 0 表示没有全局限制。

bottomN

整数

0

计算的得分总数的全局限制。返回 N 个最小的总结果。此值不能为负,值为 0 表示没有全局限制。

relationshipWeightProperty

字符串

用作权重的关系属性的名称。如果未指定,则算法将无权重运行。

similarityMetric

字符串

JACCARD

用于计算相似度的度量。可以是 JACCARDOVERLAPCOSINE

useComponents

布尔值或字符串

如果启用,节点相似度将使用组件来提高计算性能,跳过不同组件中节点的比较。设置为 false(默认):算法不使用组件,而是计算整个图的相似度。设置为 true:算法使用组件,并将计算这些组件,然后计算相似度。设置为 **字符串**:使用存储在图中的预计算组件,**字符串** 是表示组件的节点属性的键。

表 3. 结果
名称 类型 描述

node1

整数

第一个节点的节点 ID。

node2

整数

第二个节点的节点 ID。

similarity

浮点数

两个节点的相似度得分。

在命名图上以统计模式运行节点相似度。
CALL gds.nodeSimilarity.stats(
  graphName: String,
  configuration: Map
)
YIELD
  preProcessingMillis: Integer,
  computeMillis: Integer,
  postProcessingMillis: Integer,
  nodesCompared: Integer,
  similarityPairs: Integer,
  similarityDistribution: Map,
  configuration: Map
表 4. 参数
名称 类型 默认值 可选 描述

graphName

字符串

n/a

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

configuration

映射

{}

针对算法特定内容和/或图过滤的配置。

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

nodeLabels

字符串列表

['*']

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

relationshipTypes

字符串列表

['*']

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

concurrency

整数

4

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

jobId

字符串

内部生成

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

logProgress

布尔值

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

similarityCutoff

浮点数

1e-42

结果中存在的相似度得分的下限。值必须在 0 到 1 之间。

degreeCutoff

整数

1

节点度数的包含下限,用于在比较中考虑节点。此值不能低于 1。

upperDegreeCutoff

整数

2147483647

节点度数的包含上限,用于在比较中考虑节点。此值不能低于 1。

topK

整数

10

每个节点的得分限制。返回 K 个最大的结果。此值不能低于 1。

bottomK

整数

10

每个节点的得分限制。返回 K 个最小的结果。此值不能低于 1。

topN

整数

0

计算的得分总数的全局限制。返回 N 个最大的总结果。此值不能为负,值为 0 表示没有全局限制。

bottomN

整数

0

计算的得分总数的全局限制。返回 N 个最小的总结果。此值不能为负,值为 0 表示没有全局限制。

relationshipWeightProperty

字符串

用作权重的关系属性的名称。如果未指定,则算法将无权重运行。

similarityMetric

字符串

JACCARD

用于计算相似度的度量。可以是 JACCARDOVERLAPCOSINE

useComponents

布尔值或字符串

如果启用,节点相似度将使用组件来提高计算性能,跳过不同组件中节点的比较。设置为 false(默认):算法不使用组件,而是计算整个图的相似度。设置为 true:算法使用组件,并将计算这些组件,然后计算相似度。设置为 **字符串**:使用存储在图中的预计算组件,**字符串** 是表示组件的节点属性的键。

表 6. 结果
名称 类型 描述

preProcessingMillis

整数

预处理数据的毫秒数。

computeMillis

整数

运行算法的毫秒数。

postProcessingMillis

整数

计算组件计数和分布统计信息的毫秒数。

nodesCompared

整数

计算相似度的节点数。

similarityPairs

整数

结果中相似度的数量。

similarityDistribution

映射

包含 min、max、mean 以及 p50、p75、p90、p95、p99 和 p999 百分位数值的映射,这些值是计算的相似度结果。

configuration

映射

用于运行算法的配置。

在存储在目录中的图上以变异模式运行节点相似度。
CALL gds.nodeSimilarity.mutate(
  graphName: String,
  configuration: Map
)
YIELD
  preProcessingMillis: Integer,
  computeMillis: Integer,
  mutateMillis: Integer,
  postProcessingMillis: Integer,
  relationshipsWritten: Integer,
  nodesCompared: Integer,
  similarityDistribution: Map,
  configuration: Map
表 7. 参数
名称 类型 默认值 可选 描述

graphName

字符串

n/a

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

configuration

映射

{}

针对算法特定内容和/或图过滤的配置。

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

mutateRelationshipType

字符串

n/a

写入投影图的新关系使用的关系类型。

mutateProperty

字符串

n/a

GDS 图中写入相似度得分的关联属性。

nodeLabels

字符串列表

['*']

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

relationshipTypes

字符串列表

['*']

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

concurrency

整数

4

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

jobId

字符串

内部生成

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

similarityCutoff

浮点数

1e-42

结果中存在的相似度得分的下限。值必须在 0 到 1 之间。

degreeCutoff

整数

1

节点度数的包含下限,用于在比较中考虑节点。此值不能低于 1。

upperDegreeCutoff

整数

2147483647

节点度数的包含上限,用于在比较中考虑节点。此值不能低于 1。

topK

整数

10

每个节点的得分限制。返回 K 个最大的结果。此值不能低于 1。

bottomK

整数

10

每个节点的得分限制。返回 K 个最小的结果。此值不能低于 1。

topN

整数

0

计算的得分总数的全局限制。返回 N 个最大的总结果。此值不能为负,值为 0 表示没有全局限制。

bottomN

整数

0

计算的得分总数的全局限制。返回 N 个最小的总结果。此值不能为负,值为 0 表示没有全局限制。

relationshipWeightProperty

字符串

用作权重的关系属性的名称。如果未指定,则算法将无权重运行。

similarityMetric

字符串

JACCARD

用于计算相似度的度量。可以是 JACCARDOVERLAPCOSINE

useComponents

布尔值或字符串

如果启用,节点相似度将使用组件来提高计算性能,跳过不同组件中节点的比较。设置为 false(默认):算法不使用组件,而是计算整个图的相似度。设置为 true:算法使用组件,并将计算这些组件,然后计算相似度。设置为 **字符串**:使用存储在图中的预计算组件,**字符串** 是表示组件的节点属性的键。

表 9. 结果
名称 类型 描述

preProcessingMillis

整数

预处理数据的毫秒数。

computeMillis

整数

运行算法的毫秒数。

mutateMillis

整数

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

postProcessingMillis

整数

计算百分位的毫秒数。

nodesCompared

整数

计算相似度的节点数。

relationshipsWritten

整数

创建的关系数。

similarityDistribution

映射

包含 min、max、mean、stdDev 以及 p1、p5、p10、p25、p75、p90、p95、p99、p100 百分位数值的映射,这些值是计算的相似度结果。

configuration

映射

用于运行算法的配置。

在存储在目录中的图上以写入模式运行节点相似度。
CALL gds.nodeSimilarity.write(
  graphName: String,
  configuration: Map
)
YIELD
  preProcessingMillis: Integer,
  computeMillis: Integer,
  writeMillis: Integer,
  postProcessingMillis: Integer,
  nodesCompared: Integer,
  relationshipsWritten: Integer,
  similarityDistribution: Map,
  configuration: Map
表 10. 参数
名称 类型 默认值 可选 描述

graphName

字符串

n/a

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

configuration

映射

{}

针对算法特定内容和/或图过滤的配置。

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

nodeLabels

字符串列表

['*']

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

relationshipTypes

字符串列表

['*']

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

concurrency

整数

4

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

jobId

字符串

内部生成

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

logProgress

布尔值

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

writeConcurrency

整数

'concurrency' 的值

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

writeRelationshipType

字符串

n/a

用于将计算出的关系持久化到 Neo4j 数据库中的关系类型。

writeProperty

字符串

n/a

写入 Neo4j 数据库中相似度得分的关联属性。

similarityCutoff

浮点数

1e-42

结果中存在的相似度得分的下限。值必须在 0 到 1 之间。

degreeCutoff

整数

1

节点度数的包含下限,用于在比较中考虑节点。此值不能低于 1。

upperDegreeCutoff

整数

2147483647

节点度数的包含上限,用于在比较中考虑节点。此值不能低于 1。

topK

整数

10

每个节点的得分限制。返回 K 个最大的结果。此值不能低于 1。

bottomK

整数

10

每个节点的得分限制。返回 K 个最小的结果。此值不能低于 1。

topN

整数

0

计算的得分总数的全局限制。返回 N 个最大的总结果。此值不能为负,值为 0 表示没有全局限制。

bottomN

整数

0

计算的得分总数的全局限制。返回 N 个最小的总结果。此值不能为负,值为 0 表示没有全局限制。

relationshipWeightProperty

字符串

用作权重的关系属性的名称。如果未指定,则算法将无权重运行。

similarityMetric

字符串

JACCARD

用于计算相似度的度量。可以是 JACCARDOVERLAPCOSINE

useComponents

布尔值或字符串

如果启用,节点相似度将使用组件来提高计算性能,跳过不同组件中节点的比较。设置为 false(默认):算法不使用组件,而是计算整个图的相似度。设置为 true:算法使用组件,并将计算这些组件,然后计算相似度。设置为 **字符串**:使用存储在图中的预计算组件,**字符串** 是表示组件的节点属性的键。

表 12. 结果
名称 类型 描述

preProcessingMillis

整数

预处理数据的毫秒数。

computeMillis

整数

运行算法的毫秒数。

writeMillis

整数

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

postProcessingMillis

整数

计算百分位的毫秒数。

nodesCompared

整数

计算相似度的节点数。

relationshipsWritten

整数

创建的关系数。

similarityDistribution

映射

包含 min、max、mean、stdDev 以及 p1、p5、p10、p25、p75、p90、p95、p99、p100 百分位数值的映射,这些值是计算的相似度结果。

configuration

映射

用于运行算法的配置。

示例

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

示例使用 Cypher 投影 作为规范。原生投影将在未来的版本中被弃用。

在本节中,我们将展示在具体图上运行节点相似度算法的示例。目的是说明结果的外观并提供在实际环境中使用算法的指南。我们将在一个小型知识图上进行,该知识图包含少量节点,以特定模式连接。示例图如下所示

Visualization of the example graph
以下 Cypher 语句将在 Neo4j 数据库中创建示例图
CREATE
  (alice:Person {name: 'Alice'}),
  (bob:Person {name: 'Bob'}),
  (carol:Person {name: 'Carol'}),
  (dave:Person {name: 'Dave'}),
  (eve:Person {name: 'Eve'}),
  (guitar:Instrument {name: 'Guitar'}),
  (synth:Instrument {name: 'Synthesizer'}),
  (bongos:Instrument {name: 'Bongos'}),
  (trumpet:Instrument {name: 'Trumpet'}),

  (alice)-[:LIKES]->(guitar),
  (alice)-[:LIKES]->(synth),
  (alice)-[:LIKES {strength: 0.5}]->(bongos),
  (bob)-[:LIKES]->(guitar),
  (bob)-[:LIKES]->(synth),
  (carol)-[:LIKES]->(bongos),
  (dave)-[:LIKES]->(guitar),
  (dave)-[:LIKES {strength: 1.5}]->(trumpet),
  (dave)-[:LIKES]->(bongos);

此二部图有两个节点集,Person 节点和 Instrument 节点。这两个节点集通过 LIKES 关系连接。每个关系都从 Person 节点开始,在 Instrument 节点结束。

在示例中,我们希望使用节点相似度算法根据人们喜欢的乐器来比较人们。

节点相似度算法将仅计算度数至少为 1 的节点的相似度。在示例图中,Eve 节点不会与其他 Person 节点进行比较。

以下语句将投影图并将其存储在图目录中。
MATCH (source:Person)
OPTIONAL MATCH (source)-[r:LIKES]->(target:Instrument)
RETURN gds.graph.project(
  'myGraph',
  source,
  target,
  { relationshipProperties: r { strength: coalesce(r.strength, 1.0) } }
)

在以下示例中,我们将演示在该图上使用节点相似度算法。

内存估计

首先,我们将使用 estimate 过程估计运行算法的成本。这可以使用任何执行模式完成。在本例中,我们将使用 write 模式。估计算法有助于了解在您的图上运行算法将产生的内存影响。当您稍后实际以其中一种执行模式运行算法时,系统将执行估计。如果估计表明执行很可能超过其内存限制,则会禁止执行。有关此内容的更多信息,请参见 自动估计和执行阻止

有关 estimate 的更多详细信息,请参见 内存估计

以下内容将估计运行算法所需的内存
CALL gds.nodeSimilarity.write.estimate('myGraph', {
  writeRelationshipType: 'SIMILAR',
  writeProperty: 'score'
})
YIELD nodeCount, relationshipCount, bytesMin, bytesMax, requiredMemory
表 13. 结果
nodeCount relationshipCount bytesMin bytesMax requiredMemory

9

9

2384

2600

"[2384 字节 ... 2600 字节]"

stream 执行模式下,算法返回每个关系的相似度得分。这使我们能够直接检查结果或在 Cypher 中对其进行后处理,而不会产生任何副作用。

有关 stream 模式的更多详细信息,请参见

以下将运行算法并流式传输结果
CALL gds.nodeSimilarity.stream('myGraph')
YIELD node1, node2, similarity
RETURN gds.util.asNode(node1).name AS Person1, gds.util.asNode(node2).name AS Person2, similarity
ORDER BY similarity DESCENDING, Person1, Person2
表 14. 结果
Person1 Person2 similarity

"Alice"

"Bob"

0.6666666666666666

"Bob"

"Alice"

0.6666666666666666

"Alice"

"Dave"

0.5

"Dave"

"Alice"

0.5

"Alice"

"Carol"

0.3333333333333333

"Carol"

"Alice"

0.3333333333333333

"Carol"

"Dave"

0.3333333333333333

"Dave"

"Carol"

0.3333333333333333

"Bob"

"Dave"

0.25

"Dave"

"Bob"

0.25

我们使用过程配置参数的默认值。TopK 设置为 10,topN 设置为 0。因此,结果集包含每个节点的前 10 个相似度得分。

如果我们希望改为比较乐器,那么我们将使用 REVERSE 方向投影 LIKES 关系类型。这将返回乐器对的相似度,而不会计算 Person 之间的任何相似度。

统计信息

stats 执行模式下,算法返回包含算法结果摘要的单行。此执行模式没有任何副作用。它可以通过检查 computeMillis 返回项来评估算法性能,这很有用。在下面的示例中,我们将省略返回计时。过程的完整签名可以在 语法部分 中找到。

有关 stats 模式的更多详细信息,请参见 统计信息

以下将运行算法并以统计信息和测量值的 bentuk 返回结果
CALL gds.nodeSimilarity.stats('myGraph')
YIELD nodesCompared, similarityPairs
表 15. 结果
nodesCompared similarityPairs

4

10

变异

mutate 执行模式扩展了 stats 模式,并具有一个重要的副作用:使用新的关系属性更新命名图,该属性包含该关系的相似度得分。新属性的名称使用必需的配置参数 mutateProperty 指定。结果是一个单一的摘要行,类似于 stats,但包含一些额外的指标。当多个算法联合使用时,mutate 模式特别有用。

有关一般 `mutate` 模式的更多详细信息,请参阅 Mutate

以下操作将运行算法,并将结果写入内存中的图。
CALL gds.nodeSimilarity.mutate('myGraph', {
    mutateRelationshipType: 'SIMILAR',
    mutateProperty: 'score'
})
YIELD nodesCompared, relationshipsWritten
表 16. 结果
nodesCompared relationshipsWritten

4

10

从结果可以看出,创建的关系数量等于流式示例中的行数。

即使输入图是无向的,由突变产生的关系也始终是有向的。如果 `a → b` 是 `a` 的 topK,并且对称地 `b → a` 是 `b` 的 topK(或者 `a → b` 和 `b → a` 都是 topN),它看起来像产生了一个无向关系。但是,它们只是两个独立产生的有向关系。

写入

对于每对节点,`write` 执行模式创建一个关系,并将它们的相似度得分作为属性写入 Neo4j 数据库。新关系的类型使用强制配置参数 `writeRelationshipType` 指定。新属性的名称使用强制配置参数 `writeProperty` 指定。结果是一个类似于 `stats` 的单个摘要行,但包含一些额外的指标。

有关一般 `write` 模式的更多详细信息,请参阅 Write

以下操作将运行算法,并将结果写入。
CALL gds.nodeSimilarity.write('myGraph', {
    writeRelationshipType: 'SIMILAR',
    writeProperty: 'score'
})
YIELD nodesCompared, relationshipsWritten
表 17. 结果
nodesCompared relationshipsWritten

4

10

从结果可以看出,创建的关系数量等于流式示例中的行数。

写入的关系始终是有向的,即使输入图是无向的。如果 `a → b` 是 `a` 的 topK,并且对称地 `b → a` 是 `b` 的 topK(或者 `a → b` 和 `b → a` 都是 topN),它看起来像写入了一个无向关系。但是,它们只是两个独立写入的有向关系。

限制结果

可以对相似度结果应用四种限制。Top 限制结果为最高相似度得分。Bottom 限制结果为最低相似度得分。Top 和 Bottom 限制都可以应用于整个结果 ("N"),或应用于每个节点的结果 ("K")。

始终必须有一个 "K" 限制,无论是 bottomK 还是 topK,它是一个正数。topK 和 bottomK 的默认值为 10。

表 18. 结果限制
总结果 每个节点的结果

最高得分

topN

topK

最低得分

bottomN

bottomK

topK 和 bottomK

TopK 和 bottomK 是对每个节点计算的得分数量的限制。对于 topK,每个节点的 K 个最大相似度得分将被返回。对于 bottomK,每个节点的 K 个最小相似度得分将被返回。TopK 和 bottomK 不能为 0,不能一起使用,默认值为 10。如果没有指定任何一个,将使用 topK。

以下操作将运行算法,并流式传输每个节点的 top 1 结果。
CALL gds.nodeSimilarity.stream('myGraph', { topK: 1 })
YIELD node1, node2, similarity
RETURN gds.util.asNode(node1).name AS Person1, gds.util.asNode(node2).name AS Person2, similarity
ORDER BY Person1
表 19. 结果
Person1 Person2 similarity

"Alice"

"Bob"

0.666666666666667

"Bob"

"Alice"

0.666666666666667

"Carol"

"Alice"

0.333333333333333

"Dave"

"Alice"

0.5

以下操作将运行算法,并流式传输每个节点的 bottom 1 结果。
CALL gds.nodeSimilarity.stream('myGraph', { bottomK: 1 })
YIELD node1, node2, similarity
RETURN gds.util.asNode(node1).name AS Person1, gds.util.asNode(node2).name AS Person2, similarity
ORDER BY Person1
表 20. 结果
Person1 Person2 similarity

"Alice"

"Carol"

0.3333333333333333

"Bob"

"Dave"

0.25

"Carol"

"Alice"

0.3333333333333333

"Dave"

"Bob"

0.25

topN 和 bottomN

TopN 和 bottomN 限制了所有节点的相似度得分数量。这是对总结果集的限制,除了对每个节点的结果的 topK 或 bottomK 限制之外。对于 topN,将返回 N 个最大相似度得分。对于 bottomN,将返回 N 个最小相似度得分。值为 0 表示不施加全局限制,将返回 topK 或 bottomK 中的所有结果。

以下操作将运行算法,并流式传输每个节点的 top 1 结果中的 3 个最高结果。
CALL gds.nodeSimilarity.stream('myGraph', { topK: 1, topN: 3 })
YIELD node1, node2, similarity
RETURN gds.util.asNode(node1).name AS Person1, gds.util.asNode(node2).name AS Person2, similarity
ORDER BY similarity DESC, Person1, Person2
表 21. 结果
Person1 Person2 similarity

"Alice"

"Bob"

0.6666666667

"Bob"

"Alice"

0.6666666667

"Dave"

"Alice"

0.5

度限制和相似度限制

节点相似度可以通过两个名为 `degreeCutoff` 和 `upperDegreeCutoff` 的整型参数进行调整,以忽略基于度约束的某些节点。如果设置,`degreeCutoff` 将对度施加一个下限,以便在比较中考虑一个节点,并跳过任何度数低于 `degreeCutoff` 的节点。如果设置,`upperDegreeCutoff` 将对节点度施加一个上限,并跳过任何度数高于 `upperDegreeCutoff` 的节点。这两个参数也可以组合使用,以便只考虑度数落在特定段内的那些节点。

这两个参数的最小值为 `1`。

以下操作将忽略 LIKES 关系少于 3 个的节点。
CALL gds.nodeSimilarity.stream('myGraph', { degreeCutoff: 3 })
YIELD node1, node2, similarity
RETURN gds.util.asNode(node1).name AS Person1, gds.util.asNode(node2).name AS Person2, similarity
ORDER BY Person1
表 22. 结果
Person1 Person2 similarity

"Alice"

"Dave"

0.5

"Dave"

"Alice"

0.5

相似度限制是相似度得分出现在结果中的下限。默认值为非常小的值 (1E-42),以排除相似度得分为 0 的结果。

将相似度限制设置为 0 可能会产生非常大的结果集,增加运行时间和内存消耗。

以下操作将忽略相似度得分小于 0.5 的节点对。
CALL gds.nodeSimilarity.stream('myGraph', { similarityCutoff: 0.5 })
YIELD node1, node2, similarity
RETURN gds.util.asNode(node1).name AS Person1, gds.util.asNode(node2).name AS Person2, similarity
ORDER BY Person1
表 23. 结果
Person1 Person2 similarity

"Alice"

"Bob"

0.666666666666667

"Alice"

"Dave"

0.5

"Bob"

"Alice"

0.6666666666666666

"Dave"

"Alice"

0.5

加权相似度

关系属性可用于通过将它们的值作为衡量重要性的方式,来修改某些关系引起的相似度。默认情况下,加权节点相似度使用加权 Jaccard 相似度,根据以下公式:

weighted jaccard

形式上,给定两个节点及其加权邻居列表 `A'` 和 `B'`,我们将列表扩展到 `A` 和 `B`,通过将权重设置为 0 来索引它们的邻居 `A' ∪ B'` 的并集,对于任何非邻居,然后应用加权 Jaccard 相似度。

它还支持加权重叠相似度,根据以下公式:

weighted overlap

此外,余弦相似度可以在加权情况下使用,如 简介 中所述。

加权相似度指标仅对大于或等于 0 的值定义。

以下查询将在相似度计算中尊重关系属性。
CALL gds.nodeSimilarity.stream('myGraph', { relationshipWeightProperty: 'strength', similarityCutoff: 0.3 })
YIELD node1, node2, similarity
RETURN gds.util.asNode(node1).name AS Person1, gds.util.asNode(node2).name AS Person2, similarity
ORDER BY Person1
表 24. 结果
Person1 Person2 similarity

"Alice"

"Bob"

0.8

"Alice"

"Dave"

0.333333333333333

"Bob"

"Alice"

0.8

"Dave"

"Alice"

0.333333333333333

可以看出,与该算法的非加权版本相比,Alice 和 Dave 之间的相似度降低了(从 0.5 到 0.33)。

Alice 喜欢 Guitar、Synthesize 和 Bongos,强度分别为 `(1, 1, 0.5)`。Dave 喜欢 Guitar、Bongos 和 Trumpet,强度分别为 `(1, 1, 1.5)`。因此,取 Alice 和 Dave 的邻居,我们得到 Alice 的强度列表为 `A = (1, 1, 0.5, 0)`,Dave 的强度列表为 `B = (1, 0, 1, 1.5)`,索引为 `Guitar, Synthesizer, Bongos, Trumpet`。

因此,Alice 和 Dave 的加权(Jaccard)节点相似度为

weighted jaccard example

类似地,Alice 和 Bob 之间的相似度增加了(从 0.66 到 0.8),因为缺少的喜欢的乐器对相似度得分的影响较小。