Procesamiento de lenguaje natural con NLTK (Natural Language Toolkit)
|
|
|
|
¿Qué es el Procesamiento de Lenguaje Natural? El PLN (o NLP en inglés) es el uso de computadoras para el procesado de lenguaje humano. Tiene pilas de aplicaciones prácticas (blogs, twitter, phones, etc) y en algún sentido puede considerarse un hito (casi) final para la Inteligencia Artificial (El test de Turing, al fin y al cabo, es lenguaje natural, pero esto es muy discutido, un robot immerso en el mundo es mucho más difícil).
Todo muy lindo con el PLN, pero la gente es muy buena hablando, por naturaleza (su lengua materna, por supuesto), así que los usuarios de PLN tienen altas espectativas del rendimiento de los sistemas (que no se conllevan con la realidad). Aparte, las personas que hacen PLN tienen una mezcla de interéses tanto en lenguajes como en matemáticas, una combinación inusual. Hoy en día el PLN involucra pilas de ingeniería y tweaking (y la sensación de que... ¡Tiene que haber una forma mejor!).
Natural Language Toolkit
NLTK es un toolkit, una colección de paquetes y objetos python muy adaptados para tareas de PLN. El NLTK es a la vez una herramienta que introduce a nuevas personas al estado del arte en PLN mientras que permite a los expertos sentirse muy cómodos dentro de su entorno. Comparado a otros frameworks, el NLTK tiene asunciones por defecto muy fuertes (por ej, un texto es una secuencia de palabras), aunque pueden cambiarse. NLTK no sólo se centra en gente que trabaja en PLN viniendo desde la computación sino también en lingüistas haciendo trabajo de campo. NLTK se mezcla bien con Python (no está simplemente “implementado” en Python).
Algunos datos acerca del NLTK:
El NLTK comenzó en la Universidad de Pennsylvania, como parte de un curso de lingüística computacional. Se encuentra disponible en Internet, desde http://www.nltk.org/. Su código fuente se distribuye bajo la Apache Licens version 2.0 y hay un libro de 500 paginas por Bird, Klein y Loper disponible desde O’Reilly “Natural Language Processing with Python”, muy recomendable (http://nltk.googlecode.com/svn/trunk/doc/book/).
El toolkit incluye también datos en la forma de colecciones de textos (muchos anotados) y modelos estadísticos.
NLTK y Python
El toolkit se integra muy bien con Python ya que trata de hacer la mayoria de las cosas con facilidades de Python como porciones y listas por comprensión. Por ejemplo, un texto es una lista de palabras y una lista de palabras puede ser transformada en un texto. Los objetivos de diseño del toolkit (Simpleza, Consistencia, Extensibilidad y Modularidad) van de la mano con el diseño mismo de Python. Además, fiel a dichos objetivos, NLTK evita crear sus propias clases cuando los diccionarios, listas y tuplas por defecto de Python son suficientes.
Paquetes principales de NLTK:
- Acceso a documentos: Interfaces para colecciones de textos.
- Procesamiento de cadenas: Tokenizado, detección de oraciones, stemmers.
- Descubrimiento de collocactions: Tokens que aparecen juntos más frequentemente que por chance.
- Part-of-speech tagging: Distinguir substantivos de verbos, etc.
- Clasificación: Clasificadores general, basados en diccionarios de Python como entrenamiento.
- Chunking: Partir una oración en unidades granulares
- Análisis Sintáctico: Análisis complejo (sintáctico y otros).
- Interpretación Semántica: Cálculo λ (lambda), lógica de 1er órden, etc.
- Métricas de Evaluación: Precisión, covertura, etc.
- Estadística: Distribución de frecuencias, estimadores, etc.
- Aplicaciones: Browser de WordNet, chatbots.
Algunos Ejemplos
Para probarlo, el importar todo lo que está en el paquete nltk.book pone al intérprete de Python listo para empezar. (También hay que descargar primero los datos binarios, importando nltk y haciendo nltk.download()).
Una vez hecho esto, se puede preguntar, por ejemplo, por palabras similares basadas en contextos, dado un texto.
>>> from nltk.book import * # long comment, skipped >>> moby_dick = text1 >>> moby_dick.similar('poor') Building word-context index... old sweet as eager that this all own help peculiar german crazy three at goodness world wonderful floating ring simple >>> inaugural_addresses = text4 >>> inaugural_addresses.similar('poor') Building word-context index... free south duties world people all partial welfare battle settlement integrity children issues idealism tariff concerned young recurrence charge those
Tutorial: Noticias destacadas
Nos interesa hacer algo similar a las Top Stories de http://news.google.com/.
Top stories a la NLTK
- Nuestra estrategia será:
- Buscaremos Named Entities
- Usando NLTK out-of-the-box
- Luego puntuaremos las entidades y mostraremos las mejores.
Como datos usamos 7,705 noticias internacionales prestadas del sitio de Reuters U.S. (http://www.reuters.com/)
¿Qué son las entidades nombradas?
Las entidades nombradas son elementos atómicos del texto que caen en categorias tales como personas, lugares, organizaciones. Para extraer entidades nombradas con nltk usamos el siguiente código:
>>> import nltk >>> s = """ ... Prince William and his new wife Catherine kissed twice ... to satisfy the besotted Buckingham Palace crowds""" >>> a = nltk.word_tokenize(s) >>> b = nltk.pos_tag(a) >>> c = nltk.ne_chunk(b,binary=True) >>> for x in c.subtrees(): ... if x.node == "NE": ... words = [w[0] for w in x.leaves()] ... name = " ".join(words) ... print name ... Prince William Catherine Buckingham Palace >>>
Los algoritmos del estado del arte para el reconocimiento de entidades nombradas automáticamente se adaptan entidades que no han sido vistas con anterioridad. De la imagen de news.google.com que presentamos antes vemos que la lista está comprendida en su mayor parte por entidades nombradas. Entonces encontrar entidades nombradas y ponerlas en un ranking nos permitiría simular el comportamiento de news.google.com.
El código anterior en tres simples pasos:
- Armar una lista de palabras
>>> a = nltk.word_tokenize(s) ['Prince', 'William', 'and', 'his', 'new', 'wife', ...
- Agregar la categoría gramatical
>>> b = nltk.pos_tag(a) [('Prince', 'NN'), ('William', 'NNP'), ('and', 'CC'), ...
- Anotar las entidades nombradas
>>> c = nltk.ne_chunk(b,binary=True) Tree('S',[Tree('NE', [('Prince', 'NN'), ('William', 'NNP')]), ...
El resto del código del ejemplo es solo para mostrar las entidades en pantalla.
¿Cuáles más son relevantes?
El problema pendiente es construir un ranking con las entidades más relevantes.
¿Como distingir que “Japon” es más relevante entre el 10 y 20 de marzo (recordar el tsunami) que entre el 10 y 20 de abril? Para responder esto, el método que proponemos para este ejemplo consiste en considerar cuando más frecuente es Japon en un rango de días con respecto a lo que habitualmente es. Entonces, nuestra función de ranking es:
\[ratio(word) = \frac{prob.\ de\ word\ en\ los\ días\ i..j} {prob.\ de\ word\ en\ todas\ las\ noticias}\]Las palabras con ratio más alto fueron significativas en los dias entre i y j.
¿Cómo evitar superposición?
“Japon” y “Tokio” podrían tener ratio alto pero probablemente solo nos interese nombrar solo una como noticia relevante.
Para resolver esto hacemos:
- Elegimos la entidad E con mayor ratio.
- Tiramos todos las noticas en las que E aparece.
- Recalculamos los ratios y volvemos al primer paso.
Un ouput típico de todos los pasos es:
============================================================
Top news between 2011-03-11 00:00:00 and 2011-03-20 00:00:00
============================================================
zuwarah
uss ronald reagan
richard wakeford
patrick fuller
unit
soviet ukraine
g7
tokyo commodity exchange
roppongi
nuclear security
El código del ejemplo esta disponible en:
http://duboue.net/download/pyday-nltk.tar.gz
Conclusiones
Rafael Carrascosa (A.K.A. Player 1) usó NLTK en su trabajo en la Facultad de Matemática, Astronomía y Física de la UNC, principalmente en un pipeline sobre avisos clasificados para:
- Para hacer POS tagging del castellano.
- Para hacer Chunking del castellano.
- Para hacer chunk sense disambiguation.
Además, tambien armó modelos de lenguaje para compresión de textos usando gramáticas probabilisticas, N-Gramas y parsers estadísticos, todos basados en NLTK.
Entonces... ¿Cuanto se la banca NLTK? Al estar implementado en puro Python, hay veces que se toma su tiempo, aparte los distintos paquetes disponibles varian mucho a nivel de madurez del código. Una pregunta que se puede hacer es uno es:
¿Se puede usar para implementar productos comerciales?
A nivel de licencia, está todo bien. A nivel de errores de los anotadores, hay que probar y a nivel de velocidad, también hay que probar. O sea... ¡Probá!
Otros frameworks que andan dando vuelta incluyen GATE y UIMA que son muy basados en Java.
¿Cómo continuar? NLTK está muy bueno, probálo y fijate el libro (que está en linea).
Help PET: Donate
blog comments powered by Disqus