2016-10-10 1 views
0

Je suis nouveau sur Neo4j et Python et je tente de remplir une base de données de test avec des nœuds et des relations utilisant IPython. J'utilise py2neo v 3.1.2. Le problème que j'essaie de résoudre est de représenter une collection de phrases dans un graphique avec l'id de la phrase connecté à des mots contenus via des liens ayant le mot count comme propriété.La création graphique via Neo4j prend trop de temps

J'ai ajouté les contraintes Neo4j pertinentes pour String (num) et Word (val). Le code correspondant est donnée ici:

from py2neo import Graph, Node, Path 
import re 
graph = Graph("http://neo4j:[email protected]:7474/db/data/")  
f1 = open("test.txt", "r") 
cnt = 0 
for line in f1: 
    cnt = cnt+1 
    line=line.lower() 
    line = re.sub(r'[^\w\s]','',line) 
    wordlist = line.split() 
    lgth = len(wordlist) 
    wordfreq = [wordlist.count(w) for w in wordlist] 
    dct = dict(zip(wordlist,wordfreq)) 
    str = Node("String", num=cnt, length = lgth) 
    graph.merge(str) 
    for k, v in dct.items(): 
     wrd = Node("Word", val=k) 
     graph.merge(wrd) 
     property_dict = {"wrdcnt": v} 
     relate = Path(str, ("CONTAINS",property_dict),wrd) 
     graph.merge(relate) 

Une petite collection de 1000 lignes prend environ 10 minutes pour remplir un graphique Neo4j. Je suis sûr que je fais quelque chose de mal dans mon code python et le même peut être accéléré de manière significative. Apprécierait toute idée significative ..

+0

Avez-vous référencé juste votre analyse? En outre: vous effectuez un nombre important de fusions. Peut-être éditer votre question pour montrer les requêtes Cypher de base que vous exécuteriez, lors de l'importation. –

+0

J'ai analysé l'analyse syntaxique ... le code python zippe à travers la sous-seconde – user6948456

Répondre

0

Vous exécutez 2 requêtes par mot dans chaque phrase, plus une autre requête par phrase; Cela prend beaucoup de temps parce que vous engagez une énorme quantité de frais généraux en utilisant ces méthodes de commodité py2neo. Vous pouvez couper le chemin du retour à une seule requête par phrase si vous utilisez des paramètres et de mettre plus de travail sur Cypher:

from collections import Counter 
from string import maketrans, punctuation 
no_punc = maketrans(punctuation, ' ' * len(punctuation)) 
with open('test.txt', 'r') as f1: 
    for ct, line in enumerate(f1): 
     line = line.lower().translate(no_punc).split() 
     length = len(line) 
     dct = Counter(line) 
     graph.run(''' 
      MERGE (s:Sentence { id:{count}, length: {s_length} }) 
      WITH s 
      UNWIND keys({dct}) AS word 
      MERGE (w:Word { id: word }) 
      MERGE (s) - [:CONTAINS {wrdcnt: {dct}[word] }] -> (w)''', 
      parameters={'dct': dct, 's_length': length, 'count': ct}) 

rabbithole: Ceci est la chose entière réalisée dans une requête. Ce n'est pas joli, mais c'est potentiellement le plus rapide. En outre, assurez-vous que vous avez des index sur :Sentence(id) et dans les deux cas, il va accélérer à la fois considérablement.

from collections import Counter 
from string import maketrans, punctuation 
no_punc = maketrans(punctuation, ' ' * len(punctuation)) 
params = [] 
with open('test.txt', 'r') as f1: 
    for ct, line in enumerate(f1): 
     line = line.lower().translate(no_punc).split() 
     length = len(line) 
     dct = Counter(line) 
     params.append({'dct': dct, 's_length': length, 'count': ct}) 
graph.run(''' 
    UNWIND {params} AS param 
    WITH param['dct'] AS dct, param['count'] AS ct, param['s_length'] AS s_length 
    MERGE (s:Sentence { id: ct, length: s_length }) 
    WITH s, dct 
    UNWIND keys(dct) AS word 
    MERGE (w:Word { id: word }) 
    MERGE (s) - [:CONTAINS {wrdcnt: dct[word] }] -> (w)''', 
    parameters={'params': params}) 
+0

L'erreur suivante est levée dans IPython - CypherSyntaxError: WITH est requis entre MERGE et UNWIND – user6948456

+0

ouais, que l'on me attrape à chaque fois. C'est fixé ci-dessus. –

+0

Merci, cela a accéléré le programme .. il prend maintenant sous-2 minutes pour 1000 lignes (6334 nœuds, 21777 relations). Mais je me demande si cela peut être amélioré. Auparavant, j'ai essayé d'importer des formats csv avec un demi-million de nœuds en moins de 5 minutes. Cependant, la tâche en cours est orientée texte – user6948456