Seguimos dando ejemplos de lo fácil que es hoy en día añadir pequeñas dosis de Inteligencia Artificial a cualquier aplicación (recordad este ejemplo de detección de comentarios tóxicos en WordPress con TensorFlow). En esta ocasión nos centramos en el análisis de sentimientos en un texto.

¿Y por qué querrías analizar qué sentimiento (positivo, negativo, alegría, cabreo,…) se esconde detrás del texto que escribe el usuario de tu aplicación? La respuesta es muy simple, cuanto mejor comprendas como se siente mejor podrás adaptarte a él y responderle de la forma más adecuada posible. Hay muchos tipos de aplicaciones que podrían beneficiarse de esto pero nos centraremos en el caso más obvio / extremo: los chatbots. Aquí es clave ir monitorizando como se siente el usuario. Primero para intentar evitar que abandone el bot enfadado por las respuestas que recibe pero, más en general, para demostrar un nivel de empatía que lo haga sentir cómodo en todo momento. Igual que cuando conversamos con otras personas donde intentamos siempre adaptar nuestro tono y respuesta a la percepción que recibimos del estado emocional del interlocutor.

Para conseguir este nivel de empatía el primer caso es implementar una funcionalidad de análisis de sentimiento que, dado un texto de entrada, nos lo clasifique en uno o más de los sentimientos que queremos tener en cuenta. En el caso más simple, querremos simplemente ver si el tono es positivo, neutral o negativo. Evidentemente, sería fantástico llegar a detectar si está contento, enfadado, triste, bromeando,… pero como en cualquier problema de clasificación, cuantas más categorías queremos tener en cuenta más difícil (y menos fiable) es el aprendizaje y la calidad de la red neuronal resultante.

Esto es exactamente lo que hemos añadido a nuestra plataforma de software libre para la creación de chatbots: Xatkit. A continuación os explico como lo hemos hecho para que podáis hacer vosotros lo mismo en vuestros propios proyectos si queréis (y si no, para que veáis como cada vez hay más librerías y modelos preentrenados que permite añadir fácilmente “inteligencia” a cualquier software).

Lo hemos implementado como parte de nuestro nuevo concepto de Processor. Los Processors son funciones que puedes añadir a la lógica de reconocimiento de intenciones (si esto de los intents te suena a chino, mírate este tutorial sobre chatbots) ya sea optimizando el texto antes de enviarlo al motor de lenguaje natural o bien anotando el resultado con información adicional que permita una respuesta más adecuada. Este último es el caso del análisis de sentimiento.

Pero teníamos claro que no queríamos implementar este clasificador de sentimientos empezando de cero. Y como el core de Xatkit está programado en Java, buscamos alguna librería open source que pudiéramos reutilizar. Por suerte, para Java tenemos disponible la súper librería Stanford CoreNLP que viene con el componente SentimentAnnnotator.

Stanford NLP anota un texto de entrada en base a un clasificador que distingue entre 5 sentimientos: muy negativo, negativo, neutral, positive y muy positivo. El clasificador está implementado como una Red neuronal recursiva pre-entrenada. Si os parece complicado, tranquilos. El cómo Stanford NLP esté implementado internamente no nos afecta. Nosotros sólo tenemos que llamarlo como cualquier otra función. Todo el código que os enseña como lo hemos integrado está en esta clase Java. Veamos el código más relevante para que te sea fácil reutilizarlo.

El extracto de código siguiente os muestra como creamos una instancia de tipo Annotation a partir de un texto inicial (en este ejemplo, proporcionado por getMatchedInput ; esta función y el objeto session son elementos internos a Xatkit que simplemente guardan información sobre el texto escrito por el usuario y parámetros adicionales de la sesión). A partir de la instancia annotation, recuperamos las sentencias ya anotadas (Stanford asume que lo que queremos anotar es un texto completo no simplemente una frase individual, aunque en nuestras pruebas, para las frases individuales funciona razonablemente bien). Finalmente, con get(SentimentCoreAnnotations.SentimentClass.class), filtramos todos los tipos de anotaciones que no nos interesan y nos quedamos sólo con las que hacen referencia al análisis de sentimientos. Este valor lo guardamos en la session para usarlo después al crear la respuesta.

Del código anterior, el método getAnnotation es el más importante ya que es aquí donde realmente pedimos a Stanford NLP que analize el texto. En nuestro código, hemos envuelto este código en nuestra propia clase StanfordNLPPostProcessor por un tema de optimización: la anotación de un texto toma su tiempo y queríamos controlar que sólo se hiciera una vez, independientemente del número de Processors que se estuvieran usando. Sólo se llama el método si no hay ya ningún otro objeto Annotation ya para ese mismo texto.

A nivel de usuario de Xatkit, el resultado del análisis es accesible vía la variable context disponible como parte del lenguaje de ejecución que usamos al crear un nuevo bot. Tenemos un contexto especial llamado nlp que guarda el resultado de todos los análisis hechos con la librería StanfordNLP (aparte del análisis de sentimiento podemos también detectar si el usuario está haciendo una pregunta, etc). El ejemplo que os mostramos a continuación es de hecho parte del código real de nuestro propio bot.

Podéis probarlo vosotros mismos en la página de Xatkit. Esta animación os enseña también la parte de test de sentimientos en nuestra demo online:

Sentiment Analysis test in our own chatbot

Espero que este post os anime a probar algunas de estas tecnologías. ¡Ya me contaréis como os va!.

Imagen destacada por Tyler Nix