在书中"图形算法,在Apache Spark &Neo4J中的实际例子(05-2019,Mark Needham,Amy E. Hodler)。",第155页,有一个使用APOC的PageRank算法来计算某些用户的PageRanks的例子。
的代码片段。
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}}
)
节点声明很清楚。但是,在relation-statement中,似乎可以包含重复的关系。比如说 User
A
写2 Review
s; User
A
还拥有2个朋友(2个其他 User
s,例如 B
和 C
). 那么,我们最终有4对关系 A
-B
, A
-C
, A
-B
, A
-C
,如(*)。
问题: APOC的PageRank是否会忽略这种重复关系?即它只会看到两个对子。A
-B
, A
-C
. 或者这个实现将重复关系视为 "权重"?即如果3对 A
-B
返回,它认为单 A
-B
与权重3的关系。还是说没有这样的预处理,PageRank本身就会把每对链接视为一个独立的链接?
我已经查阅了官方文档(如下),但没有发现对这个问题的见解。希望得到任何帮助。
APOC的PageRank将重复的链接视为独立的链接,这意味着在程序中的 apoc.algo.pageRankWithCypher()
如果Cypher查询意外地返回了重复的链接,就像书中的例子一样,它可能会影响最终的PageRanks。换句话说,与清除重复链接(只清除一个)相比,程序返回的PageRanks是不同的。
在程序的Java源代码中,每个节点的外链数量用行来计算 sourceDegreeData.increment(sourceIndex);
(联系). 节点将共享它们的 自己的网页排名 平等地分配给所有的外链。研究表明,该代码不做任何重复数据删除,即如果遇到了 A->B
, A->C
, A->B
,它考虑的是3种关系。在这种情况下,外链的数量为 每个节点 叫做 程度 的节点。在我们的例子中, 程度 对于节点 A
是3。
这一点(没有重复数据删除)在代码的其他部分也是如此。在其他部分的代码中也是如此。NumLinks
,就像最初的PageRank公式一样(联系),是以函数计算的。getTotalWeightForNode()
(联系). 之后,当PageRanks在函数 startIteration()
(联系)和 iterateParallel()
(联系),当前节点的PageRank依赖于它的 程度. 同样,没有代码片段表明重复数据删除。
此外,没有产生Cypher查询部分中每个关系的权重。apoc.algo.pageRankWithCypher()
,默认权重为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,第1个假设没有重复链接;第2个 故意 对某些节点产生重复的链接。
// 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})
之后,我们可以比较属性 PageRank1
和 PageRank2
为每个节点,看看区别。
在计算 PageRank 时,出现无意的重复链接有什么大不了的吗?我认为是的,因为 PageRank 公式化假设了独特的外链。
同一页面上的重复链接将被视为单个链接。
为了保证可重复性,这里测试的Neo4j版本为 v3.5.17
. APOC版本 v3.5.0.9
(其相应的源代码在 GitHub,分支 3.5
.