73 votes

Comment extraire des phrases communes / significatives d'une série d'entrées de texte

J'ai une série d'éléments textuels - HTML brut provenant d'une base de données MySQL. Je veux trouver les phrases les plus courantes dans ces entrées (pas la phrase la plus courante, et idéalement, sans imposer une correspondance mot à mot).

Mon exemple est n'importe quelle critique sur Yelp.com, qui montre 3 extraits parmi des centaines de critiques d'un restaurant donné, dans le format:

"Essayez le hamburger" (dans 44 critiques)

par exemple, la section "Points forts de l'avis" de cette page:

http://www.yelp.com/biz/sushi-gen-los-angeles/

J'ai NLTK installé et j'ai un peu joué avec, mais je suis franchement dépassé par les options. Cela semble être un problème assez courant et je n'ai pas pu trouver de solution directe en cherchant ici.

1 votes

Avec nltk, il est assez facile d'obtenir des bigrammes et des trigrammes, mais ce que je recherche sont des phrases probablement de 7 à 8 mots de longueur. Je n'ai pas encore trouvé comment faire en sorte que nltk (ou une autre méthode) fournisse de tels 'octogrammes' et plus.

0 votes

Peut-être pouvez-vous essayer des algorithmes basés sur des graphes comme TextRank - github.com/ceteri/pytextrank

105voto

dmcer Points 5561

Je soupçonne que vous ne voulez pas seulement les phrases les plus courantes, mais plutôt les collocations les plus intéressantes. Sinon, vous pourriez vous retrouver avec une sur-représentation de phrases composées de mots courants et moins de phrases intéressantes et informatives.

Pour ce faire, vous voudrez essentiellement extraire des n-grammes de vos données, puis trouver ceux qui ont le plus d'information mutuelle ponctuelle (PMI). Autrement dit, vous voulez trouver les mots qui co-occurrent ensemble beaucoup plus que ce à quoi vous vous attendriez par hasard.

Le guide des collocations NLTK explique comment faire cela en environ 7 lignes de code, par exemple :

import nltk
from nltk.collocations import *
bigram_measures = nltk.collocations.BigramAssocMeasures()
trigram_measures = nltk.collocations.TrigramAssocMeasures()

# change this to read in your data
finder = BigramCollocationFinder.from_words(
    nltk.corpus.genesis.words('english-web.txt'))

# only bigrams that appear 3+ times
finder.apply_freq_filter(3)

# return the 10 n-grams with the highest PMI
finder.nbest(bigram_measures.pmi, 10)

3 votes

Oui, je suis d'accord - et en regardant cette page, je peux aller jusqu'aux bi et tri-grammes, mais comment cela est-il étendu aux n-grammes? Je crois que j'aurai besoin de phrases de longueur > 5 pour être vraiment intéressantes, et peut-être que j'exprime mon ignorance, mais cette page de démo ne me permet d'obtenir que des ensembles de mots de 2 et 3 mots?

5 votes

Pour cela, je pense que vous devrez étendre nltk.collocations.AbstractCollocationFinder, en utilisant BigramCollocationFinder et TrigramCollocationFinder comme guide, voir nltk.googlecode.com/svn/trunk/doc/api/…. Mais, êtes-vous sûr que vous avez vraiment besoin de phrases si longues? Sur Yelp, il semble qu'ils mettent en évidence des mots individuels et des collocations avec quelques mots, dans votre exemple lié ils ont sashimi, Little Tokyo et fish. Ils sélectionnent ensuite une phrase complète qui contient chaque mot ou phrase intéressant.

7 votes

Cela. Je pense que tu as tout à fait raison. Observation brillante (et élégante)!

5voto

Toby Points 110

Si vous voulez simplement passer à des n-grammes supérieurs à 3, vous pouvez essayer ceci. Je suppose que vous avez enlevé toutes les choses inutiles comme HTML, etc.

import nltk
ngramlist=[]
raw=

x=1
ngramlimit=6
tokens=nltk.word_tokenize(raw)

while x <= ngramlimit:
  ngramlist.extend(nltk.ngrams(tokens, x))
  x+=1

Probablement pas très pythonique car je ne fais cela que depuis un mois environ moi-même, mais cela pourrait vous aider !

1 votes

-1 cela n'a rien fait pour moi. Je suis dans la même situation que l'OP, et votre méthode a simplement retourné une énorme liste de tuples qui suivait la structure du texte original. Comment devrais-je procéder?

1 votes

Une fois que vous avez cette liste, vous devez la parcourir pour compter la présence des n-grammes uniques. Une façon de le faire est de créer un dictionnaire où la clé est le n-gramme et de l'incrémenter à chaque fois que vous obtenez une correspondance.

0 votes

Je ne comprends pas non plus. Comment comptez-vous les grammes uniques ? c'est un sac de mots individuels.

5voto

Jacob Points 2458

Je pense que ce que vous recherchez est le chunking. Je recommande de lire le chapitre 7 du livre NLTK ou peut-être mon propre article sur l'extraction de chunks. Les deux supposent une connaissance de l'étiquetage des parties du discours, qui est traité dans le chapitre 5.

0 votes

Je ne comprends vraiment pas en quoi le chunking y est lié.

3 votes

Chunking peut analyser des phrases, et une fois que vous avez des phrases, alors vous pouvez identifier des phrases communes et significatives.

0voto

Eh bien, pour commencer, vous devriez probablement supprimer toutes les balises HTML (recherchez "<[^>]*>" et remplacez-la par ""). Après cela, vous pourriez essayer l'approche naïve de chercher les sous-chaînes communes les plus longues entre chaque paire d'éléments de texte, mais je ne pense pas que vous obtiendriez de très bons résultats. Vous pourriez faire mieux en normalisant les mots (les réduisant à leur forme de base, en supprimant tous les accents, en mettant tout en minuscules ou en majuscules) en premier lieu et ensuite analyser. Encore une fois, en fonction de ce que vous voulez accomplir, vous pourriez regrouper les éléments de texte de manière plus efficace si vous permettez une certaine flexibilité dans l'ordre des mots, c'est-à-dire traiter les éléments de texte comme des ensembles de mots normalisés et mesurer la similarité des ensembles.

J'ai commenté sur un sujet similaire (bien que non identique) ici.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X