Chatbot de RASA: experiencia de Parallels



La industria del chatbot está en auge. Al principio eran lo suficientemente estúpidos y podían mantener un diálogo con el usuario, liderando y ofreciendo posibles respuestas. Luego, los bots se volvieron un poco más inteligentes y comenzaron a exigir la entrada de texto del usuario para obtener palabras clave de las respuestas. El desarrollo del aprendizaje automático ha llevado a la aparición de la capacidad de comunicarse con el bot y la voz. Sin embargo, la mayoría de las soluciones no fueron muy lejos de la misma construcción del gráfico de diálogo y la transición entre sus nodos por palabras clave.

Recientemente, en Parallels, decidimos optimizar una serie de procesos internos y crear un bot para nuestras propias necesidades como experimento. Después de una breve búsqueda, decidimos probar suerte en el proyecto de código abierto RASA . Según los propios desarrolladores, crearon un bot de chat de tercera generación. Es decir, este bot no solo recorre el gráfico de estado, sino que puede guardar y usar el contexto del diálogo anterior. Hasta la fecha, la mejor ilustración para los bots de chat modernos se parece a esto:



Es decir, los bots de chat son solo un conjunto de reglas verificadas para moverse de un punto del gráfico a otro. Si observa las soluciones existentes de los gigantes del mercado, de hecho, no hay nada muy diferente del conjunto de reglas allí. En términos generales, este conjunto se parece a esto:

Diálogo en el punto XXX.
Si el usuario ingresó una oferta con las palabras ['comprar', 'boleto'], vaya al punto “PREGUNTE DÓNDE”
Si el usuario ingresó una oferta con las palabras ['comprar', 'chuleta'], vaya al punto “PREGUNTE DE QUÉ”

Es inmediatamente obvio que aquí hay basura, si el usuario ingresó: "Me gustaría comprar un boleto a Oporto", todavía le preguntarán: "¿A dónde quieres ir?" Para que el diálogo sea más humano, tendrá que agregar nuevas reglas sobre qué hacer si hay una indicación del lugar.
Luego agregue reglas sobre qué hacer si hay una indicación del lugar y la hora, y así sucesivamente.

Este conjunto de reglas crecerá lo suficientemente rápido, pero no es lo peor, todas las formas "correctas" se pueden describir, mejorar y lamer.

Lo más desagradable es que una persona es una criatura impredecible, a diferencia de un bot, y en cualquier momento puede comenzar a preguntar completamente diferente. Es decir, en el momento en que el bot ya está listo para reservar un boleto, una persona puede preguntar "por cierto, ¿qué pasa con el clima?" o "aunque no, me gustaría ir en mi automóvil, ¿cuánto tiempo dura el camino?"

Sin embargo, puede preguntar esto también en el momento después de elegir una ciudad, pero antes de elegir una hora de salida o incluso elegir un lugar al que quiera ir. El bot, basado en máquinas de estado, se atascará y sus seudópodos mecánicos se contraerán tristemente, y el usuario se sentirá frustrado.

Aquí puede (y debe) utilizar el aprendizaje automático. Pero luego surgen nuevos problemas: por ejemplo, si usa el entrenamiento de refuerzo para predecir las transiciones a los puntos del gráfico, surgen preguntas: ¿dónde obtener los datos para este entrenamiento y quién calificará la calidad de las respuestas?

Es poco probable que los usuarios acepten enseñarle a su bot y, como lo demuestra la práctica, una comunidad de usuarios puede enseñarle a un bot nada de lo que quiere y de lo que la sociedad considera decente. Además, el bot en la etapa inicial responderá completamente fuera de lugar, lo que hará que los usuarios estén nerviosos y, en principio, no se entrometan con tal soporte.

Después de analizar y pensar en todas las deficiencias de los bots existentes, los desarrolladores de RASA intentaron resolver los problemas de la siguiente manera:

  • Cualquier entrada del usuario pasa por la "determinación de intención", es decir, el texto ingresado mediante el aprendizaje automático se asigna a una (o varias) intenciones. Además, si es necesario, las entidades se aíslan del texto y se agregan a la memoria del bot.
  • Este proceso es similar a otros bots, con la excepción del modelo de determinación de intención utilizado.
  • La próxima acción del bot se predice utilizando el aprendizaje automático basado en el contexto, es decir, las acciones anteriores, las intenciones y el estado de la memoria del bot.
  • Al mismo tiempo, no se necesitan muchos datos para el entrenamiento inicial, y el bot puede predecir qué acción realizar incluso sin ejemplos y reglas específicas.

