【问题标题】:Neo4j - How does APOC's PageRank handle duplicate relationships in relationship-statement?Neo4j - APOC 的 PageRank 如何处理关系语句中的重复关系?
【发布时间】:2020-05-17 21:27:55
【问题描述】:

在“Graph Algorithms, Practical Examples in Apache Spark & Neo4J (05-2019, Mark Needham, Amy E. Hodler)一书中,第 155 页,有一个使用 APOC 的 PageRank 的例子算法来计算某些用户的 PageRanks。

代码sn-p:

CALL algo.pageRank(
    'MATCH (u:User)-[:WROTE]->()-[:REVIEWS]->()-[:IN_CATEGORY]->
                                    (:Category {name: $category})
    WITH u, count(*) AS reviews
    WHERE reviews >= $cutOff
    RETURN id(u) AS id',
    'MATCH (u1:User)-[:WROTE]->()-[:REVIEWS]->()-[:IN_CATEGORY]->
                                    (:Category {name: $category})
    MATCH (u1)-[:FRIENDS]->(u2)
    RETURN id(u1) AS source, id(u2) AS target', (*)
    {graph: "cypher", write: true, writeProperty: "hotelPageRank",
    params: {category: "Hotels", cutOff: 3}}
)

节点语句很清楚。但是,在关系声明中,它似乎可能包含重复的关系。例如,UserA 写入 2 Reviews; User A 也有 2 个朋友(另外 2 个 Users,例如 BC)。然后,我们最终得到 4 个关系对 A-BA-CA-BA-C,如 (*)。

问题:APOC 的 PageRank 是否会忽略这种重复关系? IE。它只会看到两对A-BA-C。或者这个实现将重复关系视为“权重”? IE。如果返回了 3 对 A-B,则认为单个 A-B 与权重 3 的关系。或者没有这样的预处理,PageRank 本身会将每一对视为单独的链接?

我查阅了官方文档(如下),但对这个问题没有任何见解。任何帮助表示赞赏。

The PageRank algorithm

【问题讨论】:

    标签: neo4j neo4j-apoc pagerank


    【解决方案1】:

    您可能应该开始使用Graph Data Science 库,它是图形算法库的继承者,也是更成熟的产品。您正在阅读的书正在慢慢更新以使用 GDS 库。 GDS 库中的 PageRank 版本确实支持一对节点之间的重复关系,即所谓的多重图。您也可以查看this blog post 了解更多信息。

    【讨论】:

      【解决方案2】:

      APOC 的 PageRank 将重复链接视为单独的链接,这意味着在程序 apoc.algo.pageRankWithCypher() 中:如果 Cypher 查询意外返回重复链接,如书中的示例,它可能会影响最终的 PageRank。换句话说,与清除重复链接(只清除一个)相比,该过程返回不同的 PageRank。

      证明

      在程序的 Java 源代码中,每个节点的外链接数以行 sourceDegreeData.increment(sourceIndex); (link) 计算。节点将与所有外链平等地共享其自己的 PageRank。显示代码没有做任何去重,即如果遇到A->BA->CA->B,它会考虑3个关系。在这种情况下,每个节点的外链接数称为该节点的。在我们的示例中,节点 Adegree 为 3。

      这(无重复数据删除)也适用于代码的其他部分。 NumLinks 与原始 PageRank 公式 (link) 一样,是在函数 getTotalWeightForNode() (link) 中计算的。之后,当在函数 startIteration() (link) 和 iterateParallel() (link) 中并行迭代计算 PageRank 时,当前节点的 PageRank 依赖于它的 degree。同样,没有代码 sn-p 表示重复数据删除。

      另外,apoc.algo.pageRankWithCypher() 的 Cypher 查询部分中没有为每个关系生成权重,默认权重为 1。

      一个例子

      假设一个空图,执行这个查询:

      CREATE (a:Node {name: "a"}), (b:Node {name: "b"}), (c: Node {name: "c"}), (x:Node {name: "x"}), (y:Node {name: "y"}), (a)-[:CONNECT]->(b), (b)-[:CONNECT]->(c), (x)-[:CONNECT]->(a), (y)-[:CONNECT]->(c)
      

      图表:

      注意:虽然它显示了关系方向,但我们忽略了方向并认为每一对都有双向关系。

      计算PageRanks,第一个假设没有重复链接;第二个故意为某些节点生成重复链接。

      // 1st
      CALL apoc.algo.pageRankWithCypher({iterations: 2, node_cypher: 'MATCH (n) RETURN ID(n) as id', rel_cypher: 'MATCH (n)-[]-(m) RETURN ID(n) AS source, ID(m) AS target ORDER BY source', write: true, property:'pageRank1', numCpu: 1})
      
      // 2nd
      CALL apoc.algo.pageRankWithCypher({iterations: 2, node_cypher: 'MATCH (n) RETURN ID(n) as id', rel_cypher: 'MATCH (n)-[]-(m) RETURN ID(n) AS source, ID(m) AS target ORDER BY source UNION ALL MATCH (n)-[]-(m {name: "b"}) RETURN ID(n) AS source, ID(m) AS target ORDER BY source', write: true, property:'pageRank2', numCpu: 1})
      

      之后,我们可以比较每个节点的属性PageRank1PageRank2,看看有什么区别。

      最后的话

      在计算 PageRank 时出现意外的重复链接是否很重要?我相信是这样,因为 PageRank 公式假设了独特的外链:

      同一页面上的重复链接被视为单个链接

      PageRank

      为了重现性,这里测试的 Neo4j 版本是v3.5.17。 APOC版本v3.5.0.9(对应源码在GitHub,分支3.5

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-27
        • 1970-01-01
        • 2012-10-07
        • 2017-03-14
        相关资源
        最近更新 更多