复杂的密码查询与数学公式

cod*_*iac 3 similarity neo4j graph-databases cypher

我有一个包含2种节点的图表:person&food.我有一种关系 - Ate有一个属性 - count.每次person a时food,count关系的属性都会增加.

我的目标是计算两个person节点之间的相似性.我在网上找到了这个算法来计算相似度,我想用它.如何将其转换为Cypher查询?

sim = 0
for k = 1 to n:
  sim = sim + (1 - Math.abs((N1k/H1 - N2k/H2)))(N1k+N2k)/(H1+H2)
Run Code Online (Sandbox Code Playgroud)

哪里:

sim =相似性指数
H1 = food吃掉的项目总数person1
H2 = food吃掉的项目总数person2
n = 共同food节点数 N1k = 1 次吃掉'n' 项中的'第k'个项目 N2k = 2 次在"n"个常用项目中吃过"第k个" 项目的次数
personfoodfood
personfoodfood

我已准备好骨架,但我不知道如何继续.

Start me=node(name="%s")
MATCH me-[r1:Ate]->some_food<-[r2:Ate]-other_dude
// do some stuff here to find out sim
RETURN other_dude, sim
ORDER BY sim DESC
LIMIT 10
Run Code Online (Sandbox Code Playgroud)

帮助赞赏!

rhe*_*nik 5

我在Neo4j邮件列表上看到了这个问题,但昨天无法回复.

对于Cypher来说,我是新手.但是,我可以帮助您解决Gremlin中的问题.我可以创建一个类似于你的图形并在其上运行Gremlin遍历.

我的图表看起来像:

gremlin> g.v(1,2,3,4)_().outE('eats').inV.path{it.name}{it.count}{it.name}  
==>[Neo, 5, Meat]
==>[Neo, 1, Cheese]
==>[Neo, 4, Chicken]
==>[Morpheus, 3, Bread]
==>[Morpheus, 3, Cheese]
==>[Morpheus, 2, Chicken]
==>[Trinity, 1, Apple]
==>[Trinity, 2, Bread]
==>[Trinity, 4, Meat]
==>[Trinity, 2, Cheese]
==>[Smith, 3, Apple]
==>[Smith, 4, Ham]
==>[Smith, 5, Pork]
gremlin> 
Run Code Online (Sandbox Code Playgroud)

我编写了一个遍历来为任何一个顶点生成相似性索引,由start一组剩余的ID表示.我最后的遍历看起来像:

simarray=[];start=3;
[1,2,4].each{
                p1=start;p2=it;
                first=g.v(p1);
                second=g.v(p2);
                sim=0;
                h1=first.out('eats').count().toFloat();
                h2=second.out('eats').count().toFloat();
                first.outE('eats').as('edges')
                .inV.in('eats').has('id',second.id).back('edges')
                .each{
                        n1k = it.count;
                        n2k = it.inV.inE('eats').outV
                                .has('id', second.id).back(2).count.next();
                        sim = sim + (1 - ((n1k/h1)-(n2k/h2)).abs())*(n1k+n2k)/(h1+h2)
                        };
                simarray.add(sim)
            };
simarray
Run Code Online (Sandbox Code Playgroud)

输出:

gremlin> simarray=[];start=3;[1,2,4].each{p1=start;p2=it; first=g.v(p1); second=g.v(p2); sim=0; h1=first.out('eats').count().toFloat(); h2=second.out('eats').count().toFloat(); first.outE('eats').as('edges').inV.in('eats').has('id',second.id).back('edges').each{n1k = it.count; n2k = it.inV.inE('eats').outV.has('id', second.id).back(2).count.next(); sim = sim + (1 - ((n1k/h1)-(n2k/h2)).abs())*(n1k+n2k)/(h1+h2)}; simarray.add(sim)};simarray
==>0.7857142857142856
==>0.7142857142857143
==>0.14285714285714285
Run Code Online (Sandbox Code Playgroud)

以上遍历直接转换为您的公式/计算.它可以针对图形遍历的性能进行优化.此外,您可能希望通过Gremlin的文档详细了解相关内容. https://github.com/tinkerpop/gremlin/wiki

除了您已经加入的Neo4j邮件列表之外,您还可以在Gremlin邮件列表中提出您的疑问:https: //groups.google.com/group/gremlin-users