Your SlideShare is downloading. ×
ParisDataGeek - L amour est dans le graphe
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Introducing the official SlideShare app

Stunning, full-screen experience for iPhone and Android

Text the download link to your phone

Standard text messaging rates apply

ParisDataGeek - L amour est dans le graphe

1,580
views

Published on

L'amour est dans le graphe …

L'amour est dans le graphe

Un loft ou un pré pour trouver l'amour en 2013 ? Has-been, embrassez plutôt le graphe !

C'est en s'appuyant sur ce concept que MEETIC et OCTO ont choisi de prototyper le développement d'un moteur de recommandation construit autour d'une base de données graphe. Basé sur les principes du filtrage collaboratif, l'objectif est donc d'optimiser les propositions de rencontre en fonction des interactions entre les membres et d'autres axes possibles. Nous vous présenterons donc lors de cette session les différentes étapes de constructions de ce PoC en détaillant les choix technologiques réalisés, le code produit et les limites atteintes.

Alors si vous êtes curieux de découvrir Neo4j, le langage Cypher et la manipulation de tous ces concepts en PHP, venez assister à la première saison !

Published in: Technology

0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,580
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
0
Comments
0
Likes
4
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. 1Tél : +33 (0)1 58 56 10 00Fax : +33 (0)1 58 56 10 01www.octo.com© OCTO 201350, avenue des Champs-Elysées75008 Paris - FRANCEDjamel Zouaoui – Meetup ParisDataGeek21/05/2013@DjamelOnLinegraphe
  • 2. 2C’est quoi ?Un retourd’expérienceSur ledéveloppementd’un moteur derecommandationBasé sur lesinteractions entremembresConstruit autourd’une basegraphe (Neo4j)Eric DupréR&D Deputy Director@RicouninhoMatthieu RobinResponsable Core AnalyseDjamel ZouaouiManager@DjamelOnLineThomas VialArchitecte senior
  • 3. 3Recommandation ?Source : Machine Learning by Andrew Ng – Coursera
  • 4. 4Filtrage collaboratifDjamelMoi
  • 5. 5Filtrage collaboratifDjamelNellyCelineMarinaMoiLes personnes avec qui j’ai eu desinteractions
  • 6. 6Filtrage collaboratifDjamelNellyCelineMarinaThomasRudyMathieuDavidMoiLes personnes avec qui j’ai eu desinteractionsMes « Senders like me »
  • 7. 7Filtrage collaboratifDjamelNellyCelineMarinaThomasRudyMathieuDavidPaulineAnneCarolineMoiLes personnes avec qui j’ai eu desinteractionsMes « Senders like me » Mes « prospects »SitiSabrina
  • 8. 8Filtrage collaboratifDjamelNellyCelineMarinaThomasRudyMathieuDavidPaulineAnneCarolineMoiLes personnes avec qui j’ai eu desinteractionsMes « Senders like me » Mes « prospects »SitiSabrinaPondération : 3Pondération : 1Pondération : 2Pondération : 1Pondération : 2
  • 9. 9Vue d’ensembleBatch derequetageServeur Neo4JBatch d’importMembresInteractionsProspects
  • 10. 10Périmètre de la sessionBatch derequetageServeur Neo4JBatch d’importMembresInteractionsProspectsLa requête de filtrage collaboratif a été écrite en langage CypherGremlin a été évalué pour l’écriture de l’algorithme de filtrage collaboratif mais abandonné àcause de ces limitationsDes limites sur les primitives présentes de base dans le langage gremlinDes limites sur les features présentes (ex : évaluation native de variable dans la requête)Gremlin est bati sur le langage groovy et n’est donc pas « naturel » à lutilisation avec du php (oun’importe quel autre langage que java)Des retours d’expérience de l’éditeur (non atteint dans notre poc) concernant des problèmes deperformance (à priori lié à lutilisation de groovy et l’overhead que cela apporte)
  • 11. 11START me = node:node_auto_index(abo_id=170021316)MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slm-[:wink|favorite]->prospectsWHERE not(me = slm) and not(me--prospects)RETURN count(*) AS prospectsWeight, prospects.attraction AS attraction, prospects.abo_id AS abo_idORDER BY count DESC, attraction DESC, abo_id DESC;Requête CYPHER : cas d’écoleDjamelNellyCelineMarinaThomasRudyMathieuDavidPaulineAnneCarolineSitiSabrinaPondération : 3Pondération : 1Pondération : 2Pondération : 1Pondération : 2
  • 12. 12Requête CYPHER : cas d’écoleDjamelNellyCelineMarinaThomasRudyMathieuDavidPaulineAnneCarolineSitiSabrinaSTART me = node:node_auto_index(abo_id=170021316)MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slm-[:wink|favorite]->prospectsWHERE not(me = slm) and not(me--prospects)RETURN count(*) AS prospectsWeight, prospects.attraction AS attraction, prospects.abo_id AS abo_idORDER BY count DESC, attraction DESC, abo_id DESC;Pondération : 3Pondération : 1Pondération : 2Pondération : 1Pondération : 2
  • 13. 13Requête CYPHER : cas d’écoleDjamelNellyCelineMarinaThomasRudyMathieuDavidPaulineAnneCarolineSitiSabrinaSTART me = node:node_auto_index(abo_id=170021316)MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slm-[:wink|favorite]->prospectsWHERE not(me = slm) and not(me--prospects)RETURN count(*) AS prospectsWeight, prospects.attraction AS attraction, prospects.abo_id AS abo_idORDER BY count DESC, attraction DESC, abo_id DESC;Pondération : 3Pondération : 1Pondération : 2Pondération : 1Pondération : 2
  • 14. 14Requête CYPHER : cas d’écoleDjamelNellyCelineMarinaThomasRudyMathieuDavidPaulineAnneCarolineSitiSabrinaSTART me = node:node_auto_index(abo_id=170021316)MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slm-[:wink|favorite]->prospectsWHERE not(me = slm) and not(me--prospects)RETURN count(*) AS prospectsWeight, prospects.attraction AS attraction, prospects.abo_id AS abo_idORDER BY count DESC, attraction DESC, abo_id DESC;Pondération : 3Pondération : 1Pondération : 2Pondération : 1Pondération : 2
  • 15. 15Requête CYPHER : cas d’écoleDjamelNellyCelineMarinaThomasRudyMathieuDavidPaulineAnneCarolineSitiSabrinaSTART me = node:node_auto_index(abo_id=170021316)MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slm-[:wink|favorite]->prospectsWHERE not(me = slm) and not(me--prospects)RETURN count(*) AS prospectsWeight, prospects.attraction AS attraction, prospects.abo_id AS abo_idORDER BY count DESC, attraction DESC, abo_id DESC;Pondération : 3Pondération : 1Pondération : 2Pondération : 1Pondération : 2
  • 16. 16START me = node:node_auto_index(abo_id=170021316)MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slm-[:wink|favorite]->prospectsWHERE not(me = slm) and not(me--prospects)RETURN count(*) AS prospectsWeight, prospects.attraction AS attraction, prospects.abo_id AS abo_idORDER BY count DESC, attraction DESC, abo_id DESC;Requête CYPHER : cas d’écoleDjamelNellyCelineMarinaThomasRudyMathieuDavidPaulineAnneCarolineSitiSabrinaPondération : 3Pondération : 1Pondération : 2Pondération : 1Pondération : 2
  • 17. 170.111010010000 5000 10000 15000 20000 25000 30000TempsensecondesNombre de prospectsMais les performances…
  • 18. 18Le problème : « les serials »Les serial dragueurs* Attention, cet homme se cache dans la salle * La fameuse Pauline, mais elle n’est pas dans lasalle…Les serial bombes98% des personnes dans notredataset ont réalisé moins de 107interactionsLe max est à 2640 avec unemoyenne à 304 sur les 2 derniers %98% des personnes dans notredataset ont reçu moins de 78sollicitationsLe max est à 955 avec unemoyenne à 176 sur les 2 derniers %
  • 19. 19Monsieur X est un membre :Il a eu 43 interactions avec d’autres membresCela le connecte à 3 265 « sender like me » distinctsmais en comptant la pondération cela représente 8 764 chemins différents (doncautant de nœuds)Au final il dispose de 37 467 « prospects »Mais en prenant la pondération cela représente 2 050 395Quelques chiffresDe part la nature connectée des graphes, les nœuds les plus connectésinfluent de façon significative sur les nœuds les moins connectés dans notrecontexte
  • 20. 20Optimisations
  • 21. 21START me = node:node_auto_index(abo_id=170021316)MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slmWHERE not(me = slm) AND slm.age > me.age -10 and slm.age < me.age + 5AND slm.nbFavoriteOut + slm.nbWinkOut < 100WITH me, slm, count(*) AS slmWeightORDER BY slmWeight DESCLIMIT 20MATCH slm-[:wink|favorite]->prospectsWITH me, prospects, sum(slmWeight) AS prospectsWeightWHERE not(me--prospects)RETURN prospectsWeight AS count, prospects.attraction AS attraction, prospects.abo_id AS abo_idORDER BY count DESC, attraction DESC, abo_id DESCLIMIT 100;Optimisations fonctionnelles [1/3]Les filtres fonctionnelsPour aller plus loin : Machine learning et/ou statistiques pour découvrir les features les plus représentatives
  • 22. 22Optimisations fonctionnelles [2/3]Filtrer les serial dragueursPour aller plus loin : Modélisation optimisée avec une notion de nœud éligible/non éligible et des requêtes baséessur la connectivitéSTART me = node:node_auto_index(abo_id=170021316)MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slmWHERE not(me = slm) AND slm.age > me.age -10 and slm.age < me.age + 5AND slm.nbFavoriteOut + slm.nbWinkOut < 100WITH me, slm, count(*) AS slmWeightORDER BY slmWeight DESCLIMIT 20MATCH slm-[:wink|favorite]->prospectsWITH me, prospects, sum(slmWeight) AS prospectsWeightWHERE not(me--prospects)RETURN prospectsWeight AS count, prospects.attraction AS attraction, prospects.abo_id AS abo_idORDER BY count DESC, attraction DESC, abo_id DESCLIMIT 100;
  • 23. 23Optimisations fonctionnelles [3/3]N’utiliser que les « senders like me » les plusreprésentatifsPour aller plus loin : Valeur à affiner en fonction des données et à mettre en musique avec l’ensemble desoptimisations fonctionnellesSTART me = node:node_auto_index(abo_id=170021316)MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slmWHERE not(me = slm) AND slm.age > me.age -10 and slm.age < me.age + 5AND slm.nbFavoriteOut + slm.nbWinkOut < 100WITH me, slm, count(*) AS slmWeightORDER BY slmWeight DESCLIMIT 20MATCH slm-[:wink|favorite]->prospectsWITH me, prospects, sum(slmWeight) AS prospectsWeightWHERE not(me--prospects)RETURN prospectsWeight AS count, prospects.attraction AS attraction, prospects.abo_id AS abo_idORDER BY count DESC, attraction DESC, abo_id DESCLIMIT 100;
  • 24. 24Optimisations techniques [1/4]Utilisation des sous requêtes (WITH)Pour aller plus loin : Evidemment comme chaque optimisation technique, elle est liée à une situation donnée etpeut donc dans certains cas être inopérante voire pénalisanteSTART me = node:node_auto_index(abo_id=170021316)MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slmWHERE not(me = slm) AND slm.age > me.age -10 and slm.age < me.age + 5AND slm.nbFavoriteOut + slm.nbWinkOut < 100WITH me, slm, count(*) AS slmWeightORDER BY slmWeight DESCLIMIT 20MATCH slm-[:wink|favorite]->prospectsWITH me, prospects, sum(slmWeight) AS prospectsWeightWHERE not(me--prospects)RETURN prospectsWeight AS count, prospects.attraction AS attraction, prospects.abo_id AS abo_idORDER BY count DESC, attraction DESC, abo_id DESCLIMIT 100;
  • 25. 25Et ça donne quoi ?0.00010.0010.010.110 100 200 300 400 500 600 700 800 900ExecutionTime(s)Number of prospects
  • 26. 26Optimisations techniques [2/4]Utilisation des « unmanaged extension »Pour aller plus loin : Analyse profonde du plan d’éxecution pour comprendre qu’elle est la partie à optimiser / àdébrancher
  • 27. 27Et maintenant ?
  • 28. 28Optimisations techniques [3/4]Utilisation des « api core »Pour aller plus loin : Nécessite une bonne connaissance des data structures utilisées et de la complexité associée
  • 29. 29Optimisations techniques [4/4]Optimisation des cachesPour aller plus loin : Nécessite d’avoir une vision assez fine de la modélisation mais aussi des requêtes d’accès àla donnée (en collaboration avec les développeurs et pas en amont des développements)Cache de nœudsCache de relationsCache de clefs d’indexCache de valeurs d’indexCache des propriétés...
  • 30. 30Meetic est une boîte innovante (et si vous êtes célibataire elle peut vous aider )PHP ce n’est pas si mal (contrairement à ce dont je me souvenais…)Les graphes et Neo4j apportent une vraie réponse dans le traitement desdonnées fortement connectéesLes datastores NoSql sont des produits puissants mais pas magiquesIl existe des données encore vierges (ou presque) d’analyse et ellesreprésentent des potentiels gisements de valeur donc open « your mind andkiss the graph»Ce qu’il faut retenir