模块度量 (Modularity metric)

术语表

有向

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

有向

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

有向

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

无向

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

无向

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

异构节点

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

异构节点

异构节点允许。该算法平等对待所有选定的节点,无论其标签如何。

异构关系

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

异构关系

异构关系允许。该算法平等对待所有选定的关系,无论其类型如何。

加权关系

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

加权关系

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

节点属性

节点属性特征。该算法使用节点属性。

简介

模块化 (Modularity) 是一种用于评估社区发现质量的指标。社区 C 中节点的各种关系,可能连接至 C 内部的节点,也可能连接至 C 外部的节点。具有高模块化的图,其社区内部节点间的连接非常稠密,而不同社区节点间的连接则非常稀疏。

语法

本节介绍了在每种执行模式下运行“模块化指标”算法的语法。此处描述的是命名图 (named graph) 语法变体。如需了解关于通用语法变体的更多信息,请参阅 语法概述

示例 1. 各种模式下的模块化语法
在命名图上以流 (stream) 模式运行模块化算法。
CALL gds.modularity.stream(
  graphName: String,
  configuration: Map
) YIELD
  communityId: Integer,
  modularity: Float
表 1. 参数
名称 类型 默认 可选 描述

graphName

字符串

不适用

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

配置

Map

{}

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

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

nodeLabels

字符串列表

['*']

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

relationshipTypes

字符串列表

['*']

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

concurrency

整数

4 [1]

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

jobId

字符串

内部生成

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

logProgress

布尔值

true

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

relationshipWeightProperty

字符串

null

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

communityProperty

字符串

不适用

用于存储每个节点社区 ID(整数)的节点属性。请注意,只有非负的社区 ID 才被视为有效,并会计算其模块化得分。

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

表 3. 结果
名称 类型 描述

communityId

整数

社区 ID。

modularity

浮点数

社区的模块化得分。

在命名图上以统计 (stats) 模式运行模块化算法。
CALL gds.modularity.stats(
  graphName: String,
  configuration: Map
) YIELD
  nodeCount: Integer,
  relationshipCount: Integer,
  communityCount: Integer,
  modularity: Float,
  postProcessingMillis: Integer,
  preProcessingMillis: Integer,
  computeMillis: Integer,
  configuration: Map
表 4. 参数
名称 类型 默认 可选 描述

graphName

字符串

不适用

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

配置

Map

{}

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

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

nodeLabels

字符串列表

['*']

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

relationshipTypes

字符串列表

['*']

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

concurrency

整数

4 [2]

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

jobId

字符串

内部生成

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

logProgress

布尔值

true

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

relationshipWeightProperty

字符串

null

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

communityProperty

字符串

不适用

用于存储每个节点社区 ID(整数)的节点属性。请注意,只有非负的社区 ID 才被视为有效,并会计算其模块化得分。

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

表 6. 结果
名称 类型 描述

nodeCount

整数

图中的节点数。

relationshipCount

整数

图中的关系总数。

communityCount

整数

社区数量。

modularity

浮点数

总模块化得分。

preProcessingMillis

整数

预处理数据的毫秒数。

computeMillis

整数

运行算法的毫秒数。

postProcessingMillis

整数

计算百分位数和社区数量所需的毫秒数。

配置

Map

用于运行算法的配置。

示例

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

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

在本节中,我们将展示在具体图上运行模块化算法的示例。旨在说明结果呈现方式,并提供如何在实际场景中使用该算法的指南。我们将使用一个小型社交网络图,其中包含以特定模式连接的少量节点。示例图如下所示:

Visualization of the example graph
以下 Cypher 语句将在 Neo4j 数据库中创建示例图:
CREATE
  (nAlice:User {name: 'Alice', community: 3}),
  (nBridget:User {name: 'Bridget', community: 2}),
  (nCharles:User {name: 'Charles', community: 2}),
  (nDoug:User {name: 'Doug', community: 3}),
  (nMark:User {name: 'Mark', community: 5}),
  (nMichael:User {name: 'Michael', community: 5}),

  (nAlice)-[:LINK {weight: 1}]->(nBridget),
  (nAlice)-[:LINK {weight: 1}]->(nCharles),
  (nCharles)-[:LINK {weight: 1}]->(nBridget),

  (nAlice)-[:LINK {weight: 5}]->(nDoug),

  (nMark)-[:LINK {weight: 1}]->(nDoug),
  (nMark)-[:LINK {weight: 1}]->(nMichael),
  (nMichael)-[:LINK {weight: 1}]->(nMark);

该图包含三个预先计算好的 Users(用户)社区,它们连接紧密。有关可用社区发现算法的更多详细信息,请参阅文档的 社区算法 部分。社区由每个节点上的 community 节点属性标识。连接每个组件中节点的关系具有一个 weight(权重)属性,该属性决定了关系的强度。

现在我们可以投影该图并将其存储在图目录 (graph catalog) 中。我们加载 LINK 关系,并将方向设置为 UNDIRECTED(无向)。

以下语句将投影图并将其存储在图目录中。
MATCH (source:User)-[r:LINK]->(target:User)
RETURN gds.graph.project(
  'myGraph',
  source,
  target,
  {
    sourceNodeProperties: source { .community },
    targetNodeProperties: target { .community },
    relationshipProperties: r { .weight }
  },
  { undirectedRelationshipTypes: ['*'] }
)

内存估算

首先,我们将使用 estimate 过程估算运行该算法的成本。这可以在任何执行模式下完成。在此示例中,我们将使用 stats 模式。估算算法对于理解在图上运行算法对内存的影响非常有用。当您随后在某种执行模式下实际运行算法时,系统将执行一次估算。如果估算结果显示执行超出其内存限制的概率极高,则会禁止执行。要阅读更多关于此的内容,请参见 自动估算和执行阻塞

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

以下代码将估算以统计模式运行算法所需的内存
CALL gds.modularity.stats.estimate('myGraph', {
     communityProperty: 'community',
     relationshipWeightProperty: 'weight'
})
YIELD nodeCount, relationshipCount, bytesMin, bytesMax, requiredMemory
表 7. 结果
nodeCount relationshipCount bytesMin bytesMax requiredMemory

6

14

968

968

"968 字节"

流模式

由于我们拥有每个节点的社区信息,因此可以使用模块化指标来评估其质量。请注意,在本例中,我们利用了关系由关系属性加权这一特性。

模块化流过程返回每个社区的模块化得分。这使我们可以直接检查结果,或在 Cypher 中进行后处理,且不会产生任何副作用。

有关流模式的更多详细信息,请参阅 流模式 (Stream)

以下代码将以 stream 模式运行模块化算法:
CALL gds.modularity.stream('myGraph', {
     communityProperty: 'community',
     relationshipWeightProperty: 'weight'
})
YIELD communityId, modularity
RETURN communityId, modularity
ORDER BY communityId ASC
表 8. 结果
communityId modularity

2

0.057851239669421

3

0.105371900826446

5

0.130165289256198

我们可以看到,加权图中模块化程度最高的社区是社区 5。这意味着社区 5 是最“紧密”的社区,即其大部分关系权重都集中在社区内部。

统计信息 (Stats)

有关统计模式的更多详细信息,请参阅 统计模式 (Stats)

以下代码将以 stats 模式运行模块化算法:
CALL gds.modularity.stats('myGraph', {
     communityProperty: 'community',
     relationshipWeightProperty: 'weight'
})
YIELD nodeCount, relationshipCount, communityCount, modularity
表 9. 结果
nodeCount relationshipCount communityCount modularity

6

14

3

0.293388429752066