Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the acf domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/planetac/desa.planetachatbot.com/wp-includes/functions.php on line 6170

Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the all-in-one-seo-pack domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/planetac/desa.planetachatbot.com/wp-includes/functions.php on line 6170

Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the wp-user-avatar domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/planetac/desa.planetachatbot.com/wp-includes/functions.php on line 6170

Warning: Cannot modify header information - headers already sent by (output started at /home/planetac/desa.planetachatbot.com/wp-includes/functions.php:6170) in /home/planetac/desa.planetachatbot.com/wp-content/plugins/all-in-one-seo-pack/app/Common/Meta/Robots.php on line 87

Warning: Cannot modify header information - headers already sent by (output started at /home/planetac/desa.planetachatbot.com/wp-includes/functions.php:6170) in /home/planetac/desa.planetachatbot.com/wp-includes/feed-rss2.php on line 8
Jaime Tenorio - Planeta Chatbot https://desa.planetachatbot.com Comunidad de expertos en IA Conversacional Mon, 06 Jun 2022 13:34:56 +0000 es hourly 1 https://wordpress.org/?v=7.0 https://desa.planetachatbot.com/wp-content/uploads/2021/05/cropped-favicon-32x32.png Jaime Tenorio - Planeta Chatbot https://desa.planetachatbot.com 32 32 Aprende a usar los “forms” de RASA: un sencillo chatbot de ejemplo https://desa.planetachatbot.com/aprende-forms-rasa-sencillo-chatbot-ejemplo/?utm_source=rss&utm_medium=rss&utm_campaign=aprende-forms-rasa-sencillo-chatbot-ejemplo https://desa.planetachatbot.com/aprende-forms-rasa-sencillo-chatbot-ejemplo/#respond Wed, 09 Dec 2020 10:10:49 +0000 https://desa.planetachatbot.com/?p=826 Este tutorial es la tercera parte de mi serie de tutoriales de RASA en español. Si te gustaría leer las partes anteriores, haz click aquí: Primer parte Segunda parte Introducción En las partes anteriores demostré los conceptos básicos necesarios para construir chatbots con el framework Rasa, tales como los archivos requeridos, su estructura, y las […]

The post Aprende a usar los “forms” de RASA: un sencillo chatbot de ejemplo first appeared on Planeta Chatbot.

]]>
Este tutorial es la tercera parte de mi serie de tutoriales de RASA en español. Si te gustaría leer las partes anteriores, haz click aquí:

Introducción

En las partes anteriores demostré los conceptos básicos necesarios para construir chatbots con el framework Rasa, tales como los archivos requeridos, su estructura, y las principales características que ofrece.

En esta ocasión revisaremos los forms, que a mi parecer son de los componentes más útiles y versátiles que ofrece Rasa. Los forms son un conjunto de slots que deberán llenarse durante la conversación para finalmente ejecutar una tarea en específico, lo cual es muy útil cuando se busca obtener información puntual sobre el usuario.

Si bien en los casos anteriores no fue necesario mucho código, en Rasa, el concepto de los forms o formularios involucra el uso del rasa_sdk, que es la misma librería de Python utilizada para construir las acciones personalizadas.

Este chatbot es la traducción al español del formbot, un bot que Rasa provee como ejemplo en su repositorio de GitHub.

Antes de empezar

Para utilizar este bot debes instalar RASA y descargar el modelo de español de Spacy, puedes utilizar pip para hacerlo.

Puedes ver todo el código original en mi repositorio.

Nota:
Si deseas usar RASA 2.0, visita la guía de migración. Dado que esta versión aún se encuentra en sus etapas iniciales, seguiré usando la versión 1.10.

Datos de entrenamiento

El objetivo del formbot de Rasa es demostrar la versatilidad de los formularios, y el ejemplo se trata de desarrollar un chatbot que pida al usuario los datos suficientes para realizar una búsqueda de restaurantes. Los datos que el usuario podrá ingresar son los siguientes:

  • Tipo de cocina
  • Número de personas
  • Asiento exterior
  • Preferencias
  • Comentarios

