Hace unas semanas me quedé pegado a la pantalla del ordenador viendo vídeos de YouTube. Estaba viendo un concurso de televisión estadounidense llamado Jeopardy!. ¿Los concursantes? Ken Jennings, el mayor campeón histórico del formato; Brad Rutter, otro coloso imbatido; y Watson, una caja negra con un logo brillante de IBM.
Watson barrió el suelo con ellos.
En 1997 los más mayores vieron a Deep Blue ganar a Kaspárov al ajedrez, pero aquello, aunque impresionante, era pura fuerza bruta matemática evaluando árboles de decisión en un entorno de reglas cerradas. Lo de Watson es otra liga completamente distinta. Watson ha entendido chistes, juegos de palabras, ironías y pistas ambiguas en lenguaje natural humano.
¿Por qué el NLP es un infierno para un programador?
A los que nos pasamos el día picando código estructurado, el Procesamiento de Lenguaje Natural (NLP) nos parece brujería. Los lenguajes de programación no tienen ambigüedades: un if es un if. Pero el lenguaje humano es caótico. La frase "La llama llama a la llama" tiene sentido en español, pero programar a una máquina para que distinga el animal, el verbo y el fuego basándose en el contexto es un auténtico dolor de cabeza.
Watson no "busca en Google". De hecho, jugó sin conexión a internet. Utilizó el framework Apache UIMA (Unstructured Information Management Architecture) y una red de clústeres corriendo Hadoop para procesar en paralelo unos 200 millones de páginas de información (incluyendo toda la Wikipedia).
Para entender lo difícil que es esto a nivel básico, el otro día estuve trasteando con NLTK (Natural Language Toolkit) en Python. Solo para identificar las partes de una oración (part-of-speech tagging), la máquina tiene que hacer malabares estadísticos:
import nltk
# Un ejemplo clásico de ambigüedad en inglés
frase = "Time flies like an arrow; fruit flies like a banana."
# Tokenización: separamos las palabras
tokens = nltk.word_tokenize(frase)
# Etiquetado gramatical (Part-of-Speech tagging)
etiquetas = nltk.pos_tag(tokens)
for palabra, etiqueta in etiquetas:
# Imprime la palabra y si es Nombre (NN), Verbo (VB), etc.
print f"{palabra} -> {etiqueta}"
El script de arriba sufre para entender que en la primera mitad "flies" es un verbo (vuela) y en la segunda es un sustantivo (moscas). IBM Watson ejecuta miles de algoritmos de este tipo simultáneamente, generando múltiples hipótesis, comprobando fuentes y asignando un "porcentaje de confianza" a cada posible respuesta en menos de tres segundos. Si la confianza supera un umbral, Watson aprieta el pulsador.
Reflexión: La barrera del hardware y el futuro
La hazaña de Watson es posiblemente el mayor hito de la inteligencia artificial en la última década. Nos demuestra que las máquinas pueden llegar a "entender" nuestra sintaxis desordenada.
Sin embargo, hay un gran elefante en la habitación. Para lograr esto, IBM tuvo que construir un superordenador del tamaño de una habitación, compuesto por 90 servidores IBM Power 750, sumando 2880 núcleos de procesamiento y 16 Terabytes de RAM.
Es una bestialidad inaccesible. Hoy por hoy, el NLP avanzado está reservado a las mega-corporaciones o a las universidades. Mi gran duda es si, gracias a la Ley de Moore y al avance del cloud computing como Amazon EC2, algún día nosotros, los desarrolladores "de a pie", tendremos acceso a estas maravillas. Por ahora, nos toca seguir peleándonos con simples expresiones regulares.