SlideShare a Scribd company logo
1 of 30
1
Tél : +33 (0)1 58 56 10 00
Fax : +33 (0)1 58 56 10 01
www.octo.com© OCTO 2013
50, avenue des Champs-Elysées
75008 Paris - FRANCE
Djamel Zouaoui – Meetup ParisDataGeek
21/05/2013
@DjamelOnLine
graph
e
2
C’est quoi ?
Un retour
d’expérience
Sur le
développement
d’un moteur de
recommandation
Basé sur les
interactions entre
membres
Construit autour
d’une base
graphe (Neo4j)
Eric Dupré
R&D Deputy Director
@Ricouninho
Matthieu Robin
Responsable Core Analyse
Djamel Zouaoui
Manager
@DjamelOnLine
Thomas Vial
Architecte senior
3
Recommandation ?
Source : Machine Learning by Andrew Ng – Coursera
4
Filtrage collaboratif
Djamel
Moi
5
Filtrage collaboratif
Djamel
Nelly
Celine
Marina
Moi
Les personnes avec qui j’ai eu des
interactions
6
Filtrage collaboratif
Djamel
Nelly
Celine
Marina
Thomas
Rudy
Mathieu
David
Moi
Les personnes avec qui j’ai eu des
interactions
Mes « Senders like me »
7
Filtrage collaboratif
Djamel
Nelly
Celine
Marina
Thomas
Rudy
Mathieu
David
Pauline
Anne
Caroline
Moi
Les personnes avec qui j’ai eu des
interactions
Mes « Senders like me » Mes « prospects »
Siti
Sabrina
8
Filtrage collaboratif
Djamel
Nelly
Celine
Marina
Thomas
Rudy
Mathieu
David
Pauline
Anne
Caroline
Moi
Les personnes avec qui j’ai eu des
interactions
Mes « Senders like me » Mes « prospects »
Siti
Sabrina
Pondération : 3
Pondération : 1
Pondération : 2
Pondération : 1
Pondération : 2
9
Vue d’ensemble
Batch de
requetage
Serveur Neo4J
Batch d’import
Membres
Interactions
Prospects
10
Périmètre de la session
Batch de
requetage
Serveur Neo4J
Batch d’import
Membres
Interactions
Prospects
La requête de filtrage collaboratif a été écrite en langage Cypher
Gremlin a été évalué pour l’écriture de l’algorithme de filtrage collaboratif mais abandonné à
cause de ces limitations
Des limites sur les primitives présentes de base dans le langage gremlin
Des 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 » à l'utilisation avec du php (ou
n’importe quel autre langage que java)
Des retours d’expérience de l’éditeur (non atteint dans notre poc) concernant des problèmes de
performance (à priori lié à l'utilisation de groovy et l’overhead que cela apporte)
11
START me = node:node_auto_index(abo_id='170021316')
MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slm-[:wink|favorite]->prospects
WHERE not(me = slm) and not(me--prospects)
RETURN count(*) AS prospectsWeight, prospects.attraction AS attraction, prospects.abo_id AS abo_id
ORDER BY count DESC, attraction DESC, abo_id DESC;
Requête CYPHER : cas d’école
Djamel
Nelly
Celine
Marina
Thomas
Rudy
Mathieu
David
Pauline
Anne
Caroline
Siti
Sabrina
Pondération : 3
Pondération : 1
Pondération : 2
Pondération : 1
Pondération : 2
12
Requête CYPHER : cas d’école
Djamel
Nelly
Celine
Marina
Thomas
Rudy
Mathieu
David
Pauline
Anne
Caroline
Siti
Sabrina
START me = node:node_auto_index(abo_id='170021316')
MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slm-[:wink|favorite]->prospects
WHERE not(me = slm) and not(me--prospects)
RETURN count(*) AS prospectsWeight, prospects.attraction AS attraction, prospects.abo_id AS abo_id
ORDER BY count DESC, attraction DESC, abo_id DESC;
Pondération : 3
Pondération : 1
Pondération : 2
Pondération : 1
Pondération : 2
13
Requête CYPHER : cas d’école
Djamel
Nelly
Celine
Marina
Thomas
Rudy
Mathieu
David
Pauline
Anne
Caroline
Siti
Sabrina
START me = node:node_auto_index(abo_id='170021316')
MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slm-[:wink|favorite]->prospects
WHERE not(me = slm) and not(me--prospects)
RETURN count(*) AS prospectsWeight, prospects.attraction AS attraction, prospects.abo_id AS abo_id
ORDER BY count DESC, attraction DESC, abo_id DESC;
Pondération : 3
Pondération : 1
Pondération : 2
Pondération : 1
Pondération : 2
14
Requête CYPHER : cas d’école
Djamel
Nelly
Celine
Marina
Thomas
Rudy
Mathieu
David
Pauline
Anne
Caroline
Siti
Sabrina
START me = node:node_auto_index(abo_id='170021316')
MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slm-[:wink|favorite]->prospects
WHERE not(me = slm) and not(me--prospects)
RETURN count(*) AS prospectsWeight, prospects.attraction AS attraction, prospects.abo_id AS abo_id
ORDER BY count DESC, attraction DESC, abo_id DESC;
Pondération : 3
Pondération : 1
Pondération : 2
Pondération : 1
Pondération : 2
15
Requête CYPHER : cas d’école
Djamel
Nelly
Celine
Marina
Thomas
Rudy
Mathieu
David
Pauline
Anne
Caroline
Siti
Sabrina
START me = node:node_auto_index(abo_id='170021316')
MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slm-[:wink|favorite]->prospects
WHERE not(me = slm) and not(me--prospects)
RETURN count(*) AS prospectsWeight, prospects.attraction AS attraction, prospects.abo_id AS abo_id
ORDER BY count DESC, attraction DESC, abo_id DESC;
Pondération : 3
Pondération : 1
Pondération : 2
Pondération : 1
Pondération : 2
16
START me = node:node_auto_index(abo_id='170021316')
MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slm-[:wink|favorite]->prospects
WHERE not(me = slm) and not(me--prospects)
RETURN count(*) AS prospectsWeight, prospects.attraction AS attraction, prospects.abo_id AS abo_id
ORDER BY count DESC, attraction DESC, abo_id DESC;
Requête CYPHER : cas d’école
Djamel
Nelly
Celine
Marina
Thomas
Rudy
Mathieu
David
Pauline
Anne
Caroline
Siti
Sabrina
Pondération : 3
Pondération : 1
Pondération : 2
Pondération : 1
Pondération : 2
17
0.1
1
10
100
1000
0 5000 10000 15000 20000 25000 30000
Tempsensecondes
Nombre de prospects
Mais les performances…
18
Le problème : « les serials »
Les serial dragueurs
* Attention, cet homme se cache dans la salle * La fameuse Pauline, mais elle n’est pas dans la
salle…
Les serial bombes
98% des personnes dans notre
dataset ont réalisé moins de 107
interactions
Le max est à 2640 avec une
moyenne à 304 sur les 2 derniers %
98% des personnes dans notre
dataset ont reçu moins de 78
sollicitations
Le max est à 955 avec une
moyenne à 176 sur les 2 derniers %
19
Monsieur X est un membre :
Il a eu 43 interactions avec d’autres membres
Cela le connecte à 3 265 « sender like me » distincts
mais en comptant la pondération cela représente 8 764 chemins différents (donc
autant de nœuds)
Au final il dispose de 37 467 « prospects »
Mais en prenant la pondération cela représente 2 050 395
Quelques chiffres
De part la nature connectée des graphes, les nœuds les plus connectés
influent de façon significative sur les nœuds les moins connectés dans notre
contexte
20
Optimisations
21
START me = node:node_auto_index(abo_id='170021316')
MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slm
WHERE not(me = slm) AND slm.age > me.age -10 and slm.age < me.age + 5
AND slm.nbFavoriteOut + slm.nbWinkOut < 100
WITH me, slm, count(*) AS slmWeight
ORDER BY slmWeight DESC
LIMIT 20
MATCH slm-[:wink|favorite]->prospects
WITH me, prospects, sum(slmWeight) AS prospectsWeight
WHERE not(me--prospects)
RETURN prospectsWeight AS count, prospects.attraction AS attraction, prospects.abo_id AS abo_id
ORDER BY count DESC, attraction DESC, abo_id DESC
LIMIT 100;
Optimisations fonctionnelles [1/3]
Les filtres fonctionnels
Pour aller plus loin : Machine learning et/ou statistiques pour découvrir les features les plus représentatives
22
Optimisations fonctionnelles [2/3]
Filtrer les serial dragueurs
Pour aller plus loin : Modélisation optimisée avec une notion de nœud éligible/non éligible et des requêtes basées
sur la connectivité
START me = node:node_auto_index(abo_id='170021316')
MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slm
WHERE not(me = slm) AND slm.age > me.age -10 and slm.age < me.age + 5
AND slm.nbFavoriteOut + slm.nbWinkOut < 100
WITH me, slm, count(*) AS slmWeight
ORDER BY slmWeight DESC
LIMIT 20
MATCH slm-[:wink|favorite]->prospects
WITH me, prospects, sum(slmWeight) AS prospectsWeight
WHERE not(me--prospects)
RETURN prospectsWeight AS count, prospects.attraction AS attraction, prospects.abo_id AS abo_id
ORDER BY count DESC, attraction DESC, abo_id DESC
LIMIT 100;
23
Optimisations fonctionnelles [3/3]
N’utiliser que les « senders like me » les plus
représentatifs
Pour aller plus loin : Valeur à affiner en fonction des données et à mettre en musique avec l’ensemble des
optimisations fonctionnelles
START me = node:node_auto_index(abo_id='170021316')
MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slm
WHERE not(me = slm) AND slm.age > me.age -10 and slm.age < me.age + 5
AND slm.nbFavoriteOut + slm.nbWinkOut < 100
WITH me, slm, count(*) AS slmWeight
ORDER BY slmWeight DESC
LIMIT 20
MATCH slm-[:wink|favorite]->prospects
WITH me, prospects, sum(slmWeight) AS prospectsWeight
WHERE not(me--prospects)
RETURN prospectsWeight AS count, prospects.attraction AS attraction, prospects.abo_id AS abo_id
ORDER BY count DESC, attraction DESC, abo_id DESC
LIMIT 100;
24
Optimisations 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 et
peut donc dans certains cas être inopérante voire pénalisante
START me = node:node_auto_index(abo_id='170021316')
MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slm
WHERE not(me = slm) AND slm.age > me.age -10 and slm.age < me.age + 5
AND slm.nbFavoriteOut + slm.nbWinkOut < 100
WITH me, slm, count(*) AS slmWeight
ORDER BY slmWeight DESC
LIMIT 20
MATCH slm-[:wink|favorite]->prospects
WITH me, prospects, sum(slmWeight) AS prospectsWeight
WHERE not(me--prospects)
RETURN prospectsWeight AS count, prospects.attraction AS attraction, prospects.abo_id AS abo_id
ORDER BY count DESC, attraction DESC, abo_id DESC
LIMIT 100;
25
Et ça donne quoi ?
0.0001
0.001
0.01
0.1
1
0 100 200 300 400 500 600 700 800 900
ExecutionTime(s)
Number of prospects
26
Optimisations 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
Et maintenant ?
28
Optimisations 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
Optimisations techniques [4/4]
Optimisation des caches
Pour 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œuds
Cache de relations
Cache de clefs d’index
Cache de valeurs d’index
Cache des propriétés
...
30
Meetic 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 des
données fortement connectées
Les datastores NoSql sont des produits puissants mais pas magiques
Il existe des données encore vierges (ou presque) d’analyse et elles
représentent des potentiels gisements de valeur donc open « your mind and
kiss the graph»
Ce qu’il faut retenir

More Related Content

Viewers also liked

Presentation phytofar nouvelles législations 12092012 compressed
Presentation phytofar nouvelles législations 12092012 compressedPresentation phytofar nouvelles législations 12092012 compressed
Presentation phytofar nouvelles législations 12092012 compressedPhytofar mobile
 
Carrieres informatiques
Carrieres informatiquesCarrieres informatiques
Carrieres informatiquesFreddy266
 
Prédire des tendances et mesurer l’économie
Prédire des tendances et mesurer l’économiePrédire des tendances et mesurer l’économie
Prédire des tendances et mesurer l’économieTalkwalker
 
Presentation croquis avize
Presentation croquis avizePresentation croquis avize
Presentation croquis avizesalleherodote
 
Jean luc boeuf - La réforme des territoires et les collectivités locales
Jean luc boeuf - La réforme des territoires et les collectivités localesJean luc boeuf - La réforme des territoires et les collectivités locales
Jean luc boeuf - La réforme des territoires et les collectivités localesJean Luc Boeuf
 
Portfolio elsie violet
Portfolio elsie violetPortfolio elsie violet
Portfolio elsie violetelsieviolet
 
Assemblée générale 2013 - La Boule Joyeuse - Aubord
Assemblée générale 2013 - La Boule Joyeuse - AubordAssemblée générale 2013 - La Boule Joyeuse - Aubord
Assemblée générale 2013 - La Boule Joyeuse - Aubordkeelefr
 
Identification de la problématique par le document
Identification de la problématique par le documentIdentification de la problématique par le document
Identification de la problématique par le documentbusterkeaton974
 
Bilan 2006-2012 des formations documentaires à l'École Centrale de Lyon
Bilan 2006-2012 des formations documentaires à l'École Centrale de LyonBilan 2006-2012 des formations documentaires à l'École Centrale de Lyon
Bilan 2006-2012 des formations documentaires à l'École Centrale de LyonCéline Andrieu
 
Luxury Kiosks
Luxury KiosksLuxury Kiosks
Luxury Kioskskslaoui
 
L'art de la guerre
L'art de la guerreL'art de la guerre
L'art de la guerreLepic
 
Rechercher des informations en Sciences Humaines et Sociales
Rechercher des informations en Sciences Humaines et SocialesRechercher des informations en Sciences Humaines et Sociales
Rechercher des informations en Sciences Humaines et SocialesCéline Andrieu
 
Réunion Publique - Liste "Unis Pour Agir" - 18 mars 2014
Réunion Publique - Liste "Unis Pour Agir" - 18 mars 2014Réunion Publique - Liste "Unis Pour Agir" - 18 mars 2014
Réunion Publique - Liste "Unis Pour Agir" - 18 mars 2014Unis-Pour-Agir
 
Bilan sarkozy dans le finistère
Bilan sarkozy dans le finistèreBilan sarkozy dans le finistère
Bilan sarkozy dans le finistèregraves146
 

Viewers also liked (18)

Presentation phytofar nouvelles législations 12092012 compressed
Presentation phytofar nouvelles législations 12092012 compressedPresentation phytofar nouvelles législations 12092012 compressed
Presentation phytofar nouvelles législations 12092012 compressed
 
Évaluation des apprentissages
Évaluation des apprentissagesÉvaluation des apprentissages
Évaluation des apprentissages
 
Carrieres informatiques
Carrieres informatiquesCarrieres informatiques
Carrieres informatiques
 
Prédire des tendances et mesurer l’économie
Prédire des tendances et mesurer l’économiePrédire des tendances et mesurer l’économie
Prédire des tendances et mesurer l’économie
 
Presentation croquis avize
Presentation croquis avizePresentation croquis avize
Presentation croquis avize
 
Barriere secu
Barriere secuBarriere secu
Barriere secu
 
Jean luc boeuf - La réforme des territoires et les collectivités locales
Jean luc boeuf - La réforme des territoires et les collectivités localesJean luc boeuf - La réforme des territoires et les collectivités locales
Jean luc boeuf - La réforme des territoires et les collectivités locales
 
Portfolio elsie violet
Portfolio elsie violetPortfolio elsie violet
Portfolio elsie violet
 
Assemblée générale 2013 - La Boule Joyeuse - Aubord
Assemblée générale 2013 - La Boule Joyeuse - AubordAssemblée générale 2013 - La Boule Joyeuse - Aubord
Assemblée générale 2013 - La Boule Joyeuse - Aubord
 
Identification de la problématique par le document
Identification de la problématique par le documentIdentification de la problématique par le document
Identification de la problématique par le document
 
Bilan 2006-2012 des formations documentaires à l'École Centrale de Lyon
Bilan 2006-2012 des formations documentaires à l'École Centrale de LyonBilan 2006-2012 des formations documentaires à l'École Centrale de Lyon
Bilan 2006-2012 des formations documentaires à l'École Centrale de Lyon
 
Luxury Kiosks
Luxury KiosksLuxury Kiosks
Luxury Kiosks
 
Parte 2
Parte 2Parte 2
Parte 2
 
L'art de la guerre
L'art de la guerreL'art de la guerre
L'art de la guerre
 
Rechercher des informations en Sciences Humaines et Sociales
Rechercher des informations en Sciences Humaines et SocialesRechercher des informations en Sciences Humaines et Sociales
Rechercher des informations en Sciences Humaines et Sociales
 
Bretagne at Dawajine 2015
Bretagne at Dawajine 2015 Bretagne at Dawajine 2015
Bretagne at Dawajine 2015
 
Réunion Publique - Liste "Unis Pour Agir" - 18 mars 2014
Réunion Publique - Liste "Unis Pour Agir" - 18 mars 2014Réunion Publique - Liste "Unis Pour Agir" - 18 mars 2014
Réunion Publique - Liste "Unis Pour Agir" - 18 mars 2014
 
Bilan sarkozy dans le finistère
Bilan sarkozy dans le finistèreBilan sarkozy dans le finistère
Bilan sarkozy dans le finistère
 

More from Djamel Zouaoui

Paris Data Geek - Spark Streaming
Paris Data Geek - Spark Streaming Paris Data Geek - Spark Streaming
Paris Data Geek - Spark Streaming Djamel Zouaoui
 
Datajob 2013 - Construire un système de recommandation
Datajob 2013 - Construire un système de recommandationDatajob 2013 - Construire un système de recommandation
Datajob 2013 - Construire un système de recommandationDjamel Zouaoui
 
Usi 2013 - NoSql les defis à relever
Usi 2013 -  NoSql les defis à releverUsi 2013 -  NoSql les defis à relever
Usi 2013 - NoSql les defis à releverDjamel Zouaoui
 
Microsoft Tech days 2007 - Industrialisation des développements : Retours d'e...
Microsoft Tech days 2007 - Industrialisation des développements : Retours d'e...Microsoft Tech days 2007 - Industrialisation des développements : Retours d'e...
Microsoft Tech days 2007 - Industrialisation des développements : Retours d'e...Djamel Zouaoui
 
USI 2009 - Du RIA pour SI
USI 2009 - Du RIA pour SIUSI 2009 - Du RIA pour SI
USI 2009 - Du RIA pour SIDjamel Zouaoui
 
Retour d'expérience TechLead
Retour d'expérience TechLeadRetour d'expérience TechLead
Retour d'expérience TechLeadDjamel Zouaoui
 
Présentation Alt.net - Tests unitaires automatisés
Présentation Alt.net - Tests unitaires automatisésPrésentation Alt.net - Tests unitaires automatisés
Présentation Alt.net - Tests unitaires automatisésDjamel Zouaoui
 
USI Casablanca 2010 - Industrialisation et intégration continue
USI Casablanca 2010 - Industrialisation et intégration continueUSI Casablanca 2010 - Industrialisation et intégration continue
USI Casablanca 2010 - Industrialisation et intégration continueDjamel Zouaoui
 
USI 2011 - De l offshore qui fonctionne !
USI 2011 - De l offshore qui fonctionne !USI 2011 - De l offshore qui fonctionne !
USI 2011 - De l offshore qui fonctionne !Djamel Zouaoui
 

More from Djamel Zouaoui (9)

Paris Data Geek - Spark Streaming
Paris Data Geek - Spark Streaming Paris Data Geek - Spark Streaming
Paris Data Geek - Spark Streaming
 
Datajob 2013 - Construire un système de recommandation
Datajob 2013 - Construire un système de recommandationDatajob 2013 - Construire un système de recommandation
Datajob 2013 - Construire un système de recommandation
 
Usi 2013 - NoSql les defis à relever
Usi 2013 -  NoSql les defis à releverUsi 2013 -  NoSql les defis à relever
Usi 2013 - NoSql les defis à relever
 
Microsoft Tech days 2007 - Industrialisation des développements : Retours d'e...
Microsoft Tech days 2007 - Industrialisation des développements : Retours d'e...Microsoft Tech days 2007 - Industrialisation des développements : Retours d'e...
Microsoft Tech days 2007 - Industrialisation des développements : Retours d'e...
 
USI 2009 - Du RIA pour SI
USI 2009 - Du RIA pour SIUSI 2009 - Du RIA pour SI
USI 2009 - Du RIA pour SI
 
Retour d'expérience TechLead
Retour d'expérience TechLeadRetour d'expérience TechLead
Retour d'expérience TechLead
 
Présentation Alt.net - Tests unitaires automatisés
Présentation Alt.net - Tests unitaires automatisésPrésentation Alt.net - Tests unitaires automatisés
Présentation Alt.net - Tests unitaires automatisés
 
USI Casablanca 2010 - Industrialisation et intégration continue
USI Casablanca 2010 - Industrialisation et intégration continueUSI Casablanca 2010 - Industrialisation et intégration continue
USI Casablanca 2010 - Industrialisation et intégration continue
 
USI 2011 - De l offshore qui fonctionne !
USI 2011 - De l offshore qui fonctionne !USI 2011 - De l offshore qui fonctionne !
USI 2011 - De l offshore qui fonctionne !
 

ParisDataGeek - L amour est dans le graphe

  • 1. 1 Tél : +33 (0)1 58 56 10 00 Fax : +33 (0)1 58 56 10 01 www.octo.com© OCTO 2013 50, avenue des Champs-Elysées 75008 Paris - FRANCE Djamel Zouaoui – Meetup ParisDataGeek 21/05/2013 @DjamelOnLine graph e
  • 2. 2 C’est quoi ? Un retour d’expérience Sur le développement d’un moteur de recommandation Basé sur les interactions entre membres Construit autour d’une base graphe (Neo4j) Eric Dupré R&D Deputy Director @Ricouninho Matthieu Robin Responsable Core Analyse Djamel Zouaoui Manager @DjamelOnLine Thomas Vial Architecte senior
  • 3. 3 Recommandation ? Source : Machine Learning by Andrew Ng – Coursera
  • 6. 6 Filtrage collaboratif Djamel Nelly Celine Marina Thomas Rudy Mathieu David Moi Les personnes avec qui j’ai eu des interactions Mes « Senders like me »
  • 7. 7 Filtrage collaboratif Djamel Nelly Celine Marina Thomas Rudy Mathieu David Pauline Anne Caroline Moi Les personnes avec qui j’ai eu des interactions Mes « Senders like me » Mes « prospects » Siti Sabrina
  • 8. 8 Filtrage collaboratif Djamel Nelly Celine Marina Thomas Rudy Mathieu David Pauline Anne Caroline Moi Les personnes avec qui j’ai eu des interactions Mes « Senders like me » Mes « prospects » Siti Sabrina Pondération : 3 Pondération : 1 Pondération : 2 Pondération : 1 Pondération : 2
  • 9. 9 Vue d’ensemble Batch de requetage Serveur Neo4J Batch d’import Membres Interactions Prospects
  • 10. 10 Périmètre de la session Batch de requetage Serveur Neo4J Batch d’import Membres Interactions Prospects La requête de filtrage collaboratif a été écrite en langage Cypher Gremlin a été évalué pour l’écriture de l’algorithme de filtrage collaboratif mais abandonné à cause de ces limitations Des limites sur les primitives présentes de base dans le langage gremlin Des 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 » à l'utilisation avec du php (ou n’importe quel autre langage que java) Des retours d’expérience de l’éditeur (non atteint dans notre poc) concernant des problèmes de performance (à priori lié à l'utilisation de groovy et l’overhead que cela apporte)
  • 11. 11 START me = node:node_auto_index(abo_id='170021316') MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slm-[:wink|favorite]->prospects WHERE not(me = slm) and not(me--prospects) RETURN count(*) AS prospectsWeight, prospects.attraction AS attraction, prospects.abo_id AS abo_id ORDER BY count DESC, attraction DESC, abo_id DESC; Requête CYPHER : cas d’école Djamel Nelly Celine Marina Thomas Rudy Mathieu David Pauline Anne Caroline Siti Sabrina Pondération : 3 Pondération : 1 Pondération : 2 Pondération : 1 Pondération : 2
  • 12. 12 Requête CYPHER : cas d’école Djamel Nelly Celine Marina Thomas Rudy Mathieu David Pauline Anne Caroline Siti Sabrina START me = node:node_auto_index(abo_id='170021316') MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slm-[:wink|favorite]->prospects WHERE not(me = slm) and not(me--prospects) RETURN count(*) AS prospectsWeight, prospects.attraction AS attraction, prospects.abo_id AS abo_id ORDER BY count DESC, attraction DESC, abo_id DESC; Pondération : 3 Pondération : 1 Pondération : 2 Pondération : 1 Pondération : 2
  • 13. 13 Requête CYPHER : cas d’école Djamel Nelly Celine Marina Thomas Rudy Mathieu David Pauline Anne Caroline Siti Sabrina START me = node:node_auto_index(abo_id='170021316') MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slm-[:wink|favorite]->prospects WHERE not(me = slm) and not(me--prospects) RETURN count(*) AS prospectsWeight, prospects.attraction AS attraction, prospects.abo_id AS abo_id ORDER BY count DESC, attraction DESC, abo_id DESC; Pondération : 3 Pondération : 1 Pondération : 2 Pondération : 1 Pondération : 2
  • 14. 14 Requête CYPHER : cas d’école Djamel Nelly Celine Marina Thomas Rudy Mathieu David Pauline Anne Caroline Siti Sabrina START me = node:node_auto_index(abo_id='170021316') MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slm-[:wink|favorite]->prospects WHERE not(me = slm) and not(me--prospects) RETURN count(*) AS prospectsWeight, prospects.attraction AS attraction, prospects.abo_id AS abo_id ORDER BY count DESC, attraction DESC, abo_id DESC; Pondération : 3 Pondération : 1 Pondération : 2 Pondération : 1 Pondération : 2
  • 15. 15 Requête CYPHER : cas d’école Djamel Nelly Celine Marina Thomas Rudy Mathieu David Pauline Anne Caroline Siti Sabrina START me = node:node_auto_index(abo_id='170021316') MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slm-[:wink|favorite]->prospects WHERE not(me = slm) and not(me--prospects) RETURN count(*) AS prospectsWeight, prospects.attraction AS attraction, prospects.abo_id AS abo_id ORDER BY count DESC, attraction DESC, abo_id DESC; Pondération : 3 Pondération : 1 Pondération : 2 Pondération : 1 Pondération : 2
  • 16. 16 START me = node:node_auto_index(abo_id='170021316') MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slm-[:wink|favorite]->prospects WHERE not(me = slm) and not(me--prospects) RETURN count(*) AS prospectsWeight, prospects.attraction AS attraction, prospects.abo_id AS abo_id ORDER BY count DESC, attraction DESC, abo_id DESC; Requête CYPHER : cas d’école Djamel Nelly Celine Marina Thomas Rudy Mathieu David Pauline Anne Caroline Siti Sabrina Pondération : 3 Pondération : 1 Pondération : 2 Pondération : 1 Pondération : 2
  • 17. 17 0.1 1 10 100 1000 0 5000 10000 15000 20000 25000 30000 Tempsensecondes Nombre de prospects Mais les performances…
  • 18. 18 Le problème : « les serials » Les serial dragueurs * Attention, cet homme se cache dans la salle * La fameuse Pauline, mais elle n’est pas dans la salle… Les serial bombes 98% des personnes dans notre dataset ont réalisé moins de 107 interactions Le max est à 2640 avec une moyenne à 304 sur les 2 derniers % 98% des personnes dans notre dataset ont reçu moins de 78 sollicitations Le max est à 955 avec une moyenne à 176 sur les 2 derniers %
  • 19. 19 Monsieur X est un membre : Il a eu 43 interactions avec d’autres membres Cela le connecte à 3 265 « sender like me » distincts mais en comptant la pondération cela représente 8 764 chemins différents (donc autant de nœuds) Au final il dispose de 37 467 « prospects » Mais en prenant la pondération cela représente 2 050 395 Quelques chiffres De part la nature connectée des graphes, les nœuds les plus connectés influent de façon significative sur les nœuds les moins connectés dans notre contexte
  • 21. 21 START me = node:node_auto_index(abo_id='170021316') MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slm WHERE not(me = slm) AND slm.age > me.age -10 and slm.age < me.age + 5 AND slm.nbFavoriteOut + slm.nbWinkOut < 100 WITH me, slm, count(*) AS slmWeight ORDER BY slmWeight DESC LIMIT 20 MATCH slm-[:wink|favorite]->prospects WITH me, prospects, sum(slmWeight) AS prospectsWeight WHERE not(me--prospects) RETURN prospectsWeight AS count, prospects.attraction AS attraction, prospects.abo_id AS abo_id ORDER BY count DESC, attraction DESC, abo_id DESC LIMIT 100; Optimisations fonctionnelles [1/3] Les filtres fonctionnels Pour aller plus loin : Machine learning et/ou statistiques pour découvrir les features les plus représentatives
  • 22. 22 Optimisations fonctionnelles [2/3] Filtrer les serial dragueurs Pour aller plus loin : Modélisation optimisée avec une notion de nœud éligible/non éligible et des requêtes basées sur la connectivité START me = node:node_auto_index(abo_id='170021316') MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slm WHERE not(me = slm) AND slm.age > me.age -10 and slm.age < me.age + 5 AND slm.nbFavoriteOut + slm.nbWinkOut < 100 WITH me, slm, count(*) AS slmWeight ORDER BY slmWeight DESC LIMIT 20 MATCH slm-[:wink|favorite]->prospects WITH me, prospects, sum(slmWeight) AS prospectsWeight WHERE not(me--prospects) RETURN prospectsWeight AS count, prospects.attraction AS attraction, prospects.abo_id AS abo_id ORDER BY count DESC, attraction DESC, abo_id DESC LIMIT 100;
  • 23. 23 Optimisations fonctionnelles [3/3] N’utiliser que les « senders like me » les plus représentatifs Pour aller plus loin : Valeur à affiner en fonction des données et à mettre en musique avec l’ensemble des optimisations fonctionnelles START me = node:node_auto_index(abo_id='170021316') MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slm WHERE not(me = slm) AND slm.age > me.age -10 and slm.age < me.age + 5 AND slm.nbFavoriteOut + slm.nbWinkOut < 100 WITH me, slm, count(*) AS slmWeight ORDER BY slmWeight DESC LIMIT 20 MATCH slm-[:wink|favorite]->prospects WITH me, prospects, sum(slmWeight) AS prospectsWeight WHERE not(me--prospects) RETURN prospectsWeight AS count, prospects.attraction AS attraction, prospects.abo_id AS abo_id ORDER BY count DESC, attraction DESC, abo_id DESC LIMIT 100;
  • 24. 24 Optimisations 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 et peut donc dans certains cas être inopérante voire pénalisante START me = node:node_auto_index(abo_id='170021316') MATCH me-[:wink|favorite]->she<-[:wink|favorite]-slm WHERE not(me = slm) AND slm.age > me.age -10 and slm.age < me.age + 5 AND slm.nbFavoriteOut + slm.nbWinkOut < 100 WITH me, slm, count(*) AS slmWeight ORDER BY slmWeight DESC LIMIT 20 MATCH slm-[:wink|favorite]->prospects WITH me, prospects, sum(slmWeight) AS prospectsWeight WHERE not(me--prospects) RETURN prospectsWeight AS count, prospects.attraction AS attraction, prospects.abo_id AS abo_id ORDER BY count DESC, attraction DESC, abo_id DESC LIMIT 100;
  • 25. 25 Et ça donne quoi ? 0.0001 0.001 0.01 0.1 1 0 100 200 300 400 500 600 700 800 900 ExecutionTime(s) Number of prospects
  • 26. 26 Optimisations 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
  • 28. 28 Optimisations 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. 29 Optimisations techniques [4/4] Optimisation des caches Pour 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œuds Cache de relations Cache de clefs d’index Cache de valeurs d’index Cache des propriétés ...
  • 30. 30 Meetic 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 des données fortement connectées Les datastores NoSql sont des produits puissants mais pas magiques Il existe des données encore vierges (ou presque) d’analyse et elles représentent des potentiels gisements de valeur donc open « your mind and kiss the graph» Ce qu’il faut retenir