Un extracto de los datos de entrenamiento para el lenguaje natural es el siguiente:

## intent:solicitar_restaurante
- estoy buscando un restaurante
- ¿Puedo conseguir comida [sueca](cocina) en cualquier área?
- un restaurante que sirve comida [caribeña](cocina)
- quisiera un restaurante
- Estoy buscando un restaurante que sirva comida [mediterránea](cocina)
- ¿Puedo encontrar un restaurante que sirva comida [china](cocina)?
- Reservame una mesa para tres en el restaurante [italiano](cocina)
- ¿Puedes reservar una mesa para 5?
- Me gustaría reservar una mesa para 2
- buscando una mesa en el restaurante [mexicano](cocina) para cinco
- búscame una mesa para 7 personas
- ¿Puedo conseguir una mesa para cuatro en algún lugar que sirvan comida [griega](cocina)?

## intent:informar
- comida [afgana](cocina)
- qué tal [asiático oriental](cocina)
- ¿Qué pasa con la comida [india](cocina)?
- uh, ¿qué tal el tipo de comida [turca](cocina)?
- um [inglés](cocina)
- Estoy buscando comida [toscana](cocina)
- me gustaría comida [marroquí](cocina)
- quiero sentarme [al aire libre](asiento)
- quiero sentarme [interior](asiento)
- vamos [adentro](asiento)
- 2 personas
- para tres personas
- solo una persona

## intent:charla
- ¿Cómo estás?
- ¿Cómo está el clima hoy?
- ¿Hace frío o calor?
- Hermoso día, ¿no?
- ¿Puedo preguntar quién te inventó?
- por favor dime la empresa que te creó
- por favor dime quien te creó

El intentsolicitar_restaurante tiene el objetivo de comunicar que el usuario desea buscar un restaurante, mientras que informar proporciona información sobre la búsqueda más en específico. En ambos casos se proporcionan entities que corresponden a los slots que serán requeridos por el formulario.

El intent charla contiene frases que no son relevantes para la conversación o que no están contempladas en el alcance del chatbot. Más adelante usaremos este intent.

El formato para las historias de entrenamiento de la conversación se verá de la siguiente forma:

## camino feliz
* saludar
    - utter_saludar
* solicitar_restaurante
    - restaurante_form
    - form{"name": "restaurante_form"}
    - form{"name": null}
    - utter_valores_slots
* gracias
    - utter_denada
    
## charla, detenerse pero continuar
* solicitar_restaurante
    - restaurante_form
    - form{"name": "restaurante_form"}
* charla
    - utter_charla
    - restaurante_form
* detener
    - utter_ask_continuar
* afirmar
    - restaurante_form
    - form{"name": null}
    - utter_valores_slots
* gracias
    - utter_denada

En primera instancia analicemos cómo se incluyen los formularios en las historias de entrenamiento. Tenemos este fragmento:

* solicitar_restaurante
 - restaurante_form
 - form{"name": "restaurante_form"}
 - form{"name": null}

El anterior extracto indica que cuando se detecte el intentsolicitar_restaurante, se correrá la acción de restaurante_form, la cual activará el formulario del mismo nombre, y una vez que se llenen todos los campos necesarios, el formulario se desactivará.

El formulario por sí solo se encargará de pedir los valores al usuario y de extraer la información, sin embargo, el formulario se puede interrumpir con otros intents y se puede regresar al formulario nuevamente, como en el siguiente fragmento:

* solicitar_restaurante
 - restaurante_form
 - form{"name": "restaurante_form"}
* charla
 - utter_charla
 - restaurante_form
* detener
 - utter_ask_continuar
* afirmar
 - restaurante_form
 - form{"name": null}
 - utter_valores_slots
* gracias
 - utter_denada

En este ejemplo, el formulario se ve interrumpido por el intent charla, sin embargo se retoma la ejecución del formulario. Más adelante, se detiene con el intentdetener, se pregunta si se desea continuar, y ante la afirmación, se continua y finaliza la ejecución del formulario.

Dominio y configuración

