Es hora de ir más allá de acabar con los chatbot del tipo “Lo siento, no entendí tu pregunta” y construir asistentes de IA que escalan utilizando el aprendizaje automático: Rasa

Los sistemas conversacionales de inteligencia artificial se están convirtiendo en una parte indispensable del ecosistema humano. Entre los ejemplos más conocidos de AI conversacional se incluyen Siri de Apple, Alexa de Amazon y Cortana de Microsoft. Los chatbots conversacionales han recorrido un largo camino desde sus predecesores basados en reglas y casi todas las empresas de tecnología emplean hoy a uno o más ade estos asistentes.

Una conversación con un chatbot comprende el contexto de la conversación y puede manejar cualquier objetivo del usuario con gracia y ayudarle a lograrlo de la mejor manera posible. Esto no siempre significa que el bot podrá responder todas las preguntas, pero puede manejar bien la conversación.

Tabla de contenidos

Objetivo

En este artículo, vamos a construir un chatbot llamado ‘Robo’ capaz de controlar el estado de ánimo de las personas y tomar las medidas necesarias para animarlos. Luego lo desplegaremos en Slack. Será un Slackbot totalmente funcional capaz de escuchar y responder a tus solicitudes. La siguiente captura de pantalla de demostración debe motivarte lo suficiente como para construir la tuya propia.

La fuente de este artículo es una maravillosa charla que Tom Bocklisch, Jefe de Ingeniería @ Rasa dio en Pydata Berlin.

Requerimientos

Principalmente requerimos la instalación de Rasa Stack y un modelo de idioma. El modelo de idioma se utilizará para analizar los mensajes de texto entrantes y extraer la información necesaria. Estaremos trabajando con el modelo de lenguaje SpaCy .

Pila de Rasa

Rasa Stack es un conjunto de herramientas de aprendizaje automático de código abierto para que los desarrolladores creen asistentes contextuales de AI y chatbots. Es el kit de herramientas de aprendizaje automático de código abierto que permite a los desarrolladores expandir los bots más allá de responder preguntas simples con un mínimo de datos de capacitación. Los robots se basan en un modelo de aprendizaje automático formado en conversaciones de ejemplo. Se compone de dos marcos:

fuente

Rasa NLU: una biblioteca para la comprensión del lenguaje natural con clasificación de intención y extracción de entidades. Esto ayuda al chatbot a entender lo que el usuario está diciendo.

Rasa Core: un marco de chatbot con gestión de diálogos basada en el aprendizaje automático que predice la siguiente mejor acción basada en la entrada de NLU, el historial de conversaciones y los datos de entrenamiento.

Rasa tiene una gran documentación que incluye algunos ejemplos interactivos para comprender fácilmente cada uno de los grupos.

Instalaciones

Usaremos el cuaderno Jupyter para ejecutar el código. Sin embargo, recomendaría usar el Colaboratory de Google, ya que no requiere ninguna configuración y el código se ejecuta en una máquina virtual dedicada a tu cuenta. El único inconveniente es que las máquinas virtuales se reciclan cuando están inactivas por un tiempo y tienen una vida útil máxima impuesta por el sistema.

Instalaciones primarias

Necesitarás una NLU Rasa, Rasa Core y un modelo de lenguaje de spaCy.

#Rasa NLU  python m pip install rasa_nlu[spacy] (https://rasa.com/docs/nlu/installation/)#Rasa Core  python m pip install -U rasa_core == 0.9.6  (https://rasa.com/docs/core/installation/)#Language Modelpython -m spacy download en_core_web_md  python -m spacy link en_core_web_md en --force;

La versión Rasa Core utilizada en este artículo no es la más reciente. Trabajar con el último generó errores al ejecutar el código, así que tuve que trabajar con la versión anterior. Actualmente estoy trabajando para que el código se ejecute en la última versión.

Instalaremos las otras dependencias según tus requerimientos.

1. Enseñar al bot a comprender las entradas del usuario utilizando Rasa NLU

NLU se ocupa de enseñar a un chatbot a entender las entradas de los usuarios. Aquí hay un ejemplo de una conversación que nos gustaría tener con nuestro bot.

Para poder lograr esto, vamos a construir un modelo Rasa NLU y alimentar los datos de entrenamiento que el usuario debe preparar. El modelo convertirá los datos en un formato estructurado que consta de entidades e intenciones.

1. Preparando los datos de entrenamiento de NLU

Los datos de entrenamiento consisten en una lista de mensajes que uno espera recibir del bot. Estos datos se anotan con la intención y las entidades que Rasa NLU debe aprender a extraer. Entendamos el concepto de intención y entidades con un ejemplo.

    • Intención: La intención describe lo que piden los mensajes. Por ejemplo, para un robot de predicción del tiempo, la oración: What’s the weather like tomorrow?” tiene una request_weatherintención.
  • Entidad: piezas de información que ayudan a un chatbot a comprender qué es lo que específicamente pregunta un usuario al reconocer los datos estructurados en la oración .

