2017-01-04 3 views
2

pour NLTK ce serait quelque chose comme:Trouvez le pour cent des jetons partagés par deux documents avec spacy

def symm_similarity(textA,textB): 
    textA = set(word_tokenize(textA)) 
    textB = set(word_tokenize(textB))  
    intersection = len(textA.intersection(textB)) 
    difference = len(textA.symmetric_difference(textB)) 
    return intersection/float(intersection+difference) 

Depuis spacy est plus rapide, Im essayant de le faire dans spacy, mais les objets symboliques ne semblent pas pour offrir une solution rapide à cela. Des idées?

Merci à tous.

Répondre

1

Votre fonction obtient le pourcentage de types de mots partagés, pas de jetons. Vous prenez l'ensemble des mots, sans sensibilité à leurs chefs d'accusation.

Si vous voulez compte de jetons, je pense que les programmes suivants très rapide, tant que vous avez le fichier de vocabulaire chargé (ce qui sera par défaut, si vous avez les données installées):

from spacy.attrs import ORTH 

def symm_similarity_types(nlp, textA,textB): 
    docA = nlp.make_doc(textA) 
    docB = nlp.make_doc(textB) 
    countsA = Counter(docA.count_by(ORTH)) 
    countsB = Counter(docB.count_by(ORTH) 
    diff = sum(abs(val) for val in (countsA - countsB).values()) 
    return diff/(len(docA) + len(docB)) 

Si vous souhaitez calculer exactement la même chose que votre code ci-dessus, voici l'équivalent spaCy. L'objet Doc vous permet de parcourir plus de Token objets. Vous devez ensuite baser votre nombre sur l'attribut token.orth, qui est l'ID entier de la chaîne. Je pense travailler avec des nombres entiers sera un peu plus vite que les ensembles de cordes:

def symm_similarity_types(nlp, textA,textB): 
    docA = set(w.orth for w in nlp(textA) 
    docB = set(w.orth for w in nlp(textB) 
    intersection = len(textA.intersection(textB)) 
    difference = len(textA.symmetric_difference(textB)) 
    return intersection/float(intersection+difference) 

Cela devrait être un peu plus efficace que la version NLTK, parce que vous travaillez avec des ensembles d'entiers, et non des chaînes.

Si vous êtes vraiment soucieux de l'efficacité, il est souvent plus pratique de travailler en Cython, plutôt que d'essayer de deviner ce que fait Python. Voici la boucle de base:

# cython: infer_types=True 
for token in doc.c[:doc.length] 
    orth = token.lex.orth 

doc.c est un TokenC*, donc vous itérer sur mémoire contiguë et déréférencement un seul pointeur (token.lex est un const LexemeC*)

+0

merci syllogisme! vous avez raison, je faisais des mots mais pour mon application, les mots ou les jetons fonctionnent bien. Cela sera certainement utile à beaucoup de gens autres que moi-même. apprécier ton aide! –