Ahora veremos cómo deben ser los archivos de dominio y configuración para poder hacer uso de los formularios en Rasa. En primer lugar, en el archivo domain.yml debemos declarar los slots que llenará nuestro formulario. Estos deben ser de tipo unfeaturized y con auto_fill en falso. Asimismo, se deben añadir respuestas con nombres de la forma utter_ask_{slot} para cada slot que llene el formulario.

entities:
  - cocina
  - asiento
  - comentarios
  - number # duckling

slots:
  cocina:
    type: unfeaturized
    auto_fill: false
  numero_personas:
    type: unfeaturized
    auto_fill: false
  asiento_exterior:
    type: unfeaturized
    auto_fill: false
  preferencias:
    type: unfeaturized
    auto_fill: false
  comentarios:
    type: unfeaturized
    auto_fill: false
  requested_slot:
    type: unfeaturized

responses:
  utter_ask_cocina:
    - text: "¿Qué tipo de cocina?"
  utter_ask_numero_personas:
    - text: "¿Para cuántas personas?"
  utter_ask_asiento_exterior:
    - text: "¿Quieres un asiento en el exterior?"
  utter_ask_preferencias:
    - text: "Por favor proporciona preferencias adicionales"
  utter_ask_comentarios:
    - text: "Por favor proporciona comentarios sobre tu experiencia hasta ahora"
    
forms:
  - restaurante_form

Tomando como ejemplo el anterior fragmento, tenemos el slot cocina, entonces agregamos el utter_ask_cocina. Estas respuestas se mostrarán automáticamente cuando el formulario necesite los llenar los slots.

Es importante mencionar que se debe agregar el slotrequested_slot, que es en donde se almacenará el nombre del slot que se buscará llenar en el formulario. También se deben agregar todos los formularios que se vayan a usar bajo el apartado forms.

En el archivo config.yml debemos incluir FormPolicy en las policies para poder hacer uso de los formularios.

language: es

pipeline:
  - name: SpacyNLP
  - name: SpacyTokenizer
  - name: SpacyFeaturizer
  - name: RegexFeaturizer
  - name: DucklingHTTPExtractor
    url: http://localhost:8000
    dimensions:
      - number
  - name: DIETClassifier
    epochs: 100
  - name: EntitySynonymMapper

policies:
  - name: FallbackPolicy
  - name: MemoizationPolicy
  - name: FormPolicy
  - name: MappingPolicy

Acciones

El último paso para poder hacer uso de nuestro formulario es agregar el código para controlar su comportamiento, haciendo uso del rasa_sdk, el cual es sumamente flexible.

El siguiente código muestra la implementación de un FormAction para nuestro formulario.

from typing import Dict, Text, Any, List, Union, Optional

from rasa_sdk import Tracker
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk.forms import FormAction


class RestaurantForm(FormAction):
    def name(self) -> Text:
        return "restaurante_form"

    @staticmethod
    def required_slots(tracker: Tracker) -> List[Text]:
        return ["cocina", "numero_personas", "asiento_exterior", "preferencias", "comentarios"]

    def slot_mappings(self) -> Dict[Text, Union[Dict, List[Dict]]]:
        return {
            "cocina": self.from_entity(entity="cocina", not_intent="chitchat"),
            "numero_personas": [
                self.from_entity(
                    entity="number", intent=["informar", "solicitar_restaurante"]
                ),
            ],
            "asiento_exterior": [
                self.from_entity(entity="asiento"),
                self.from_intent(intent="afirmar", value=True),
                self.from_intent(intent="negar", value=False),
            ],
            "preferencias": [
                self.from_intent(intent="negar", value="Sin preferencias adicionales"),
                self.from_text(not_intent="afirmar"),
            ],
            "comentarios": [self.from_entity(entity="comentarios"), self.from_text()],
        }

    @staticmethod
    def cocina_db() -> List[Text]:
        return [
            "caribeña",
            "china",
            "francesa",
            "griega",
            "india",
            "italiana",
            "mexicana",
        ]

    @staticmethod
    def is_int(string: Text) -> bool:
        try:
            int(string)
            return True
        except ValueError:
            return False

    def validate_cocina(
        self,
        value: Text,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
    ) -> Dict[Text, Any]:
        if value.lower() in self.cocina_db():
            return {"cocina": value}
        else:
            dispatcher.utter_message(template="utter_cocina_equivocada")
            return {"cocina": None}

    def validate_numero_personas(
        self,
        value: Text,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
    ) -> Dict[Text, Any]:
        if self.is_int(value) and int(value) > 0:
            return {"numero_personas": value}
        else:
            dispatcher.utter_message(template="utter_numero_personas_equivocada")
            return {"numero_personas": None}

    def validate_asiento_exterior(
        self,
        value: Text,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
    ) -> Dict[Text, Any]:
        if isinstance(value, str):
            if "afuera" in value:
                return {"asiento_exterior": True}
            elif "adentro" in value:
                return {"asiento_exterior": False}
            else:
                dispatcher.utter_message(template="utter_asiento_exterior_equivocado")
                return {"asiento_exterior": None}

        else:
            return {"asiento_exterior": value}

    def submit(
        self,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
    ) -> List[Dict]:
        dispatcher.utter_message(template="utter_submit")
        return []

