Chatbots usando Python y Rasa

Rasa es una herramienta para crear chatbots de IA personalizados utilizando Python y la comprensión del lenguaje natural (NLU). Rasa proporciona un marco para desarrollar chatbots de IA que utilizan la comprensión del lenguaje natural (NLU). También permite al usuario entrenar el modelo y agregar acciones personalizadas. Chatbots creados con Rasa implementados en múltiples plataformas como FB messenger, Microsoft bot y slack, etc.

Arquitectura:

arquitectura rasa

Rasa tiene dos componentes principales:

  • Rasa NLU (Entendimiento del lenguaje natural): Rasa NLU es una herramienta de procesamiento de lenguaje natural de código abierto para la clasificación de intenciones (decide lo que pregunta el usuario), la extracción de la entidad del bot en forma de datos estructurados y ayuda al chatbot a comprender qué usuario está diciendo.
  • Rasa Core : un marco de chatbot con gestión de diálogo basada en aprendizaje automático que toma la entrada estructurada de la NLU y predice la siguiente mejor acción utilizando un modelo probabilístico como la red neuronal LSTM en lugar de una declaración if/else. Debajo del capó, también utiliza el aprendizaje por refuerzo para mejorar la predicción de la siguiente mejor acción.

En otras palabras, el trabajo de Rasa NLU es interpretar la entrada proporcionada por el usuario en forma de datos estructurados y el trabajo de Rasa Core es decidir el próximo conjunto de acciones realizadas por el chatbot. Rasa Core y Rasa NLU son independientes entre sí y se pueden usar por separado.

Cómo instalar Rasa :

  • Se recomienda encarecidamente utilizar un entorno virtual antes de instalar RASA. Para crear el entorno virtual, el comando en anaconda es:
conda create -n rasa
activate rasa
  • Ahora, instalaremos el Rasa en nuestro entorno, lo instalaremos usando pip install. También necesitamos instalar TensorFlow en nuestro entorno (será instalado por defecto por Rasa). La instalación de rasa llevará algún tiempo.
pip install rasa
  • Ahora, inicializaremos el bot usando rasa init. Esto creará los archivos de proyecto de declaración para el chatbot y entrenará el modelo inicial.
rasa init
o get started quickly, an initial project will be created.
If you need some help, check out the documentation at https://rasa.com/docs/rasa.
Now let's start! ????????

