Tabla de Contenidos

Natural Language Processing utilizando NLTK

NLTK es un paquete para el procesamiento de lenguaje natural disponible en Python.

Funciones básicas del NLTK

Para iniciar nltk tendremos que hacer:

import nltk

Tratamiento de textos

Los textos pertenecen a la clase nltk.text.Text.

from nltk.book import *
text1						# muestra el texto 1.
text1.concordance('monstrous') 			# busca la palabra 'monstrous'.
text1.similar('monstrous')  			# muestra palabras que se encuentran en contextos similares donde se está 'monstrous'.
text2.common_contexts(['very', 'monstrous']) 	# busca el contexto común para varias palabras.
text1.generate()  				# genera un texto aleatorio a partir de un texto inicial.
len(text3)  					# muestra el número de palabras del texto 3.
len(set(text3)) 				# muestra el número de palabras en el vocabulario del texto 3.
text1.count('monstrous')  			# cuenta el número de veces que aparece la palabra 'monstrous' en el texto 1.
text1.collocations() 				# devuelve una lista de collocations

Tratar corpus

Los corpus son colecciones de textos, en NLTK se nos provee de los siguientes métodos para tratar con ellos:

c = nltk.corpus.gutenberg
c.fileids()

Con NLTK podemos tener instalados corpus de ejemplo.
Podemos convertir un elemento de un corpus a texto de la siguiente forma:

emma = nltk.Text(nltk.corpus.gutenberg.words('austen-emma.txt'))

Cargando tus propios corpus

NLTK permite cargar tus propios corpus mediante PlainTextCorpusReader, este admite la ruta de la colección de textos y una expresión regular de los ficheros aceptados:

from nltk.corpus import PlaintextCorpusReader
croot = '/home/alfred/tmp/testdocs'
corps = PlaintextCorpusReader(croot, '.*')
corps.fileids()
corps.words('fortnow10.txt')

Existen otras alternativas para cargar corpus como son el BracketParseCorpusReader… (http://nltk.sourceforge.net/corpus.html)

Estadísticas con textos

FreqDist

Con el objeto FreqDist podemos ver cómo se distribuye la frecuencia de una palabra en el texto (cantidad de las distintas palabras en el vocabulario del texto).

fdist = FreqDist(text1)
fdist.keys()  			# lista del vocabulario en el texto ordenado por frecuencia
fdist.keys()[:10]  		# el top 10 de las palabras de un texto
fdist['man']  			# devuelve cuantas veces aparece 'man' en el texto
fdist.hapaxes()  		# palabras que solo aparecen una vez
fdist.freq('monstrous')  	# frecuencia de una palabra
fdist.N()  			# número de palabras diferentes
fdist.max()  			# la palabra que aparece un número mayor de veces
fdist.items()  			# palabra y número de veces que aparece esta
fdist.plot()  			# gráfico de la distribución
fdist.plot(cumulative=True)	# gráfico acumulado de la distribución
fdist.tabulate()  		# tabla de frecuencias

ConditionalFreqDist

Cuando un texto se divide en varias categorías (género, autor…) podríamos mantener distribuciones para cada categoría con un objeto ConditionalFreqDist, el cual es una colección de distintas distribuciones de frecuencia clasificadas por su condición\categoría\tema.
Necesita de un conjunto de pares para hacer la distribución:

from nltk.corpus import brown
genre_word = [(genre, word)				# Creación de los pares
    for genre in ['news', 'romance']
    for word in brown.words(categories=genre)]
cfd = nltk.ConditionalFreqDist(genre_word)		# Creación de la distribución de frecuencia condicional
cfd.conditions()					# news y romance, las "condiciones"
cfd['news']						# palabras de news
cfd['news']['could']					# Objeto FreqDist de la palabra 'could' en 'news'

Preproceso del texto

Tokenizar

Limpieza

Segmentar

Lematizar

NLTK permite lematizar a partir del lematizador de WordNet, este elimina los afijos si la palabra resultante está en el diccionario.

wnl = nltk.WordNetLemmatizer()
[wnl.lemmatize(t) for t in tokens]

Stemizar

NLTK provee de dos stemmers, el de Porter (nltk.PorterStemmer) y el de Lancaster (nltk.LancasterStemmer), un ejemplo de uso sería:

porter = nltk.PorterStemmer()
[porter.stem(t) for t in tokens]

Esquema básico

from urllib import urlopen
url = 'http://www.uruloki.org/felipeblog/sitges-2011/el-festival-de-sitges-2011-tira-la-casa-por-la-ventana-y-nos-deja-a-todos-anonadados'
 
html = urlopen(url).read()
raw = nltk.clean_html(html)				# 1. Conseguimos el texto
tokens = nltk.wordpunct_tokenize(raw)			# 2. Lo tokenizamos
text = nltk.Text(tokens)				# 3. Lo convertimos a objeto Text
words = [w.lower() for w in text]			# 4. Lo normalizamos
vocab = sorted(set(words))				# 5. Lo tratamos (p.ej. extracción de vocabulario)

Categorizar y taggear palabras

Clasificar textos

Extraer información del texto

Analizar estructuras gramaticales

Construir gramáticas

Analizar el significado de expresiones

Notas

Libro & ejemplos

Para descargarte los módulos de ejemplo y correspondientes al libro simplemente tendremos que poner:

import nltk
nltk.download()

Podremos instalar los sub-módulos que queramos. Si instalamos el del libro tendremos acceso a distintos textos haciendo…

from nltk.book import *

Podemos abrir el shell de test de traducción:

>>> babelize_shell()
NLTK Babelizer: type 'help' for a list of commands.
Babel> how long before the next flight to Alice Springs?
Babel> spanish
Babel> run
0> how long before the next flight to Alice Springs?
1> ¿cuanto tiempo antes del vuelo siguiente a Alice Springs?
2> how long before the flight following to It stakes out Springs?
3> ¿cuanto tiempo antes del vuelo siguiente a él estaca hacia fuera suelta?
4> how long before the flight following to him it stakes towards outside loosen?
5> ¿cuanto tiempo antes de que el vuelo siguiente a él que estaca hacia exterior afloje?
6> how long before the flight following to him that it stakes towards outside relaxes?
7> ¿cuanto tiempo antes del vuelo siguiente a él que estaca hacia exterior se relaja?
8> how long before the flight following to him that it stakes towards outside it relaxes?
9> ¿cuanto tiempo antes del vuelo siguiente a él que estaca hacia afuera se relaja?

Corpus

Los encontraremos en nltk.corpus si los tenemos correctamente descargados, estos son:

Lexicos

También los encontramos en nltk.corpus:

Notas

Funciones útiles para tratar con los recursos:

path = nltk.data.find('corpora/unicode_samples/polish-lat2.txt')				# Devuelve la ruta de polish-lat2.txt

Regex útiles

regex Explicación
[aeiou]{2,} Palabras con dos vocales seguidas
^(.*)(ing|ly|ed|ious|ies|ive|es|s|ment)$ Estemiza palabras en inglés, devolviendo el estema y el sufijo
<.*><.*><bro> Tres palabras seguidas donde la última sea “bro”
<a>(<.*>)<man> Los adjetivos que se le agregan a “a man”.