¡Vaya! Tal vez parece mucho código pero su funcionamiento es muy sencillo. Veamos paso a paso qué es lo que hace este código.

Primero importamos las clases necesarias y declaramos una nueva clase RestaurantForm que hereda de FormAction. Una vez hecho esto, definiremos una serie de métodos para esta clase:

  1. name: Este método debe retornar el nombre del formulario, como se declaró en domain.yml.
  2. required_slots: Aquí se definen los slots que requerirá el formulario durante su ejecución. El formulario intentará obtenerlos en el orden especificado.
  3. slot_mappings: Esta es la forma en la que se llenará cada slot del formulario. Hay varias maneras de asignar valores a los slots: from_entity (se especifica qué entidad tomar de los mensajes), from_intent (si se identifica este intent se asigna un valor especificado) y from_text (se toma todo el texto del mensaje del usuario).
    Si se asignan varios mappings, el formulario tomará la primer coincidencia.
  4. submit: Este método se ejecuta una vez que todos los slots han sido llenados. Aquí se puede ejecutar cualquier código haciendo uso de los valores recabados durante la ejecución del formulario.
    Para obtener los valores se usa tracker.get_slot(), con el nombre del slotque se desea obtener.
  5. validate_{slot}: Estos métodos, de los cuales puede haber uno por cada slot, validarán los valores que se recojan antes de asignarlos. Yo considero que estas funciones son las más importantes en los formularios, ya que permiten tener un control total sobre los valores que se guardarán para posteriormente utilizarlos.
    Cada función de validación debe retornar un diccionario con el nombre del slot que se valida y el valor que se asigna. En caso de que la entrada sea inválida, se retorna con un valor nulo (None), en cuyo caso el formulario volverá a preguntar por este valor. Por ejemplo:
 def validate_cocina(
 self,
 value: Text,
 dispatcher: CollectingDispatcher,
 tracker: Tracker,
 domain: Dict[Text, Any],
 ) -> Dict[Text, Any]:
 if value.lower() in self.cocina_db():
 return {"cocina": value}
 else:
 dispatcher.utter_message(
 template="utter_cocina_equivocada")
 return {"cocina": None}

Si el tipo de cocina solicitado no se encuentra en la “base de datos” de cocinas, se arroja un mensaje al usuario y se volverá a preguntar por el tipo de cocina. En el caso contrario, se acepta la entrada y se continúa con el flujo.

Ejecución

Una vez listos todos los archivos, podemos proceder a probar nuestro chatbot.

En este bot haremos uso de Duckling para extraer datos numéricos (notarás que no incluimos datos de entrenamiento para este caso), entonces primero debemos correr una instancia local de este servicio con:

docker run -p 8000:8000 -d rasa/duckling

Ahora, para poder hacer uso de las acciones que escribimos, corramos un servidor de acciones de Rasa con el comando:

rasa run actions &

Y finalmente podremos interactuar con el chatbot. Con el comando siguiente podremos iniciar una sesión de conversación en la terminal:

rasa shell

