3 votes

Requêtes de cryptage complexes avec formule mathématique

J'ai un graphe avec 2 types de noeuds : person & food . J'ai un seul type de relation - Ate avec un attribut - count . Chaque fois qu'un person mange a food le count de la relation est incrémenté.

Mon objectif est de calculer la similarité entre deux person des nœuds. J'ai trouvé cet algorithme en ligne pour calculer la similarité et je veux l'utiliser. Comment convertir cet algorithme en une requête Cypher ?

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

où :

sim = indice de similarité
H1 = nombre total de food articles consommés par person 1
H2 = nombre total de food articles consommés par person 2
n = nombre de food les nœuds dans commun
N1k = nombre de fois person 1 a mangé 'kth'. food élément parmi les "n" communs food articles
N2k = nombre de fois person 2 a mangé "kth food élément parmi les "n" communs food articles

Le squelette est prêt, mais je ne sais pas comment procéder.

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

Aide appréciée !

5voto

rhetonik Points 1758

J'ai vu cette question sur la liste de diffusion Neo4j, mais je n'ai pas pu y répondre hier.

Je suis un novice en ce qui concerne Cypher. Cependant, je pourrais vous aider à trouver une solution à votre problème en Gremlin. Je pourrais créer un graphe similaire au vôtre et lancer une traversée Gremlin sur celui-ci.

Mon graphique ressemble à :

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> 

J'ai écrit une traversée pour générer des indices de similarité pour n'importe quel sommet, indiqué par start contre un tableau d'identifiants restants. Ma traversée finale ressemble à ça :

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

Sortie :

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

La traversée ci-dessus se traduit directement par votre formule/calcul. Il pourrait être optimisé pour les performances avec la traversée du graphique. En outre, vous pouvez consulter la documentation de Gremlin pour comprendre les choses en détail. https://github.com/tinkerpop/gremlin/wiki

Outre la liste de diffusion Neo4j, dont vous êtes déjà membre, vous pouvez également poser vos questions sur la liste de diffusion Gremlin : https://groups.google.com/group/gremlin-users

2voto

Luanne Points 4127

Je ne suis pas très doué pour les formules, mais il y a deux articles de blog sur le calcul de la similarité qui pourraient vous intéresser - vous pouvez toujours l'adapter pour être plus précis selon votre formule -.

Celui-ci utilise Gremlin : http://blog.everymansoftware.com/2012/02/similarity-based-recommendation-engines.html

Et ça utilise Cypher : http://thought-bytes.blogspot.in/2012/02/similarity-based-recommendations-with.html

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X