3

2種類のノードを持つグラフがあります:personfood。私には1種類の関係Ateがあります-属性付き- count。aperson がを食べるたびに、関係foodcount属性が増加します。

person私の目標は、2つのノード間の類似性を計算することです。このアルゴリズムをオンラインで見つけて類似性を計算したので、それを使用したいと思います。これをCypherクエリに変換するにはどうすればよいですか?

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

どこ:

sim=類似性指数
H1= 1がfood食べたアイテム の総数H2= 2が食べたアイテムの総数 n=共通のノードの 数N1k= 1が「n」の共通アイテムのうち「k番目」のアイテムを食べた回数 N2k = 「n」個の一般的なアイテムのうち2個が「k番目」のアイテムを食べた回数person
foodperson
food
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

感謝します!

4

2 に答える 2

5

この質問はNeo4jメーリングリストで見ましたが、昨日は回答できませんでした。

サイファーに関しては、私は初心者です。しかし、私はグレムリンでのあなたの問題の解決策を手伝うことができます。私はあなたと同じようなグラフを作成し、その上でグレムリントラバーサルを実行することができました。

私のグラフは次のようになります。

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> 

start残りのIDの配列に対して示される、任意の1つの頂点の類似性インデックスを生成するトラバーサルを作成しました。私の最後のトラバーサルは次のようになります。

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

出力:

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

上記のトラバーサルは、数式/計算に直接変換されます。グラフトラバーサルのパフォーマンスに最適化できます。さらに、Gremlinのドキュメントを読んで、物事を詳細に理解することをお勧めします。 https://github.com/tinkerpop/gremlin/wiki

すでにメンバーになっているNeo4jメーリングリストとは別に、Gremlinメーリングリストでクエリを送信することもできます:https: //groups.google.com/group/gremlin-users

于 2012-05-30T06:07:57.250 に答える
2

数式はあまり得意ではありませんが、類似性の計算に関する2つのブログ投稿があります。これは、数式に従って、いつでもより正確になるように調整できます。

これはGremlinを使用しています:http: //blog.everymansoftware.com/2012/02/similarity-based-recommendation-engines.html

そしてこれはCypherを使用します:http: //thought-bytes.blogspot.in/2012/02/similarity-based-recommendations-with.html

于 2012-05-29T03:37:26.043 に答える