Aquí tenemos un ejemplo de un “camino feliz”:

Demostrando la flexibilidad de los formularios:

Finalmente un “camino infeliz”:

Espero que este tutorial te haya sido de utilidad, si tienes algún problema con el tutorial, por favor, escríbeme y con gusto te ayudaré.

Recuerda que todo el código se encuentra en mi GitHub:

jaimeteb – Overview

Mechatronics Engineer with a career in Software Development and Machine Learning. Made in Mexico. 🇲🇽 Arctic Code…

github.com

The post Aprende a usar los “forms” de RASA: un sencillo chatbot de ejemplo first appeared on Planeta Chatbot.

]]>
https://desa.planetachatbot.com/aprende-forms-rasa-sencillo-chatbot-ejemplo/feed/ 0
Crea un chatbot de Pokémon en español con RASA https://desa.planetachatbot.com/crea-chatbot-pokemon-espanol-rasa/?utm_source=rss&utm_medium=rss&utm_campaign=crea-chatbot-pokemon-espanol-rasa https://desa.planetachatbot.com/crea-chatbot-pokemon-espanol-rasa/#respond Wed, 15 Jul 2020 10:03:32 +0000 https://desa.planetachatbot.com/?p=814 Este tutorial es la segunda parte de mi serie de tutoriales de RASA en español. Si te gustaría ver la primer parte, la puedes leer aquí. Introducción En la primera parte de los tutoriales de RASA en español construimos un chatbot muy sencillo cuyo propósito era demostrar la estructura de los archivos que utiliza el […]

The post Crea un chatbot de Pokémon en español con RASA first appeared on Planeta Chatbot.

]]>
Este tutorial es la segunda parte de mi serie de tutoriales de RASA en español. Si te gustaría ver la primer parte, la puedes leer aquí.

Introducción

En la primera parte de los tutoriales de RASA en español construimos un chatbot muy sencillo cuyo propósito era demostrar la estructura de los archivos que utiliza el framework, así como sus principales características.

Aquel bot no tiene mayor utilidad, por lo que en esta segunda parte introduciremos nuevos conceptos y al mismo tiempo crearemos un proyecto más complejo, utilizando la PokéApi.

El objetivo será desarrollar un chatbot que permita al usuario buscar información acerca de cualquier Pokémon, ya sea proporcionando su nombre o su número.

Pokébot en acción

Antes de empezar

Para utilizar este bot debes instalar RASA y descargar el modelo de español de Spacy, puedes utilizar pip para hacerlo. Personalmente utilizo la versión 1.10.1, pero no debería haber problema con las versiones, al menos para este ejemplo.

De igual manera he preparado un Dockerfile con lo necesario para ejecutar este bot. Puedes ver todo el código original en mi repositorio.

Nota:
Si deseas usar RASA 2.0, visita la guía de migración. Dado que esta versión aún se encuentra en etapa de pre-release, seguiré usando la versión 1.10.

Reconocimiento de Entidades

¿Cómo va a saber el chatbot qué buscar? De alguna manera necesitamos almacenar ya sea el nombre o el número del Pokémon a buscar para poder utilizarlo en el PokéApi. RASA soporta métodos de Reconocimiento de Entidades, los cuales serán útiles para esta tarea.

Partiremos del archivo config.yml del anterior tutorial. Antes que nada, habilitaremos el Reconocimiento de Entidades en el componente DIETClassifier:

Ahora debemos enseñar al chatbot cómo reconocer un nombre o un número de Pokémon, para lo cual nos dirigiremos al archivo nlu.md. Veamos el siguiente ejemplo:

Únicamente tenemos dos intents: saludo y buscar_pokemon. Si te fijas, en los ejemplos de buscar_pokemon hay ciertas palabras marcadas, así es como se etiquetan las entidades para el entrenamiento del chatbot:

- buscar a [Electabuzz](nombre_pokemon)
- buscar al pokemon [88](numero_pokemon)

De esta manera se indica que Electabuzz es una entidad de tipo nombre_pokemon, así como 88 es una entidad de tipo numero_pokemon.

