【问题标题】:How to find node groups with a high cohesion by relationships to intermediate nodes?如何通过与中间节点的关系找到高内聚的节点组?
【发布时间】:2022-12-14 01:36:25
【问题描述】:

最小的例子:

有些猫喜欢爬不同类型的树。

我想确定喜欢爬大致相同树的猫群。

在下面的示例中,Lily 和 Bella 的偏好有 67% 的重叠。他们应该被确定为一组。

Lune 只是简单地爬上了每棵树,所以她不应该成为该组织的一员。

Cleo 与该组完全不相交,即与 Lily 和 Bella 的重叠度为 0%。

如果查询返回的组至少有 50% 重叠,那么查询会是什么样子? (在这种情况下,一组是“莉莉和贝拉”。)

CREATE (:Cat { name: 'Luna' });
CREATE (:Cat { name: 'Lily' });
CREATE (:Cat { name: 'Bella' });
CREATE (:Cat { name: 'Lucy' });
CREATE (:Cat { name: 'Nala' });
CREATE (:Cat { name: 'Callie' });
CREATE (:Cat { name: 'Kitty' });
CREATE (:Cat { name: 'Cleo' });

CREATE (:Tree { type: 'Red_maple' });
CREATE (:Tree { type: 'Loblolly_pine' });
CREATE (:Tree { type: 'American_sweetgum' });
CREATE (:Tree { type: 'Douglas_fir' });
CREATE (:Tree { type: 'Quaking_aspen' });
CREATE (:Tree { type: 'Sugar_maple' });
CREATE (:Tree { type: 'Balsam_fir' });
CREATE (:Tree { type: 'Flowering_dogwood' });

MATCH (c:Cat), (t:Tree) WHERE c.name = 'Lily' AND t.type = 'Red_maple' CREATE (c)-[:LIKES_TO_CLIMB]->(t);
MATCH (c:Cat), (t:Tree) WHERE c.name = 'Lily' AND t.type = 'Loblolly_pine' CREATE (c)-[:LIKES_TO_CLIMB]->(t);
MATCH (c:Cat), (t:Tree) WHERE c.name = 'Lily' AND t.type = 'American_sweetgum' CREATE (c)-[:LIKES_TO_CLIMB]->(t);

MATCH (c:Cat), (t:Tree) WHERE c.name = 'Bella' AND t.type = 'Red_maple' CREATE (c)-[:LIKES_TO_CLIMB]->(t);
MATCH (c:Cat), (t:Tree) WHERE c.name = 'Bella' AND t.type = 'Loblolly_pine' CREATE (c)-[:LIKES_TO_CLIMB]->(t);
MATCH (c:Cat), (t:Tree) WHERE c.name = 'Bella' AND t.type = 'Douglas_fir' CREATE (c)-[:LIKES_TO_CLIMB]->(t);

MATCH (c:Cat), (t:Tree) WHERE c.name = 'Luna' AND t.type = 'Red_maple' CREATE (c)-[:LIKES_TO_CLIMB]->(t);
MATCH (c:Cat), (t:Tree) WHERE c.name = 'Luna' AND t.type = 'Loblolly_pine' CREATE (c)-[:LIKES_TO_CLIMB]->(t);
MATCH (c:Cat), (t:Tree) WHERE c.name = 'Luna' AND t.type = 'American_sweetgum' CREATE (c)-[:LIKES_TO_CLIMB]->(t);
MATCH (c:Cat), (t:Tree) WHERE c.name = 'Luna' AND t.type = 'Douglas_fir' CREATE (c)-[:LIKES_TO_CLIMB]->(t);
MATCH (c:Cat), (t:Tree) WHERE c.name = 'Luna' AND t.type = 'Quaking_aspen' CREATE (c)-[:LIKES_TO_CLIMB]->(t);
MATCH (c:Cat), (t:Tree) WHERE c.name = 'Luna' AND t.type = 'Sugar_maple' CREATE (c)-[:LIKES_TO_CLIMB]->(t);
MATCH (c:Cat), (t:Tree) WHERE c.name = 'Luna' AND t.type = 'Balsam_fir' CREATE (c)-[:LIKES_TO_CLIMB]->(t);
MATCH (c:Cat), (t:Tree) WHERE c.name = 'Luna' AND t.type = 'Flowering_dogwood' CREATE (c)-[:LIKES_TO_CLIMB]->(t);

MATCH (c:Cat), (t:Tree) WHERE c.name = 'Cleo' AND t.type = 'Sugar_maple' CREATE (c)-[:LIKES_TO_CLIMB]->(t);
MATCH (c:Cat), (t:Tree) WHERE c.name = 'Cleo' AND t.type = 'Balsam_fir' CREATE (c)-[:LIKES_TO_CLIMB]->(t);
MATCH (c:Cat), (t:Tree) WHERE c.name = 'Cleo' AND t.type = 'Flowering_dogwood' CREATE (c)-[:LIKES_TO_CLIMB]->(t);

【问题讨论】:

  • 你试过什么了?结果是什么?
  • 问题是,我什至不知道从哪里开始。我知道如何匹配单身关系,仅此而已。

标签: neo4j cypher graph-theory neo4j-apoc


【解决方案1】:

所以你真正想做的是:

  1. 使用 GDS 库中的节点相似度算法。默认是 Jaccard 相似度,或者您也可以使用 Overlap 相似度。节点相似性算法将在您的猫之间创建相似性关系。您可以使用similarityCutoff 参数设置阈值。

  2. 一旦你创建了相似关系,你想要运行弱连接组件算法或类似 Louvain 或 Leiden 的东西,这取决于什么最适合你的用例。

    因此,在您的特定用例中,它看起来像:

    构建投影图

    CALL gds.graph.project('cats', ['Cat', 'Tree'], 'LIKES_TO_CLIMB');
    

    运行 Jaccard 阈值为 0.5 的节点相似度算法

    CALL gds.nodeSimilarity.mutate('cats', {mutateRelationshipType:'SIMILAR',
        mutateProperty:'score', similarityCutoff:0.5})
    

    运行 WCC 或其他社区检测算法

    CALL gds.wcc.stream('cats', {relationshipTypes:['SIMILAR'], nodeLabels:['Cat']})
    YIELD nodeId, componentId
    RETURN componentId, collect(gds.util.asNode(nodeId).name) AS catGroup
    

    这将返回:

    ╒═════════════╤════════════════╕
    │"componentId"│"catGroup"      │
    ╞═════════════╪════════════════╡
    │0            │["Luna"]        │
    ├─────────────┼────────────────┤
    │1            │["Lily","Bella"]│
    ├─────────────┼────────────────┤
    │3            │["Lucy"]        │
    ├─────────────┼────────────────┤
    │4            │["Nala"]        │
    ├─────────────┼────────────────┤
    │5            │["Callie"]      │
    ├─────────────┼────────────────┤
    │6            │["Kitty"]       │
    ├─────────────┼────────────────┤
    │7            │["Cleo"]        │
    └─────────────┴────────────────┘
    

    现在显然,您可以尝试使用 similarityCutoff 参数和其他社区检测算法来最适合您的用例

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-13
    • 1970-01-01
    • 1970-01-01
    • 2019-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多