Considere los mecanismos de trabajo con más detalle.

RASA NLU


Comencemos con la primera ballena en la que descansa el bot. Esta es una comprensión del lenguaje natural, que consta de dos partes principales: determinación de intención y reconocimiento de entidades.

Detección de intenciones
La determinación de la intención se basa en un algoritmo modificado llamado StarSpace de Facebook, implementado en Tensorflow. En este caso, no se utilizan modelos pre-entrenados de representaciones vectoriales de palabras, lo que le permite sortear las limitaciones de estas representaciones.

Por ejemplo, determinar la intención en los algoritmos RASA funcionará bien para cualquier idioma, así como con cualquier palabra específica que especifique en los ejemplos de capacitación. Cuando se implementa a través de representaciones vectoriales pre-entrenadas como GloVe o word2vec, la localización del bot y su aplicación en áreas altamente especializadas traerá suficiente dolor de cabeza.

El algoritmo funciona sobre la base de la vectorización de oraciones a través de una bolsa de palabras y la comparación de su "similitud". Los ejemplos de intenciones y las intenciones mismas se convierten en vectores usando una bolsa de palabras y se alimentan a la entrada de las redes neuronales correspondientes. En la salida de la red neuronal, se obtiene un vector para este conjunto particular de palabras (la misma incrustación).

El entrenamiento se lleva a cabo de manera tal que se minimice la función de pérdida en forma de la suma de distancias por pares (ya sea coseno o productos vectoriales) entre dos vectores similares y k-diferentes. Por lo tanto, después del entrenamiento, se asociará un determinado vector con cada intención.

Al recibir la entrada del usuario, la propuesta se vectoriza de manera similar y se ejecuta a través del modelo capacitado. Después de eso, se calcula la distancia desde el vector resultante a todos los vectores de intención. El resultado se clasifica, destacando las intenciones más probables y cortando los valores negativos, es decir, completamente diferente.

Además de los bollos anteriores, este enfoque le permite distinguir automáticamente más de una intención de la propuesta. Por ejemplo: “sí, lo entendí. ¿Pero cómo puedo llegar a casa ahora? Reconocido como "intent_confirm + intent_how_to_drive", que le permite construir diálogos más humanos con el bot.

Por cierto, antes del entrenamiento, puede crear oraciones artificiales a partir de ejemplos mezclando los existentes para aumentar el número de ejemplos de entrenamiento.

Reconocimiento de entidad RASA


La segunda parte de la NLU es la extracción de entidades del texto. Por ejemplo, un usuario escribe: "Quiero ir a un restaurante chino con dos amigos", el bot debe resaltar no solo la intención, sino también los datos correspondientes. Es decir, llene su memoria de que los platos en el restaurante deben ser chinos y que el número de visitantes es tres.

Para esto, se utiliza un enfoque basado en campos aleatorios condicionales, que ya se describió en algún lugar del Habré , por lo que no lo repetiré. Aquellos que lo deseen pueden leer sobre este algoritmo en el sitio web de Stanford .

Además, noto que puede obtener entidades del texto basado en plantillas, textos (por ejemplo, nombres de ciudades), así como conectarse a un servicio separado de Facebook Duckling, del que también sería bueno escribir algún día.

Historias RASA


La segunda ballena azul en la que se basa RASA Core son las historias. La esencia general de las historias son ejemplos de conversaciones reales con el bot, formateadas como intención-reacción. Basado en estas historias, se entrena una red neuronal recurrente (LSTM), que asigna el historial de mensajes anterior a la acción deseada. Esto le permite no establecer gráficas de diálogos rígidamente, así como no determinar todos los posibles estados y transiciones entre ellos.

Con un número suficiente de ejemplos, la red pronosticará adecuadamente el siguiente estado para la transición, independientemente de la presencia de un ejemplo específico. Desafortunadamente, se desconoce el número exacto de historias para esto, y todo lo que puede guiarse es la frase de los desarrolladores: "cuanto más, mejor".

Para entrenar el sistema, no solo grabando algunos diálogos inventados allí, puedes usar entrenamiento interactivo.

Hay dos opciones:
1. Haga que varios ingenieros entablen conversaciones con el bot, corrigiendo predicciones incorrectas, definiciones incorrectas de entidades y enchufes con acciones de predicción en historias.