Además, se agregó una expresión regular para numero_pokemon, ya que se puede modelar como un número de máximo tres dígitos, y de esta manera mejorar el reconocimiento de esta entidad.

Almacenamiento de Slots

Ahora que hemos indicado al chatbot cómo reconocer entidades, ¿dónde las almacena? RASA cuenta con los llamados slots, que son valores almacenados en la memoria del bot durante la conversación. Para comenzar a utilizar slots, debemos agregarlos en domain.yml.

Hemos declarado los entities para reconocer nombre_pokemon y numero_pokemon, así como los slots para almacenar nombre_pokemon y numero_pokemon. Si un slot lleva el mismo nombre que un entity, el valor identificado de la entidad se asigna automáticamente a ese slot.

Además de lo anterior, agregamos el mensaje utter_info_pokemon para desplegar la información encontrada a través del PokéApi, en este caso el número, el nombre, los tipos y una imagen. Más adelante revisaremos cómo llenar estos campos.

Habrás notado que en domain.yml también hay un apartado llamado actions, donde he listado action_buscar_pokemon. Los actions en RASA son piezas de código en Python que se ejecutan durante la conversación. Estas acciones pueden contener funciones de todo tipo: ejecutar solicitudes a APIs, operaciones sobre bases de datos, cálculos, modificación de la conversación misma, etc.

Antes de ver a detalle el action para este chatbot, definamos en qué punto de la conversación se va ejecutar. Para esto, escribamos el archivo stories.md.

En las historias expresaremos que un usuario proporcionó el valor de un entity en un dado intent con la notación siguiente:

* intent{"entity": "valor"}

Entonces, en las historias hemos definido que se ejecute action_buscar_pokemon en cuando se proporcione un nombre_pokemon o un numero_pokemon.

Servidor de Actions

Los actions son ejecutados desde un action server, el cual requiere de un archivo llamado actions.py, donde estará el código correspondiente para cada uno.

Para desarrollar un action, haremos uso de la librería Rasa SDK, incluida en la instalación de RASA. Un action debe ser una clase que hereda de rasa_sdk.Action y que implementa el método run.

El siguiente es el archivo actions.py que desarrollé para el PokéBot (he omitido las variables POKEAPI_URL y POKEMON_TIPOS por simplicidad):

Dentro de la acción, para obtener los valores almacenados en los slots haremos uso del tracker, que es el objeto que contiene toda la información de la conversación actual.

Según el slot que encontremos, ya sea numero_pokemon o nombre_pokemon, haremos una petición al PokéApi, con ayuda del módulo requests.

Finalmente, extraemos la información necesaria del JSON que obtuvimos como respuesta a la petición, para presentarla en el mensaje utter_info_pokemon.

El tipo de dato que el método run debe devolver es una lista de events, en este caso únicamente borraremos la información almacenada en los slots, para poder almacenar nuevos valores.

Por último, debemos indicar a RASA dónde buscar las acciones, esto se hará a través del archivo endpoints.yml:

Ejecución

Con todos los componentes listos, podemos proceder a probar nuestro chatbot. Como siempre, empezaremos por entrenarlo.

rasa train

Una vez finalizado el entrenamiento ejecutaremos tanto el servidor de acciones como el de RASA, lo cual recomiendo hacer en diferentes terminales.

Para ejecutar el servidor de acciones, ejecuta el siguiente comando:

rasa run actions

Para ejecutar el chatbot, en otra terminal, ejecuta el este comando:

rasa shell

Ahora podrás hablar con el chatbot a través de la línea de comandos. Podrás interactuar con el bot de esta forma:

Pokébot en Rasa shell

El chatbot es capaz de reconocer el nombre o número de un Pokémon y obtener su información a través de la PokéApi. Hay que mencionar que el entrenamiento no ha sido intensivo ni hemos hecho muchos ajustes, por lo cual es posible que no funcione correctamente con algunos nombres de Pokémon.

Espero que este tutorial te haya sido de utilidad, si tienes algún problema con el tutorial, por favor, escríbeme y con gusto te ayudaré.

Más tutoriales de RASA en español por venir. Por lo pronto, visita mi GitHub:

jaimeteb – Overview

Mechatronics Engineer with a career in Software Development and Machine Learning. Made in Mexico. 🇲🇽 Arctic Code…

github.com

The post Crea un chatbot de Pokémon en español con RASA first appeared on Planeta Chatbot.

]]>
https://desa.planetachatbot.com/crea-chatbot-pokemon-espanol-rasa/feed/ 0
Construyendo un Chatbot en español usando RASA — Moodbot https://desa.planetachatbot.com/construyendo-un-chatbot-en-espanol-usando-rasa-moodbot/?utm_source=rss&utm_medium=rss&utm_campaign=construyendo-un-chatbot-en-espanol-usando-rasa-moodbot https://desa.planetachatbot.com/construyendo-un-chatbot-en-espanol-usando-rasa-moodbot/#comments Wed, 15 Jul 2020 09:00:06 +0000 https://desa.planetachatbot.com/?p=842 Cuando me encargaron por primera vez la tarea de crear un chatbot, no tenía idea de cómo comenzar. Mi experiencia en Machine Learning de concentraba principalmente en Visión Artificial y Redes Neuronales, nunca había experimentado con Lenguaje Natural. Sabía que se tiene que procesar el texto y producir un mensaje con base en esto, pero […]

The post Construyendo un Chatbot en español usando RASA — Moodbot first appeared on Planeta Chatbot.

]]>
Cuando me encargaron por primera vez la tarea de crear un chatbot, no tenía idea de cómo comenzar. Mi experiencia en Machine Learning de concentraba principalmente en Visión Artificial y Redes Neuronales, nunca había experimentado con Lenguaje Natural.

Sabía que se tiene que procesar el texto y producir un mensaje con base en esto, pero desconocía las técnicas apropiadas.

Teniendo conocimientos de Python, investigué las opciones disponibles para la creación de asistentes en dicho lenguaje, y entonces encontré Rasa.

Introducción

Rasa es un framework para la creación de asistentes y chatbots, escrito en Python y de código abierto. Basa su funcionamiento en dos componentes principales, NLU y Core:

  • NLU es la parte encargada de tomar el texto, analizarlo y descomponerlo de tal manera que el bot comprenda el contenido del mensaje.
  • Core es la parte encargada de tomar decisiones y dar seguimiento a la conversación según lo que NLU provee.

Ambos elementos utilizan técnicas de aprendizaje de máquina.

Si tienes experiencia en aprendizaje de máquina será más fácil que comprendas los pasos siguientes, de lo contrario, no te asustes, no tendrás que escribir código, Rasa es muy fácil de configurar.

Antes de empezar

Para utilizar este bot debes instalar RASA, puedes utilizar pip para hacerlo. Personalmente utilizo la versión 1.10.1, pero no debería haber problema con las versiones, al menos para este ejemplo.

De igual manera he preparado un Dockerfile con lo necesario para ejecutar este bot. Puedes ver todo el código original en mi repositorio.

Configuración y entrenamiento

Aunque no lo creas, este primer bot será creado con tan sólo 4 archivos. Sí, no es broma, para la creación de este chatbot básico (al que Rasa llama Moodbot) necesitaremos 4 archivos. Cada uno de ellos nos ayudará a entender mejor el funcionamiento de Rasa.

nlu.md

En este primer archivo describiremos la manera en la que el bot comprenderá el texto. Aquí enlistaremos los intents, que son las intenciones o propósitos que buscaremos captar del usuario, por ejemplo, el mensaje “buenos días” tiene como intención “saludar”, mientras que el mensaje “¿cómo estará el clima mañana?” tiene la intención “consultar clima”.

Para cada intent que se busque clasificar se deberán proporcionar textos de ejemplo, a través de los cuales el bot se entrenará. El formato a utilizar es el siguiente:

intent:afirmar

  • si claro
  • por supuesto
  • ok
  • afirmativo
  • así es
  • sin duda

intent:negar

  • No
  • para nada
  • no me gusta
  • Nunca
  • Claro que no
  • jamás
  • no no no
view raw01_nlu.md hosted with ❤ by GitHub

