节点间相似度计算
以下测试均在ongdb完成
在ongdb集群的运行过程中,READ_REPLICA节点只支持运行Mode.READ类型的过程(集群中所有节点都支持Mode.READ类型的过程),需要运行中写入的过程需要在支持写入的节点运行。
并发计算的过程不支持写入,运算得到的结果需要neo4j-stream的支持进行写入,或者额外的插件单独写入。结果的保存也可以放在其它存储系统。
可支持的并发数量与服务器的CPU核数有关系。
一、Jaccard相似度 - algo.similarity.jaccard - Mode.WRITE
杰卡尔德相似度计算更适合在大规模数据下的分布式并行运算
1、创建测试数据
CREATE (a:Person {name:'Alice'})
CREATE (b:Person {name:'Bob'})
CREATE (c:Person {name:'Charlie'})
CREATE (d:Person {name:'Dana'})
CREATE (i1:Item {name:'p1'})
CREATE (i2:Item {name:'p2'})
CREATE (i3:Item {name:'p3'})
CREATE (a)-[:LIKES]->(i1),
(a)-[:LIKES]->(i2),
(a)-[:LIKES]->(i3),
(b)-[:LIKES]->(i1),
(b)-[:LIKES]->(i2),
(c)-[:LIKES]->(i3)
2、运行相似度计算
不支持并发计算支持写入
MATCH (p:Person)-[:LIKES]->(i:Item)
WITH {item:id(p), categories: collect(distinct id(i))} as userData
WITH collect(userData) as data
CALL algo.similarity.jaccard(data, {write:true,showComputations:true,similarityCutoff:0.1}) yield p25, p50, p75, p90, p95, p99, p999, p100, nodes, similarityPairs, computations RETURN *
3、相似度计算结果
生成了一条SIMILAR关系线,更新了score属性;很明确可以看到人物节点之间的相似性得分。
4、algo.similarity.jaccard.stream - Mode.READ
并发计算,不支持写入
MATCH (p:Person)-[:LIKES]->(i:Item)
WITH {item:id(p), categories: collect(distinct id(i))} as userData
WITH collect(userData) as data
call algo.similarity.jaccard.stream(data,{topK:4,concurrency:4,similarityCutoff:-0.1}) yield item1, item2, count1, count2, intersection, similarity RETURN * ORDER BY item1,item2
二、余弦相似度 - algo.similarity.cosine - Mode.WRITE
1、创建测试数据
CREATE (a:Person {name:'Alice'})
CREATE (b:Person {name:'Bob'})
CREATE (c:Person {name:'Charlie'})
CREATE (d:Person {name:'Dana'})
CREATE (i1:Item {name:'p1'})
CREATE (i2:Item {name:'p2'})
CREATE (i3:Item {name:'p3'})
CREATE (a)-[:LIKES {stars:1}]->(i1),
(a)-[:LIKES {stars:2}]->(i2),
(a)-[:LIKES {stars:5}]->(i3),
(b)-[:LIKES {stars:1}]->(i1),
(b)-[:LIKES {stars:3}]->(i2),
(c)-[:LIKES {stars:4}]->(i3)
2、运行相似度计算
MATCH (i:Item) WITH i ORDER BY id(i) MATCH (p:Person) OPTIONAL MATCH (p)-[r:LIKES]->(i)
WITH {item:id(p), weights: collect(coalesce(r.stars,0))} as userData
WITH collect(userData) as data
CALL algo.similarity.cosine(data, {write:true,showComputations:true,similarityCutoff:0.1}) yield p25, p50, p75, p90, p95, p99, p999, p100, nodes, similarityPairs, computations RETURN *
3、algo.similarity.cosine.stream - Mode.READ
CALL algo.similarity.cosine.stream([{item:id, weights:[weights]}], {similarityCutoff:-1,degreeCutoff:0})
YIELD item1, item2, count1, count2, intersection, similarity - computes cosine distance
三、Pearson相似度 - algo.similarity.pearson - Mode.WRITE
1、创建测试数据
CREATE (a:Person {name:'Alice'})
CREATE (b:Person {name:'Bob'})
CREATE (c:Person {name:'Charlie'})
CREATE (d:Person {name:'Dana'})
CREATE (i1:Item {name:'p1'})
CREATE (i2:Item {name:'p2'})
CREATE (i3:Item {name:'p3'})
CREATE (i4:Item {name:'p4'})
CREATE (a)-[:LIKES {stars:1}]->(i1),
(a)-[:LIKES {stars:2}]->(i2),
(a)-[:LIKES {stars:3}]->(i3),
(a)-[:LIKES {stars:4}]->(i4),
(b)-[:LIKES {stars:2}]->(i1),
(b)-[:LIKES {stars:3}]->(i2),
(b)-[:LIKES {stars:4}]->(i3),
(b)-[:LIKES {stars:5}]->(i4),
(c)-[:LIKES {stars:3}]->(i1),
(c)-[:LIKES {stars:4}]->(i2),
(c)-[:LIKES {stars:4}]->(i3),
(c)-[:LIKES {stars:5}]->(i4),
(d)-[:LIKES {stars:3}]->(i2),
(d)-[:LIKES {stars:2}]->(i3),
(d)-[:LIKES {stars:5}]->(i4)
2、运行相似度计算
MATCH (i:Item) WITH i ORDER BY id(i) MATCH (p:Person) OPTIONAL MATCH (p)-[r:LIKES]->(i)
WITH {item:id(p), weights: collect(coalesce(r.stars,0))} as userData
WITH collect(userData) as data
CALL algo.similarity.pearson(data,{similarityCutoff:-0.1}) yield p25, p50, p75, p90, p95, p99, p999, p100, nodes, similarityPairs, computations RETURN *
3、algo.similarity.jaccard.stream - Mode.READ
MATCH (i:Item) WITH i ORDER BY i MATCH (p:Person) OPTIONAL MATCH (p)-[r:LIKES]->(i)
WITH p, i, r ORDER BY id(p), id(i) WITH {item:id(p), weights: collect(coalesce(r.stars,$missingValue))} as userData
WITH collect(userData) as data
call algo.similarity.pearson.stream(data,{similarityCutoff:-0.1}) yield item1, item2, count1, count2, intersection, similarity RETURN item1, item2, count1, count2, intersection, similarity ORDER BY item1,item2
四、欧式距离 - algo.similarity.euclidean - Mode.WRITE
1、创建测试数据
CREATE (a:Person {name:'Alice'})
CREATE (b:Person {name:'Bob'})
CREATE (c:Person {name:'Charlie'})
CREATE (d:Person {name:'Dana'})
CREATE (i1:Item {name:'p1'})
CREATE (i2:Item {name:'p2'})
CREATE (i3:Item {name:'p3'})
CREATE (a)-[:LIKES {stars:1}]->(i1),
(a)-[:LIKES {stars:2}]->(i2),
(a)-[:LIKES {stars:5}]->(i3),
(b)-[:LIKES {stars:1}]->(i1),
(b)-[:LIKES {stars:3}]->(i2),
(c)-[:LIKES {stars:4}]->(i3)
2、运行相似度计算
MATCH (i:Item) WITH i ORDER BY id(i) MATCH (p:Person) OPTIONAL MATCH (p)-[r:LIKES]->(i)
WITH {item:id(p), weights: collect(coalesce(r.stars,0))} AS userData
WITH collect(userData) AS data
CALL algo.similarity.euclidean(data, {similarityCutoff:-0.1}) YIELD p25, p50, p75, p90, p95, p99, p999, p100, nodes, similarityPairs, computations RETURN *
3、algo.similarity.jaccard.stream - Mode.READ
MATCH (i:Item) WITH i ORDER BY id(i) MATCH (p:Person) OPTIONAL MATCH (p)-[r:LIKES]->(i)
WITH {item:id(p), weights: collect(coalesce(r.stars,$missingValue))} AS userData
WITH collect(userData) AS data
CALL algo.similarity.euclidean.stream(data,{similarityCutoff:-0.1}) YIELD item1, item2, count1, count2, intersection, similarity RETURN item1, item2, count1, count2, intersection, similarity ORDER BY item1,item2
五、重叠相似度 - algo.similarity.overlap - Mode.WRITE
1、创建测试数据
CREATE (a:Person {name:'Alice'})
CREATE (b:Person {name:'Bob'})
CREATE (c:Person {name:'Charlie'})
CREATE (d:Person {name:'Dana'})
CREATE (i1:Item {name:'p1'})
CREATE (i2:Item {name:'p2'})
CREATE (i3:Item {name:'p3'})
CREATE (a)-[:LIKES]->(i1),
(a)-[:LIKES]->(i2),
(a)-[:LIKES]->(i3),
(b)-[:LIKES]->(i1),
(b)-[:LIKES]->(i2),
(c)-[:LIKES]->(i3)
2、运行相似度计算
MATCH (p:Person)-[:LIKES]->(i:Item)
WITH {item:id(p), categories: collect(distinct id(i))} as userData
WITH collect(userData) as data
CALL algo.similarity.overlap(data, {similarityCutoff:-0.1}) yield p25, p50, p75, p90, p95, p99, p999, p100, nodes, similarityPairs, computations RETURN p25, p50, p75, p90, p95, p99, p999, p100, nodes, similarityPairs, computations
3、algo.similarity.jaccard.stream - Mode.READ
MATCH (p:Person)-[:LIKES]->(i:Item)
WITH {item:id(p), categories: collect(distinct id(i))} as userData
WITH collect(userData) as data
call algo.similarity.overlap.stream(data,{similarityCutoff:-0.1}) yield item1, item2, count1, count2, intersection, similarity RETURN item1, item2, count1, count2, intersection, similarity ORDER BY item1,item2
备注
neo4j-graph-algorithms包相似度计算源码位置:
algo/src/main/java/org/neo4j/graphalgo/similarity