Herramientas de usuario

Herramientas del sitio


ai:nlp_with_nltk

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:

  • fileids(), devuelve el nombre de los ficheros.
  • fileids([cat]), devuelve los nombres de ficheros correspondientes a esas categorías.
  • categories(), categorías del curpos
  • raw(e), devuelve el contenido de un elemento en el corpus.
  • words(e), devuelve las distintas palabras de un elemento en el corpus.
  • sents(e), devuelve las distintas frases en un elemento de un corpus.
  • abspath(e), la ruta de ese elemento en disco.
  • encoding(e), la codificación de ese elemento.
  • readme(), los contenidos del readme de ese corpus.
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

  • nltk.word_tokenize(s), separa el texto en distintos tokens a partir de espacios en blanco, saltos de línea…
  • Podemos tokenizar a partir del método re.split(regex, text). Con expresiones regulares como r'\s+' (para espacios en blanco, tabulaciones, saltos de línea…), r'\W+' (para tokens que no contengan puntuación)…
  • nltk.regexp_tokenize(regex, s) nos permite tokenizar un texto a partir de una expresión regular.

Limpieza

  • nltk.clean_html(s), substrae el texto de un string en formato HTML.

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:

  • gutenberg: libros electrónicos del proyecto Gutenberg.
  • webtext: textos relacionados con internet (extractos del foro de Firefox, opiniones de vinos, el guión de Piratas del Caribe…)
  • nps_chat: conversaciones de chat.
  • brown, textos creados en la universidad de Brown. Se les ha agregado el método categorias.
  • reuters, noticas del periódico Reuters (también clasificados en categorias).
  • inaugural, direcciones.
  • cess_esp, corpus en castellano.
  • udhr, declaración de los derechos humanos clasificados en 300 lenguas.

Lexicos

También los encontramos en nltk.corpus:

  • stopwords, stopwords clasificados por idiomas. Por ejemplo para acceder a las de inglés haremos: nltk.corups.stopwords.words('english').
  • cmudict, diccionario de pronunciación inglés.
  • swadesh, lista de las palabras más utilizadas en los distintos lenguajes. nltk.corpus.swadesh.fileids() devolvería los idiomas disponibles y nltk.corpus.swadesh.words('es') las palabras del castellano.
  • wordnet provee de un árbol de palabras relacionadas entre ellas a partir de su significado (synsets), lemas (lemmas) y demás relaciones léxicas (hypernym, antonym, entail…) y, a la vez, de métodos para movernos por este árbol.

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”.
ai/nlp_with_nltk.txt · Última modificación: 2020/05/09 09:25 (editor externo)