stories.md

En este archivo se escriben las interacciones entre el bot y el usuario con las que se entrenará el asistente. Se deben incluir múltiples ejemplos de “historias”, con el objetivo de que el bot pueda decidir cuál es la mejor acción a tomar después de una interacción con el usuario.

Los intents del usuario se colocan con asteriscos (*), mientras que las acciones o mensajes del bot se escriben con guiones (-). Las historias pueden tener títulos, sin embargo estos no afectarán el entrenamiento. El archivo debe mantener el siguiente formato:

camino feliz

  • saludo
    • utter_saludo
  • humor_bien
    • utter_feliz

camino infeliz

  • saludo
    • utter_saludo
  • humor_mal
    • utter_animo

domain.yml

En este archivo debemos registrar todos los intents que buscaremos captar del usuario, así como los mensajes (utterances) y acciones (actions) que el bot realizará. Aquí es donde definiremos el texto que contendrán los mensajes que incluimos en las interacciones de stories.md. A continuación un ejemplo de este archivo:

 

Si te das cuenta, incluso se pueden incluir imágenes en las respuestas que proporcionará el bot.

config.yml

Por último tenemos el archivo de configuración. Aquí se definirá el pipeline, que son los procesos que se le aplicarán al texto de entrada para que el bot pueda usarlo. Cada parte del pipeline es un componente diferente que ayuda en las tareas de Lenguaje Natural, por ejemplo:

  • Tokenizers: la tokenización consiste en separar el texto en entidades llamadas tokens, para facilitar el procesamiento de este.
  • Featurizers: estos componentes convierten texto en features, que son representaciones numéricas del texto, para su uso en otros algoritmos.
  • Classifiers: los clasificadores se encargarán de decidir a qué intent se refieren los mensajes del usuario.

De igual manera, en este archivo se listan las políticas (policies) bajo las cuales se regirá la conversación. Cada política tiene un principio de funcionamiento diferente, y la combinación de ellas hace que el bot sea más robusto y pueda tomar mejores decisiones. Ejemplos de policies son los siguientes:

  • TEDPolicy: usa una red neuronal recurrente para predecir la mejor acción a tomar, basándose en las historias de entrenamiento.
  • MemoizationPolicy: decide la acción siguiente si las interacciones previas ocurrieron en las historias de entrenamiento.
  • MappingPolicy: ejecuta acciones basadas en “mapeos”; se pueden programar acciones específicas cuando se encuentren ciertos intents.

Ejecución

Con estos 4 archivos listos, podemos proceder a utilizar el bot por primera vez. Empezaremos por entrenar el bot.

rasa train

Con este comando entrenarás tanto la parte NLU como la parte Core del chatbot. Después de un momento, cuando finalice el entrenamiento, podrás usar el siguiente comando:

rasa shell

Con este último podrás interactuar con el chatbot a través de la línea de comandos. Puedes experimentar un poco y ver qué responde ante respuestas diferentes, aunque toma en cuenta que este ejemplo es muy simple.

Docker

Si te interesa ejecutar el chatbot en Docker, he creado en el repositorio para este tutorial un archivo Dockerfile.

La imagen de la cual partimos es una que yo he creado, la cual contiene el modelo de lenguaje de español, que es útil para obtener features en el pipeline. Los pasos restantes son añadir los archivos y entrenar el modelo.

Puedes construir la imagen con el comando:

docker build -t moodbot-es .

Y ejecutarlo con:

docker run -it --entrypoint rasa moodbot-es shell

Aquí puedes encontrar la segunda parte de este tutorial.

Espero que este tutorial te haya sido de utilidad. Escribiré más tutoriales de RASA en español en el futuro. Por lo pronto, visita mi GitHub:

jaimeteb – Overview

Dismiss Sign up for your own profile on GitHub, the best place to host code, manage projects, and build software…

github.com

The post Construyendo un Chatbot en español usando RASA — Moodbot first appeared on Planeta Chatbot.

]]>
https://desa.planetachatbot.com/construyendo-un-chatbot-en-espanol-usando-rasa-moodbot/feed/ 1