Aquí la cocina y la ubicación son dos entidades extraídas.

A continuación se muestra un extracto de los datos de entrenamiento. También puedes agregar algunos errores de ortografía o slangs ya que le darán un tono diferente al bot. Para toda la información de entrenamiento, puedes chequear el cuaderno .

nlu_md = """  ## intent:greet  - hey  - hello there  - hi  - hello there  ## intent:goodbye  - cu  - good by  - cee you later  ## intent:mood_unhappy  - my day was horrible  - I am sad  - I don't feel very well  - I am disappointed  %store nlu_md > nlu.md

Los datos de entrenamiento se escribirán en un nlu.mdarchivo y se almacenarán en el mismo directorio que tu cuaderno. Los datos de entrenamiento generalmente se almacenan en un markdown file.

2. Definiendo la configuración del modelo NLU

Rasa NLU tiene una serie de componentes diferentes, que juntos hacen una pipeline. Una vez que los datos de entrenamiento estén listos, podemos enviarlos al modelo de NLU. Todos los componentes que se enumeran en la pipeline serán entrenados uno tras otro. Puedes leer más sobre las pipelines aquí .

config = """  language: "en"    pipeline:  - name: "nlp_spacy"                   # loads the spacy language model  - name: "tokenizer_spacy"             # splits the sentence into tokens  - name: "ner_crf"                   # uses the pretrained spacy NER model  - name: "intent_featurizer_spacy"     # transform the sentence into a vector representation  - name: "intent_classifier_sklearn"   # uses the vector representation to classify using SVM  - name: "ner_synonyms"                # trains the synonyms  """    %store config > config.yml

Este archivo contiene las configuraciones que se utilizarán en el modelo nlu. El archivo de configuración será importante para el entrenamiento del modelo, ya que proporcionará unos cuantos parámetros importantes que se utilizarán durante el entrenamiento del modelo.

3. Entrenando el Modelo NLU.

Es hora de entrenar a nuestro modelo para que reconozca las entradas del usuario, de modo que cuando envíe un mensaje como “hola” a tu bot, este lo reconocerá como una greetintención y cuando envíe “bye”, lo reconocerá como una goodbyeintención.

from rasa_nlu.training_data import load_data  from rasa_nlu.config import RasaNLUModelConfig  from rasa_nlu.model import Trainer  from rasa_nlu import config    # loading the nlu training samples  training_data = load_data("nlu.md")    # trainer to educate our pipeline  trainer = Trainer(config.load("config.yml"))    # train the model!  interpreter = trainer.train(training_data)    # store it for future use  model_directory = trainer.persist("./models/nlu", fixed_model_name="current")

Los archivos de modelo entrenados se almacenarán en la ruta: ‘./models/nlu/current’.

4. Evaluando el modelo NLU

Es hora de probar cómo funciona nuestro modelo. Pasemos algunos mensajes al azar.

# small helper to make dict dumps a bit prettier  def pprint(o):   print(json.dumps(o, indent=2))pprint(interpreter.parse("I am unhappy"))

Nuestro modelo ha funcionado bien. Ahora evaluémoslo en un conjunto de datos de prueba. Sin embargo, para nuestro propósito, evaluémoslo en los datos disponibles, es decir,nlu.md

fromrasa_nlu.evaluateimport run_evaluationrun_evaluation("nlu.md", model_directory)

Obtenemos una matriz de Intent Confusion con varios resultados de evaluación.

<

Hemos creado con éxito un Bot básico que solo puede comprender el lenguaje natural pero no los diálogos. Es hora de agregar las capacidades de diálogo a nuestro bot.

2. Enseñar al bot a responder utilizando Rasa Core.

Nuestro Bot, ahora es capaz de entender lo que el usuario está diciendo, es decir, si nuestro estado de ánimo es feliz o triste. Ahora la siguiente tarea sería hacer que el Bot responda a los mensajes. En nuestro caso, sería obtener una imagen de un perro, gato o ave dependiendo de la elección del usuario para animarlos. Enseñaremos a Robo a hacer respuestas formando un modelo de gestión de diálogo utilizando Rasa Core.

1. Escribiendo Historias

Los datos de capacitación para los modelos de gestión de diálogos se denominan stories. Una historia que consiste en una conversación real que tiene lugar entre un usuario y un Bot. Las entradas del usuario se expresan como intentos, así como las entidades correspondientes, y las respuestas de chatbot se expresan como acciones.

Veamos cómo se ve una historia típica. Esto es solo un extracto y, para obtener información completa, tan solo tienes que consultar el cuaderno.

stories_md = """## happy path   * greet    - utter_greet  * mood_great    - utter_happy  * mood_affirm   - utter_happy  * mood_affirm   - utter_goodbye    ## sad path   * greet   - utter_greet   * mood_unhappy   - utter_ask_picture  * inform{"animal":"dog"}    - action_retrieve_image   - utter_did_that_help  * mood_affirm   - utter_happy  """%store stories_md > stories.md

El formato de una historia típica es el siguiente:

## denota el inicio de una historia y puedes darle un nombre como happy path, sad pathetc.

* Denota los mensajes enviados por el usuario en forma de intenciones.

- Denota la acción tomada por el bot.

3. Definiendo un dominio

El dominio es como un universo donde opera el bot. Esto incluye qué aportaciones del usuario debería esperar obtener, qué acciones debería poder predecir, cómo responder y qué información almacenar. El dominio se compone de cinco partes fundamentales que consisten en intents, slots, entities, actions y templates. Somos conscientes de los dos primeros, entendamos los demás.

  • ranuras : las ranuras son como marcadores de posición para los valores que permiten al robot mantener un seguimiento de las conversaciones.
  • Acciones : cosas que nuestro bot diría o haría.
  • plantillas : cadenas de plantillas para las cosas que diría bot

Definimos el dominio en forma de una domain.ymlvida. Aquí hay un dominio de ejemplo para nuestro bot:

domain_yml = """  intents:  - greet  - goodbye  - mood_affirm  slots:    group:      type: text        entities:  - group  actions:  - utter_greet  - utter_did_that_help  - utter_happy      templates:    utter_greet:    - text: "Hey! How are you?"  utter_goodbye:    - text: "Bye"        utter_ask_picture:    - text: "To cheer you up, I can show you a cute picture of a dog, cat or a bird. Which one do you choose?"  """  %store domain_yml > domain.yml

4. Acciones personalizadas

Dado que queremos que nuestro Bot realice una llamada a la API para recuperar fotografías de un perro, un gato o un ave, según lo que haya especificado el usuario, debemos crear una acción personalizada. El robot sabrá qué tipo de imagen se debe recibir al recuperar el valor de la ranura group.

from rasa_core.actions import Action  from rasa_core.events import SlotSet  from IPython.core.display import Image, display    import requests    class ApiAction(Action):      def name(self):          return "action_retrieve_image"        def run(self, dispatcher, tracker, domain):                    group = tracker.get_slot('group')                    r = requests.get('http://shibe.online/api/{}?count=1&urls=true&httpsUrls=true'.format(group))          response = r.content.decode()          response = response.replace('["',"")          response = response.replace('"]',"")                         #display(Image(response[0], height=550, width=520))          dispatcher.utter_message("Here is something to cheer you up: {}".format(response))

Finalmente, capacitaremos el modelo de gestión del diálogo citando las políticas que deben usarse para capacitarlo. Para nuestro ejemplo, implementaremos una red neuronal en Keras que gana para predecir qué acción tomar a continuación.

El componente principal del modelo es una red neuronal recurrente (un LSTM), que se mapea del historial de diálogos en bruto directamente a la distribución sobre las acciones del sistema.

from rasa_core.policies import FallbackPolicy, KerasPolicy, MemoizationPolicy  from rasa_core.agent import Agent    # The fallback action will be executed if the intent recognition has #a confidence below nlu_threshold or if none of the dialogue #policies predict an action with confidence higher than #core_threshold.    fallback = FallbackPolicy(fallback_action_name="utter_unclear",                            core_threshold=0.2,                            nlu_threshold=0.1)    agent = Agent('domain.yml', policies=[MemoizationPolicy(), KerasPolicy(), fallback])    # loading our neatly defined training dialogues  training_data = agent.load_data('stories.md')    agent.train(training_data)    agent.persist('models/dialogue')

A veces quieres retroceder a una acción alternativa como decir “Lo siento, no entendí eso”. Para hacer esto, agregue el FallbackPolicyconjunto a tu póliza.

El modelo de política de keras ajustado.

El modelo se guardará en el camino:‘models/dialogue’

6. Hora de chatear

Es hora de chatear con nuestro bot. Ejecuta el siguiente código y comienza a chatear.

import warnings  warnings.simplefilter('ignore', ruamel.yaml.error.UnsafeLoaderWarning)from rasa_core.agent import Agent  from rasa_core.interpreter import NaturalLanguageInterpreter  interpreter = NaturalLanguageInterpreter.create(model_directory)  agent = Agent.load('models/dialogue', interpreter=interpreter)print("Your bot is ready to talk! Type your messages here or send 'stop'")  while True:   a = input()   if a == 'stop':   break   responses = agent.handle_text(a)   for response in responses:   print(response["text"])

El cuaderno

Puedes acceder al cuaderno desde Github o puedes revisarlo a continuación:

Conclusión

Así pues, acabamos así la primera parte del tutorial. Hemos creado un chatbot que es capaz de escuchar la entrada del usuario y responder contextualmente. En la Parte 2 desplegaremos este bot en Slack .

Utilizamos las capacidades de Rasa NLU y Rasa Core para crear un bot con datos de entrenamiento mínimos. En la siguiente parte, utilizaremos el modelo creado para implementar el bot en Slack. Rasa hace que sea realmente fácil para los usuarios experimentar con los chatbots y crearlos sin problemas. Así que es hora de que comiences a crear un bot para tu caso de uso con Rasa.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *