2010-03-16 8 views
53

Ho una serie di elementi di testo: HTML non elaborato da un database MySQL. Voglio trovare le frasi più comuni in queste voci (non la singola frase più comune, e idealmente, non imporre la corrispondenza parola per parola).Come estrarre le frasi comuni/significative da una serie di voci di testo

Il mio esempio è un qualsiasi commento su Yelp.com, che mostra 3 frammenti di centinaia di recensioni di un determinato ristorante, nel formato:

"Provate l'hamburger" (in 44 recensioni)

esempio , la sezione "iN SINTESI" di questa pagina:

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

ho NLTK installato e ho giocato intorno con esso un po ', ma sto onestamente sopraffatto dalle opzioni. Questo sembra un problema piuttosto comune e non sono stato in grado di trovare una soluzione semplice cercando qui.

+1

con nltk, è abbastanza facile ottenere bigram e trigram, ma quello che sto cercando sono frasi che sono più probabili 7 - 8 parole di lunghezza.Non ho capito come rendere nltk (o qualche altro metodo) fornire tali "octogrammi" e oltre. – arronsky

risposta

0

Bene, per cominciare bisognerebbe probabilmente rimuovere tutti i tag HTML (cercare "< [^>] *>" e sostituirlo con ""). Dopo di ciò, potresti provare l'approccio ingenuo di cercare le sottostringhe più lunghe tra ogni due elementi di testo, ma non penso che otterrai risultati molto buoni. Si potrebbe fare meglio normalizzando le parole (riducendole al loro modulo base, rimuovendo tutti gli accenti, impostando tutto in maiuscolo o in maiuscolo) prima e quindi analizzare. Di nuovo, a seconda di ciò che si vuole realizzare, si potrebbe essere in grado di raggruppare meglio gli elementi di testo se si consente una certa flessibilità nell'ordine delle parole, ovvero trattare gli elementi di testo come sacchetti di parole normalizzate e misurare la somiglianza del contenuto del sacchetto.

Ho commentato un argomento simile (sebbene non identico) here.

75

Sospetto che non vogliate solo le frasi più comuni, ma piuttosto le più interessanti collocazioni. Altrimenti, si potrebbe finire con una sovrarappresentazione di frasi composte da parole comuni e meno frasi interessanti e informative.

Per fare ciò, in sostanza, è necessario estrarre n-gram dai dati e quindi individuare quelli con il valore massimo point wise mutual information (PMI). Cioè, vuoi trovare le parole che concorrono insieme molto più di quanto ci si aspetterebbe loro per caso.

Il NLTK collocations how-to copre come fare questo in circa 7 righe di codice, ad es .:

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) 
+1

Sì, sono d'accordo ... e guardando quella pagina, posso arrivare fino a bi e tri-grammi, ma come è esteso a n-grammi? Credo che avrò bisogno di frasi di lunghezza> 5 per essere veramente interessanti, e forse sto esprimendo la mia ignoranza, ma questa pagina demo mi consente di ottenere solo 2 e 3 set di parole? – arronsky

+3

Per quello, penso che dovrai estendere nltk.collocations.AbstractCollocationFinder, usando BigramCollocationFinder e TrigramCollocationFinder come guida, vedi http://nltk.googlecode.com/svn/trunk/doc/api/nltk.collocations-pysrc .html. Ma sei sicuro di aver davvero bisogno di frasi così lunghe? Su Yelp, sembra che stiano evidenziando singole parole e collocazioni con un paio di parole in esse, nel tuo esempio collegato hanno sashimi, Little Tokyo e pesce. Quindi selezionano una frase completa che contiene ogni parola o frase interessante. – dmcer

+3

Questo. Penso che tu abbia assolutamente ragione. Osservazione brillante (ed elegante)! – arronsky

3

se si desidera solo per arrivare al più grande di 3 ngrams si può provare questo. Sto assumendo che hai spogliato tutte le spazzatura come html ecc

import nltk 
ngramlist=[] 
raw=<yourtextfile here> 

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

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

molto divinatorio come ho solo fatto questo un mese o giù di lì me stesso, ma potrebbe essere di aiuto!

+1

-1 questo non ha fatto nulla per me. Sono nella stessa situazione dell'OP, e il tuo metodo ha appena restituito un enorme elenco di tuple che seguivano la struttura del testo originale. come devo procedere? – magnetar

+0

Una volta ottenuto tale elenco, è necessario eseguirne il ciclo per contare la presenza di ngram univoci. Un modo per farlo è creare un ditt dove la chiave è l'ngram e incrementarla ogni volta che si ottiene una corrispondenza – Toby

+0

Non capisco neanche questo. Come contate i grammi unici? è un sacco di parole individuali. –

3

Penso che quello che stai cercando è chunking. Ho consigliato di leggere chapter 7 of the NLTK book o forse il mio articolo su chunk extraction. Entrambi presuppongono la conoscenza della codifica di parte del discorso, che è trattata in chapter 5.

+0

davvero non capisco cosa c'entri il chunking. – magnetar

+1

Chunking può analizzare le frasi e, una volta ricevute le frasi, è possibile identificare frasi comuni e significative. – Jacob

Problemi correlati