2017-08-17 7 views
1

J'essaie de trouver comment extraire les co-occurrents d'un mot spécifique d'un texte. Comme dans: quels sont les mots qui font une collocation statistiquement significative avec, par exemple, le mot "hobbit" dans l'ensemble du corpus de texte? J'attends un résultat similaire à une liste de mots (colocates) ou peut-être des tuples (ma parole + sa colocate).Extraction de collocates pour un mot donné à partir d'un corpus de texte - Python

Je sais comment créer des bi- et tri-grammes en utilisant nltk, et aussi comment sélectionner uniquement les bi- ou trigrammes qui contiennent mon mot d'intérêt. J'utilise le code suivant (adapté de this StackOverflow question).

import nltk 
from nltk.collocations import * 
corpus = nltk.Text(text) # "text" is a list of tokens 
trigram_measures = nltk.collocations.TrigramAssocMeasures() 
tri_finder = TrigramCollocationFinder.from_words(corpus) 
# Only trigrams that appear 3+ times 
tri_finder.apply_freq_filter(3) 
# Only the ones containing my word 
my_filter = lambda *w: 'Hobbit' not in w 
tri_finder.apply_ngram_filter(my_filter) 

print tri_finder.nbest(trigram_measures.likelihood_ratio, 20) 

Cela fonctionne bien et me donne une liste des trigrammes (un élément qui est ma parole), chacune avec leur valeur log-vraisemblance. Mais je ne veux pas vraiment sélectionner des mots seulement à partir d'une liste de trigrammes. Je voudrais faire toutes les combinaisons de N-Gram possibles dans une fenêtre de mon choix (par exemple, tous les mots dans une fenêtre de 3 à gauche et 3 à droite de mon mot - ce qui signifierait un 7 grammes), puis vérifier ces mots N-grammes ont une fréquence statistiquement pertinente associée à ma parole d'intérêt. Je voudrais prendre la valeur Log-Likelihood pour cela.

Mon idée serait:

1) Calculer toutes les N-Gram combinaisons de différentes tailles contenant ma parole (pas nécessairement en utilisant NLTK, à moins qu'il permet de calculer des unités plus grandes que trigrammes, mais je ne l'ai pas trouvé que option),

2) Calculer la valeur de log-vraisemblance pour chacun des mots composant mes N-grammes, et en quelque sorte la comparer à la fréquence du n-gramme dans laquelle ils apparaissent (?). Voici où je me perds un peu ... Je ne suis pas expérimenté dans ce domaine et je ne sais pas comment penser cette étape.

Est-ce que quelqu'un a des suggestions comment je devrais faire? Et en supposant que j'utilise le pool de trigrammes fourni par nltk pour l'instant: est-ce que quelqu'un a des idées pour procéder à partir de là pour obtenir une liste des mots les plus pertinents près de mon mot de recherche?

Merci

Répondre

0

problème Intéressant ...

portent sur 1) jeter un oeil à ce thread ... différentes solutions pour faire de belles ngrams .. au fond, je lo

from nltk import ngrams 
sentence = 'this is a foo bar sentences and i want to ngramize it' 
n = 6 
sixgrams = ngrams(sentence.split(), n) 
for grams in sixgrams: 
    print (grams) 

L'autre moyen pourrait être:

phrases = Phrases(doc,min_count=2) 
    bigram = models.phrases.Phraser(phrases) 
    phrases = Phrases(bigram[doc],min_count=2) 
    trigram = models.phrases.Phraser(phrases) 
    phrases = Phrases(trigram[doc],min_count=2) 
    Quadgram = models.phrases.Phraser(phrases) 
    ... (you could continue infinitely) 

min_count contrôle le la fréquence de chaque mot dans les corpus.

En relation avec 2) Il est en quelque sorte difficile de calculer loglikelihood pour plus de deux variables puisque vous devriez compter pour toutes les permutations. regardez ce thesis quel gars a proposé une solution (page 26 contient une bonne explication).

Cependant, en plus de la fonction de log-vraisemblance, il existe une métrique PMI (Pointwise Mutual Information) qui calcule la cooccurrence d'une paire de mots divisée par leur fréquence individuelle dans le texte. PMI est facile à comprendre et calcule lequel vous pouvez l'utiliser pour chaque paire de mots.