? Please enter a path where the project will be created [default: current directory] ./sample_bot
? Path './sample_bot' does not exist ????. Create path?  Yes
Created project directory at 'C:\Users\Pawan\Desktop\chatbots\sample_bot'.
Finished creating project structure.
? Do you want to train an initial model? ????????  Yes
Training an initial model...
Training Core model...
Processed Story Blocks: 100%|??????????????????????????????????????????????????????| 5/5 [00:00<?, ?it/s, # trackers=1]
Processed Story Blocks: 100%|????????????????????????????????????????????| 5/5 [00:00<00:00, 1252.55it/s, # trackers=5]
Processed Story Blocks: 100%|????????????????????????????????????????????| 5/5 [00:00<00:00, 250.35it/s, # trackers=20]
Processed Story Blocks: 100%|????????????????????????????????????????????| 5/5 [00:00<00:00, 178.79it/s, # trackers=24]
Processed trackers: 100%|????????????????????????????????????????????????| 5/5 [00:00<00:00, 1252.03it/s, # actions=16]
Processed actions: 16it [00:00, 667.56it/s, # examples=16]
Processed trackers: 100%|????????????????????????????????????????????| 231/231 [00:00<00:00, 284.86it/s, # actions=126]
Epochs:   0%|                                                                                  | 0/100 [00:00<?, ?it/s]c:\users\Pawan\anaconda3\envs\rasa\lib\site-packages\rasa\utils\tensorflow\model_data.py:386: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray
  final_data[k].append(np.concatenate(np.array(v)))
Epochs: 100%|???????????????????????????????????| 100/100 [00:31<00:00,  3.15it/s, t_loss=0.202, loss=0.131, acc=1.000]
2020-07-31 22:55:59 INFO     rasa.utils.tensorflow.models  - Finished training.
2020-07-31 22:56:02 INFO     rasa.core.agent  - Persisted model to 'C:\Users\Pawan\AppData\Local\Temp\tmpk26900vo\core'
Core model training completed.
Training NLU model...
2020-07-31 22:56:03 INFO     rasa.nlu.training_data.training_data  - Training data stats:
2020-07-31 22:56:03 INFO     rasa.nlu.training_data.training_data  - Number of intent examples: 43 (7 distinct intents)
2020-07-31 22:56:03 INFO     rasa.nlu.training_data.training_data  -   Found intents: 'bot_challenge', 'mood_unhappy', 'mood_great', 'greet', 'affirm', 'goodbye', 'deny'
2020-07-31 22:56:03 INFO     rasa.nlu.training_data.training_data  - Number of response examples: 0 (0 distinct responses)
2020-07-31 22:56:03 INFO     rasa.nlu.training_data.training_data  - Number of entity examples: 0 (0 distinct entities)
2020-07-31 22:56:03 INFO     rasa.nlu.model  - Starting to train component WhitespaceTokenizer
2020-07-31 22:56:03 INFO     rasa.nlu.model  - Finished training component.
2020-07-31 22:56:03 INFO     rasa.nlu.model  - Starting to train component RegexFeaturizer
2020-07-31 22:56:03 INFO     rasa.nlu.model  - Finished training component.
2020-07-31 22:56:03 INFO     rasa.nlu.model  - Starting to train component LexicalSyntacticFeaturizer
2020-07-31 22:56:03 INFO     rasa.nlu.model  - Finished training component.
2020-07-31 22:56:03 INFO     rasa.nlu.model  - Starting to train component CountVectorsFeaturizer
2020-07-31 22:56:03 INFO     rasa.nlu.model  - Finished training component.
2020-07-31 22:56:03 INFO     rasa.nlu.model  - Starting to train component CountVectorsFeaturizer
2020-07-31 22:56:03 INFO     rasa.nlu.model  - Finished training component.
2020-07-31 22:56:03 INFO     rasa.nlu.model  - Starting to train component DIETClassifier
co get started quickly, an initial project will be created.
If you need some help, check out the documentation at https://rasa.com/docs/rasa.
Now let's start! ????????

? Please enter a path where the project will be created [default: current directory] ./sample_bot
? Path './sample_bot' does not exist ????. Create path?  Yes
Created project directory at 'C:\Users\Pawan\Desktop\chatbots\sample_bot'.
Finished creating project structure.
? Do you want to train an initial model? ????????  Yes
Training an initial model...
Training Core model...
Processed Story Blocks: 100%|??????????????????????????????????????????????????????| 5/5 [00:00<?, ?it/s, # trackers=1]
Processed Story Blocks: 100%|????????????????????????????????????????????| 5/5 [00:00<00:00, 1252.55it/s, # trackers=5]
Processed Story Blocks: 100%|????????????????????????????????????????????| 5/5 [00:00<00:00, 250.35it/s, # trackers=20]
Processed Story Blocks: 100%|????????????????????????????????????????????| 5/5 [00:00<00:00, 178.79it/s, # trackers=24]
Processed trackers: 100%|????????????????????????????????????????????????| 5/5 [00:00<00:00, 1252.03it/s, # actions=16]
Processed actions: 16it [00:00, 667.56it/s, # examples=16]
Processed trackers: 100%|????????????????????????????????????????????| 231/231 [00:00<00:00, 284.86it/s, # actions=126]
Epochs:   0%|                                                                                  | 0/100 [00:00<?, ?it/s]c:\users\Pawan\anaconda3\envs\rasa\lib\site-packages\rasa\utils\tensorflow\model_data.py:386: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray
  final_data[k].append(np.concatenate(np.array(v)))
Epochs: 100%|???????????????????????????????????| 100/100 [00:31<00:00,  3.15it/s, t_loss=0.202, loss=0.131, acc=1.000]
2020-07-31 22:55:59 INFO     rasa.utils.tensorflow.models  - Finished training.
2020-07-31 22:56:02 INFO     rasa.core.agent  - Persisted model to 'C:\Users\Pawan\AppData\Local\Temp\tmpk26900vo\core'
Core model training completed.
Training NLU model...
2020-07-31 22:56:03 INFO     rasa.nlu.training_data.training_data  - Training data stats:
2020-07-31 22:56:03 INFO     rasa.nlu.training_data.training_data  - Number of intent examples: 43 (7 distinct intents)
2020-07-31 22:56:03 INFO     rasa.nlu.training_data.training_data  -   Found intents: 'bot_challenge', 'mood_unhappy', 'mood_great', 'greet', 'affirm', 'goodbye', 'deny'
2020-07-31 22:56:03 INFO     rasa.nlu.training_data.training_data  - Number of response examples: 0 (0 distinct responses)
2020-07-31 22:56:03 INFO     rasa.nlu.training_data.training_data  - Number of entity examples: 0 (0 distinct entities)
2020-07-31 22:56:03 INFO     rasa.nlu.model  - Starting to train component WhitespaceTokenizer
2020-07-31 22:56:03 INFO     rasa.nlu.model  - Finished training component.
2020-07-31 22:56:03 INFO     rasa.nlu.model  - Starting to train component RegexFeaturizer
2020-07-31 22:56:03 INFO     rasa.nlu.model  - Finished training component.
2020-07-31 22:56:03 INFO     rasa.nlu.model  - Starting to train component LexicalSyntacticFeaturizer
2020-07-31 22:56:03 INFO     rasa.nlu.model  - Finished training component.
2020-07-31 22:56:03 INFO     rasa.nlu.model  - Starting to train component CountVectorsFeaturizer
2020-07-31 22:56:03 INFO     rasa.nlu.model  - Finished training component.
2020-07-31 22:56:03 INFO     rasa.nlu.model  - Starting to train component CountVectorsFeaturizer
2020-07-31 22:56:03 INFO     rasa.nlu.model  - Finished training component.
2020-07-31 22:56:03 INFO     rasa.nlu.model  - Starting to train component DIETClassifier
....

Empezando:

El comando anterior creará archivos de proyecto iniciales en el directorio sample_bot. Veamos estos archivos:

  • __init__.py:  un archivo vacío que ayuda a Python a localizar sus acciones.
  • actions.py: este archivo se utiliza para crear acciones personalizadas. En caso de que desee llamar a un servidor externo o obtener datos de API externos, puede definir sus acciones aquí.
  • config.yml : este archivo define la configuración de la NLU y el modelo central. Si está utilizando cualquier modelo fuera del modelo NLU, debe definir la canalización aquí.
  • credentials.yml : este archivo se utiliza para almacenar credenciales para conectarse a servicios externos como Facebook Messenger, Slack, etc.
  • data/nlu.md : en este archivo, definimos nuestras intenciones (¿qué podría pedirle el usuario al bot que hiciera?). Estos intentos luego se usan para entrenar el modelo NLU.
  • data/stories.md : las historias son la conversación de muestra entre un usuario y un bot en forma de intenciones, respuestas y acciones. Las historias de Rasa son una forma de datos de entrenamiento que se utilizan para entrenar los modelos de gestión de diálogo de Rasa.
  • domain.yml : este archivo enumera las diferentes intenciones (las cosas que espera del usuario) con las respuestas y acciones del bot que puede realizar.
  • endpoints.yml : Esto define los detalles para conectar canales como Slack, FB messenger, etc. para almacenar datos de chats en las bases de datos en línea como Redis, etc.
  • models/<timestamps>.tar.gz : el modelo inicial, todos los modelos entrenados almacenados en la carpeta de modelos. Para volver a entrenar el modelo, usamos el comando de tren rasa .

Para iniciar el entorno local usamos el comando rasa x . Empezó con algo 

Starting Rasa X in local mode... ????
wow
wow

The server is running at http://localhost:5002/login?username=me&password=s23dafd5436d

2020-08-01 00:27:24 WARNING  sanic.root  - Sanic tried to use loop.add_signal_handler but it is not implemented on this platform.
2020-08-01 00:27:24 WARNING  sanic.root  - Sanic tried to use loop.add_signal_handler but it is not implemented on this platform.
  • Ahora, navegue a la dirección proporcionada por el servidor rasa, veremos la ventana del navegador en la que se abre una ventana de chat, que podemos usar para chatear con el asistente.

Creando un bot meteorológico en Rasa:

  • En este tutorial, crearemos un bot que pueda decirnos el clima de cualquier ciudad, también usaremos la API de tiempo abierto para este tutorial.
  • Primero inicializaremos el proyecto usando el siguiente comando:
rasa init --no-prompt
  • Esto creará la estructura del proyecto inicial como vimos arriba. Para este proyecto, solo necesitamos hacer cambios en los siguientes archivos:
    • datos/nlu.md
    • datos/historias.md
    • dominio.yml
    • puntos finales.yml
    • acciones.py
  • Resto todos los archivos que dejamos sin cambios.
  • Primero, definiremos las historias (Nota: las historias son la conversación de muestra que usamos para entrenar nuestro modelo). Estas historias se definen en forma de lenguaje de rebajas. Eliminamos algunas historias predefinidas y las reemplazamos con aquellas conversaciones que son relevantes para nuestro bot.
## say goodbye
* goodbye
  - utter_goodbye

## bot challenge
* bot_challenge
  - utter_iamabot

## weather long
* greet
  - utter_greet
* weather
  - utter_ask_location
* city_info
  - utter_getting_weather
  - action_get_weather
* thanks
  - utter_welcome
  - utter_goodbye

## weather short
* greet
  - utter_greet
* weather_for_location
  - utter_getting_weather
  - action_get_weather
* thanks
  - utter_welcome
  - utter_goodbye

## New Story

* greet
    - utter_greet
* weather_for_location{"location":"London"}
    - utter_getting_weather
    - action_get_weather
  • Rasa nlu.md contiene la lista de intenciones y su posible texto de muestra. Además, mapearemos nuestras entidades stext.separadamente en este ejemplo. Estos intentos se utilizan para entrenar nuestro modelo NLU.
## intent:greet
- hey
- hello
- hi
- good morning
- good evening
- hey there

## intent:goodbye
- bye
- goodbye
- see you around
- see you later

## intent:bot_challenge
- are you a bot?
- are you a human?
- am I talking to a bot?
- am I talking to a human?

## intent:weather
- what's the weather
- what is the temperature today
- what is the temperature
- i want to know the temperature
- i want to know the weather of today
- tell me the weather forecast
- hows the weather today

## intent:weather_for_location
- what is the weather in [Noida](location)
- what is the weather in [New Delhi](location)
- weather of [Mumbai] (location)
- Today's weather in [Bangalore](location)
- [Kolkata](location) weather
- Tell me weather of [Hyderabad](location)
- Can you tell me weather of [London](location)

## intent:city_info
- [New Delhi](location)
- [India](location)
- [Mumbai](location)
- [Noida](location)
- [Kolkata](location)
- [Bangalore](location)
- [London](location)

##intent: thanks
- thanks
- thank you
- OK
  • El archivo domain.yml enumera todas las intenciones, las respuestas del bot con su texto y también la acción que puede realizar el bot. Tenga en cuenta que cualquier acción o respuesta que definamos (en nlu.md/ stories.md) debe incluirse en el dominio.yml
session_config:
  session_expiration_time: 60
  carry_over_slots_to_new_session: true

intents:
- greet
- goodbye
- bot_challenge
- weather
- weather_for_location
- city_info
- thanks
entities:
- location
slots:
  location:
    type: text
responses:
  utter_greet:
  - text: Hey! 
  utter_goodbye:
  - text: Bye
  - text: Good Bye
  utter_ask_location:
  - text: of where?
  - text: In what city?
  utter_getting_weather:
  - text: Ok, getting weather of [location] ...
  utter_welcome:
  - text: Welcome
  utter_iamabot:
  - text: I am a bot, powered by Rasa.
actions:
- action_get_weather
  • Ahora, definimos la función «action_get_weather» en el archivo actions.py. Esta función toma el nombre de la ciudad de la entidad y obtiene el clima de la ciudad con la ayuda de la API de OpenWeatherMap.
from typing import Any, Text, Dict, List

from rasa_sdk import Action, Tracker
from rasa_sdk.events import SlotSet
from rasa_sdk.executor import CollectingDispatcher
import requests


class ActionCheckWeather(Action):

    def name(self)-> Text:
        return "action_get_weather"
    
    def run(self, dispatcher, tracker, domain):
        api_key = 'Your API Key'
        loc = tracker.get_slot('location')
        current = requests.get('http://api.openweathermap.org/data/2.5/weather?q={}&appid={}'.format(loc, api_key)).json()
        print(current)
        country = current['sys']['country']
        city = current['name']
        condition = current['weather'][0]['main'    ]
        temperature_c = current['main']['temp']
        humidity = current['main']['humidity']
        wind_mph = current['wind']['speed']
        response = """It is currently {} in {} at the moment. The temperature is {} degrees, the humidity is {}% and the wind speed is {} mph.""".format(condition, city, temperature_c, humidity, wind_mph)
        dispatcher.utter_message(response)
        return [SlotSet('location', loc)]
  • Ahora, entrenamos nuestro modelo usando el comando de tren rasa . Esto entrenará nuestro modelo NLU.
  • Para comprobar que nuestro modelo funciona correctamente, utilizamos el siguiente comando:
rasa shell nlu
NLU model loaded. Type a message and press enter to parse it.
Next message:
weather in Noida
{
  "intent": {
    "name": "weather_for_location",
    "confidence": 0.9999433755874634
  },
  "entities": [
    {
      "entity": "location",
      "start": 11,
      "end": 16,
      "value": "Noida",
      "extractor": "DIETClassifier"
    }
  ],
  "intent_ranking": [
    {
      "name": "weather_for_location",
      "confidence": 0.9999433755874634
    },
    {
      "name": "city_info",
      "confidence": 5.397644417826086e-05
    },
    {
      "name": "greet",
      "confidence": 1.0934791134786792e-06
    },
    {
      "name": "goodbye",
      "confidence": 1.0303868975825026e-06
    },
    {
      "name": "thanks",
      "confidence": 2.715441951295361e-07
    },
    {
      "name": "weather",
      "confidence": 2.5835913675109623e-07
    },
    {
      "name": "bot_challenge",
      "confidence": 4.761825422860966e-08
    }
  ],
  "response_selector": {
    "default": {
      "response": {
        "name": null,
        "confidence": 0.0
      },
      "ranking": [],
      "full_retrieval_intent": null
    }
  },
  "text": "weather in Noida"
}
Next message:
delhi weather
{
  "intent": {
    "name": "weather_for_location",
    "confidence": 0.9984486103057861
  },
  "entities": [
    {
      "entity": "location",
      "start": 0,
      "end": 5,
      "value": "delhi",
      "extractor": "DIETClassifier"
    }
  ],
  "intent_ranking": [
    {
      "name": "weather_for_location",
      "confidence": 0.9984486103057861
    },
    {
      "name": "weather",
      "confidence": 0.0012639579363167286
    },
    {
      "name": "thanks",
      "confidence": 9.82139608822763e-05
    },
    {
      "name": "goodbye",
      "confidence": 8.915668877307326e-05
    },
    {
      "name": "greet",
      "confidence": 6.841398135293275e-05
    },
    {
      "name": "city_info",
      "confidence": 2.7903372028958984e-05
    },
    {
      "name": "bot_challenge",
      "confidence": 3.7094062008691253e-06
    }
  ],
  "response_selector": {
    "default": {
      "response": {
        "name": null,
        "confidence": 0.0
      },
      "ranking": [],
      "full_retrieval_intent": null
    }
  },
  "text": "delhi weather"
}
Next message:
whats the weather
{
  "intent": {
    "name": "weather",
    "confidence": 0.9636867642402649
  },
  "entities": [],
  "intent_ranking": [
    {
      "name": "weather",
      "confidence": 0.9636867642402649
    },
    {
      "name": "weather_for_location",
      "confidence": 0.03303918614983559
    },
    {
      "name": "thanks",
      "confidence": 0.0017935443902388215
    },
    {
      "name": "goodbye",
      "confidence": 0.0011113830842077732
    },
    {
      "name": "bot_challenge",
      "confidence": 0.00020741281332448125
    },
    {
      "name": "greet",
      "confidence": 0.0001540367811685428
    },
    {
      "name": "city_info",
      "confidence": 7.643929166079033e-06
    }
  ],
  "response_selector": {
    "default": {
      "response": {
        "name": null,
        "confidence": 0.0
      },
      "ranking": [],
      "full_retrieval_intent": null
    }
  },
  "text": "whats the weather"
}
  • Como podemos notar, el modelo NLU entrenado anteriormente clasifica correctamente la intención con alta precisión. Ahora, ve al archivo endpoints.yml y agrega o quita el comentario de las siguientes líneas:
action_endpoint:
  url: "http://localhost:5055/webhook"
  • Ahora abra dos ventanas del símbolo del sistema. En una ventana, ejecute acciones con el siguiente comando:
rasa run actions

Y en otra ventana, ejecute rasa shell usando el siguiente comando:

rasa shell

  • También podemos visualizar el gráfico de secuencia de la conversación del bot:
rasa visualize

Referencias:

Publicación traducida automáticamente

Artículo escrito por pawangfg y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

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