2. Guarde las conversaciones en la base de datos y luego continúe utilizando ingenieros especialmente capacitados para ver los diálogos en los que el usuario no pudo resolver su problema, es decir, cambió a una persona o el bot admitió su impotencia y no pudo responder.

Para comprender el mecanismo de las historias, es más fácil analizar algún ejemplo simple. Digamos una reserva de mesa en un restaurante, un ejemplo proporcionado por los desarrolladores en la sección de ejemplos de código fuente. Primero determinaremos nuestras intenciones y luego haremos un par de historias.

Intenciones y sus ejemplos:

Intento_hello
  • Hola
  • Hola
  • Aloha
  • Buenos dias

...
Intención_gracias
  • Gracias
  • Agradable
  • Gracias

...
Intent_request
  • Bye skip

Intención_informar
  • Bye skip

A continuación, debe crear la memoria del bot, es decir, determinar las ranuras en las que se registrará lo que el usuario requiera. Defina las ranuras:

cocina:
tipo: sin características
auto_fill: falso
num_people:
tipo: sin características
auto_fill: falso

Y ahora mostraremos ejemplos (una pequeña parte) de las intenciones omitidas anteriormente. Los corchetes en los ejemplos son los datos para entrenar a Ner_CRF, en el formato [entidad] (nombre de variable para almacenamiento: lo que almacenamos).

intent_request_restaurant
  • estoy buscando un restaurante
  • ¿Puedo obtener comida [sueca] (cocina) para [seis personas] (num_people: 6)
  • un restaurante que sirve comida [caribeña] (cocina)
  • Identificación como un restaurante
  • Estoy buscando un restaurante que sirve comida [mediterránea] (cocina)

intento_informar
  • [2] (num_people) personas
  • para [tres] (num_people: 3) personas
  • solo [una] (num_people: 1) persona
  • ¿Qué tal [asiático oriental] (cocina)
  • ¿Qué pasa con la comida [india] (cocina)
  • ¿Qué tal el tipo de comida [turca] (cocina)
  • um [inglés] (cocina)

Ahora determinamos la historia de la ruta principal:

* saludar
- utter_greet
* Intent_request
- restaurant_form
- formulario {"nombre": "restaurant_form"}
- formulario {"nombre": nulo}
- action_book_restaurant
* gracias
- utter_noworries

Ese es el bot perfecto para un mundo perfecto. Si el usuario indicó inmediatamente todos los datos necesarios en la primera oración, se reservará una tabla. Por ejemplo, escribe "Quiero reservar mesa en un restaurante español para cinco personas". En este caso, num_people será 5, y cocina - español, que es suficiente para el bot para otras acciones en la reserva.

Sin embargo, si observa los ejemplos, puede ver que los datos no siempre están presentes en la cantidad requerida y, a veces, no están en absoluto. Entonces aparecen los diálogos no centrales.

Supongamos que no hay datos sobre la cocina en la solicitud, es decir, algo así como este diálogo:
Hola
Hola
Quiero reservar restaurante para cinco personas.
...

Para que se complete correctamente, debe determinar el historial del siguiente formulario:
* saludar
- utter_greet
* Intent_request
- restaurant_form
- formulario {"nombre": "restaurant_form"}
- slot {"required_slot": "num_people"}
- utter_ask_coven
* formulario: informar {"cocina": "mexicano"}
- ranura {"cocina": "mexicano"}
- formulario: forma_restaurante
...

Y la mejor parte es que si crea historias para varias cocinas, entonces, al encontrarse con un desconocido, el bot predecirá la próxima acción por sí solo, aunque no será muy seguro. Al mismo tiempo, si crea una historia similar, pero donde se llena el espacio "cocina" y no el espacio "num_people", el bot no se preocupará en absoluto en qué orden se proporcionará la información sobre los parámetros de reserva de la mesa.

Hay dos formas de detener cualquier intento de llevar a un bot por el camino correcto: identificar posibles historias para hablar "sobre nada", o para todos los intentos de iniciar una conversación de este tipo, para responder que vale la pena volver al negocio.

Dado que nuestra compañía está al comienzo de un viaje increíble al mundo de los chatbots, existe la posibilidad de que haya nuevos artículos sobre qué rastrillo recolectamos y qué hicimos. Estén atentos!

Source: https://habr.com/ru/post/470754/


All Articles