2010-03-16 7 views
53

Tengo una serie de elementos de texto: HTML sin procesar de una base de datos MySQL. Quiero encontrar las frases más comunes en estas entradas (no la frase más común, y lo ideal es que no se haga coincidir palabra por palabra).Cómo extraer frases comunes/significativas de una serie de entradas de texto

Mi ejemplo es cualquier comentario para Yelp.com, que muestra 3 fragmentos de cientos de comentarios de un restaurante dado, en el formato:

"Prueba la hamburguesa" (en 44 comentarios)

por ejemplo, , la sección de "comentar los resultados" de esta página:

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

tengo NLTK instalado y he jugado un rato con él un poco, pero estoy sinceramente abrumado por las opciones. Esto parece ser un problema bastante común y no he podido encontrar una solución directa buscando aquí.

+1

con nltk, es bastante fácil obtener bigramas y trigramas, pero lo que estoy buscando son frases que tienen más probabilidades de 7 a 8 palabras de longitud.No he descubierto cómo hacer que nltk (u otro método) proporcione tales 'octogramas' y más. – arronsky

Respuesta

0

Bueno, para empezar, probablemente debas eliminar todas las etiquetas HTML (busca "< [^>] *>" y reemplázalo con ""). Después de eso, podría intentar el enfoque ingenuo de buscar las subcadenas comunes más largas entre cada dos elementos de texto, pero no creo que obtenga muy buenos resultados. Puede hacerlo mejor normalizando las palabras (reduciéndolas a su forma base, eliminando todos los acentos, estableciendo todo en mayúsculas o minúsculas) primero y luego analice. Nuevamente, dependiendo de lo que desee lograr, puede agrupar mejor los elementos de texto si permite cierta flexibilidad en el orden de las palabras, es decir, trate los elementos de texto como bolsas de palabras normalizadas y mida la similitud del contenido de la bolsa.

He comentado sobre un tema similar (aunque no idéntico) here.

75

sospecho que no sólo quiere las frases más comunes, sino que desea que el más interesantes colocaciones. De lo contrario, podría terminar con una sobrerrepresentación de frases hechas de palabras comunes y menos frases interesantes e informativas.

Para hacer esto, esencialmente deseará extraer n-grams de sus datos y luego buscar los que tengan el valor más alto point wise mutual information (PMI). Es decir, quieres encontrar las palabras que coinciden juntas mucho más de lo que esperarías por casualidad.

El NLTK collocations how-to explica cómo hacer esto en una cerca de 7 líneas de código, por ejemplo .:

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í, estoy de acuerdo-- y mirando esa página, puedo llegar hasta bi y tri gramos, pero ¿cómo se extiende esto a n-grams? Creo que necesitaré frases de longitud> 5 para ser realmente interesantes, y tal vez estoy expresando mi ignorancia, pero esta página de demostración solo me permite obtener conjuntos de 2 y 3 palabras. – arronsky

+3

Para eso, creo que deberá ampliar nltk.collocations.AbstractCollocationFinder, utilizando BigramCollocationFinder y TrigramCollocationFinder como guía, consulte http://nltk.googlecode.com/svn/trunk/doc/api/nltk.collocations-pysrc .html. Pero, ¿estás seguro de que realmente necesitas frases tan largas? En Yelp, parece que están resaltando palabras sueltas y colocaciones con un par de palabras, en su ejemplo vinculado tienen sashimi, Little Tokyo y fish. Luego seleccionan una oración completa que contiene cada palabra o frase interesante. – dmcer

+3

Esto. Creo que tienes toda la razón. ¡Observación brillante (y elegante)! – arronsky

3

si lo que desea es llegar a más de 3 N-gramas que puede probar esto. Estoy asumiendo que ha despojado toda la basura como html, etc.

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 
Probablemente no

muy Pythonic tan sólo he estado haciendo esto un mes o así mismo, pero puede ser de ayuda!

+1

-1 esto no hizo nada por mí. Estoy en la misma situación que el OP, y su método acaba de devolver una enorme lista de tuplas que siguen la estructura del texto original. ¿Cómo debo proceder? – magnetar

+0

Una vez que tenga esa lista, debe recorrerla para contar la presencia de ngrams únicos. Una forma de hacerlo es creando un dict donde la clave sea el ngrama y aumentándola cada vez que obtenga una coincidencia – Toby

+0

. No entiendo esto tampoco. ¿Cómo se cuentan los gramos únicos? es una bolsa de palabras individuales. –

3

Creo que lo que estás buscando es fragmentando. Le recomendé leer chapter 7 of the NLTK book o tal vez mi propio artículo en chunk extraction. Ambos asumen el conocimiento del etiquetado de parte de la voz, que se trata en chapter 5.

+0

realmente no veo qué tiene que ver la fragmentación. – magnetar

+1

Chunking puede analizar frases, y una vez que tenga frases, puede identificar frases comunes y significativas. – Jacob

Cuestiones relacionadas