Я был очень активен в сообществе Rasa в течение последних 10 месяцев или около того и довольно много экспериментировал с Rasa Core. В то время как традиционные разработки чат-ботов в течение последних 2 лет были в значительной степени сосредоточены на том, чтобы заставить бот действительно понять, что вы имеете в виду, мало что было сделано с использованием подхода науки о данных к управлению разговором, который был и справедливо поэтому очень логически управляемой машиной до сих пор. бот понимает намерение пользователя X, машина должна выполнить Y. Однако разговоры в реальной жизни немного сложнее простой логики. Конечно, с точки зрения процесса эта логика верна, поскольку не имеет значения, идете ли вы в филиал или заполняете онлайн-форму, если вы хотите открыть банковский счет - процесс существует.

Какое значение имеет ядро ​​Rasa?

Думаю, я должен прояснить одну вещь - я не являюсь экспертом, когда дело доходит до понимания ядра Rasa, однако, учитывая время, которое я потратил на это, я буду делать вид, что у меня есть свой опыт в этом 😆

Итак, давайте поговорим о ценности

Подход науки о данных к управлению разговорами не изменит радикально существующий процесс - если вы хотите чертову пиццу, вы ДОЛЖНЫ сообщить чат-боту, какой тип базы, какие начинки вы хотите и куда вы хотите доставить.

Но давайте будем умными, всегда есть исключения, как в случае с пиццей - АЛЛЕРГИИ !! что-то неожиданное. Конечно, вы можете определить логику, но сколько такой логики вы собираетесь кодировать каждый день.

Имейте в виду, что ядро ​​Rasa не меняет ваш процесс, и машина не генерирует ответы, а просто позволяет вам лучше обрабатывать исключения. Ваши правила по-прежнему правят 📏

Разговор

Прежде чем мы начнем эксперимент о различных элементах, я хотел бы провести простую беседу. В конце концов, моей целью будет продемонстрировать внутреннюю работу ядра Rasa и то, как лучше всего использовать ядро ​​Rasa для конкретного разговора, который может вести ваш чат-бот. Основное внимание будет уделяться исключительно управлению диалогом, а вовсе не NLU (понимание естественного языка) - я предполагаю, что ваша машина прекрасно понимает естественный язык.

Хорошо, чтобы сделать правильное предположение, нам понадобится разговор, эквивалентный аналогичному состоянию приложения или человека.

Здесь мы начнем с бизнес-кейса, и, поскольку в прошлом я немного поработал с ресторанной индустрией и люблю готовить.

Давайте разберем завтрак !! 🥘

Мы сделаем чат-бота, который сможет принимать ваш заказ еды. Разговор ведется между пользователем, заказывающим вынос.

Давайте построим разные состояния

Как вы уже можете видеть, простой разговор о заказе уже довольно сложен, здесь я рассмотрел одно из исключений, когда данный элемент недоступен, бот может предложить некоторые альтернативы. Вы скоро узнаете, что таких альтернатив много, и что с ними делать.

Архитектура ядра Rasa

Просто здесь я опишу архитектуру того, как ядро ​​Rasa обучается и как ядро ​​Rasa анализирует конкретный входящий текст. Опять же, предполагается, что уже существует реализация NLU, поскольку для ядра Rasa на самом деле полезными являются функции для прогнозирования следующего шага в разговоре, который является не естественным текстом, а скорее намерением входящего текста.

Тренировочный процесс

Давайте проанализируем каждый шаг, чтобы увидеть, что на самом деле происходит с каждым из них. Имейте в виду, что каждый из этих компонентов четко определен в основной документации Rasa - https://rasa.com/docs/core/

Я просто представляю каждый из них через свое собственное мнение, чтобы убедиться, что, когда я буду экспериментировать с приведенным выше бизнес-кейсом, эти слова связаны

  • Тренировочные данные - это, по сути, все истории, в которых вы обычно определяете, что является нормальным разговором для вашего процесса, вы определяете это в определенном формате ядра rasa. Вы найдете информацию о формате здесь - https://rasa.com/docs/core/stories/
    Если вы проверите ссылку - вы найдете некоторые важные элементы там в историях
    Давайте возьмем пример и посмотрим на каждого из них
## story_07715946 <! — name of the story — just for debugging 
* greet ( Intent of the user)
 — action_ask_howcanhelp ( What the bot should do)
* inform{“location”: “rome”, “price”: “cheap”} <! — user utterance, in format intent{entities} → Next step of the conversation
 — action_on_it
 — action_ask_cuisine
* inform{“cuisine”: “spanish”}
 — action_ask_numpeople <! — action that the bot should execute 
* inform{“people”: “six”}
 — action_ack_dosearch
  • Домен - это сердце чат-бота. Домен в основном определяет, что должен понимать ваш чат-бот, что он может делать и какая информация необходима для контекста вашего чат-бота, чтобы он лучше понимал пользователя. Подробнее о формате домена здесь: https://rasa.com/docs/core/domains/
  • Загрузить агент - я хотел начать с первой загрузки агента здесь, прежде чем объяснять загрузку данных, потому что агент (или бот) сначала загружается с некоторыми параметрами, которые определяют, как данные обучения будут преобразованы в функции. для обучения агента. Один действительно важный параметр -
    - Политика (поясняется ниже).
  • Политика - это основная архитектура модели бота. Политика определяет, что будет следующим действием. Поскольку ядро ​​Rasa имеет открытый исходный код, вы действительно можете создать свою собственную политику, но давайте разберемся с основами и посмотрим, какие из уже доступных политик используются по умолчанию. У вас будет дополнительная информация здесь - https://rasa.com/docs/core/policies/
    - Политика запоминания - Хотя название действительно звучит что-то, что вышло прямо из исследовательской работы, основная идея этой политики или, скажем, алгоритма состоит в том, чтобы скопировать ваши тренировочные данные и запомнить их наизусть, а затем предсказать следующее действие. Здесь прогноз является двоичным, если беседа соответствует одной из историй в ваших обучающих данных, то следующее действие будет иметь достоверность 1, если нет, то достоверность равна 0. Однако, как в разговоре, это совпадение необходимо. проверка будет зависеть от Max History (упомянутого ниже). Примечание. Существует также AugmentedMemoizationPolicy - вы можете использовать ее вместо этого, если у вас нет слотов, установленных в прогнозировании, но они присутствуют в ваших обучающих данных, в основном это помогает для Политика мемоизации, чтобы игнорировать слоты в трекере для рассмотрения решения
    - Политика Keras -. Одна из моделей машинного обучения - это рекуррентная нейронная сеть (LSTM), которая использует множество функций, чтобы предсказать следующее возможное действие. Мы узнаем об особенностях ниже.
    - Резервная политика -. Это простая функциональная логика, которая принимает три параметра
    Порог NLU, Порог ядра и резервное действие. Если порог NLU ниже заданного процента, будет вызвано резервное действие. Однако, если пороговое значение NLU в порядке, но данное намерение отсутствует в домене, оно вызовет резервное действие.
    Базовый порог - это второй резервный вариант, когда бот очень хорошо понимает намерение, но не уверен в прогнозируемом действии, и он ниже основного порога, тогда вызывается резервное действие.
  • Featurization - Я не буду здесь много объяснять, поскольку featurizer довольно хорошо задокументирован в документации rasa core: «https://rasa.com/docs/core/api/featurizer/ женщина
    Основная идея для любой модели, специально предназначенной для нейронной сети, заключается в том, что сеть должна быть снабжена набором функций, которые определяют следующее действие в разговоре, эти функции обычно являются векторным представлением разговора, поэтому политика Keras например - каждое состояние разговора будет содержать набор функций, таких как намерения, сущности, слоты и предыдущие действия. Общее количество состояний, для которых определяется каждая функция, затем передается в сеть, которая прогнозирует метку (одно из ваших действий в списке). Мой совет очень хорошо читал об SingleStateFeaturizer.
  • Параметры - Чтобы снабдить политики множеством функций диалога, существует один гиперпараметр, который играет действительно важную роль: max_history
    - MaxHistory - max_history в основном предоставляет SingleStateFeaturizer значение, которое определяет количество наборов функций, которые необходимо передать в нейронную сеть. Это также полезно для генерации историй, о которой мы поговорим ниже. Чтобы сеть могла выдавать выходные данные, нам необходимо выяснить, на сколько в прошлом разговора политика должна оглянуться назад, чтобы определить, что делать дальше в разговоре. По умолчанию для Max History установлено значение 5, поэтому допустим, что для политики Memoization, которая использует SingleStateFeaturizer с max_hisory, равным 5, будет выполняться 5 шагов назад в вашем трекере, чтобы определить, совпадает ли следующий шаг с какими-либо историями в ваших тренировочных данных. Точно так же для политики Keras максимальная история также увеличивает общее количество функций, которые управляют разговором.
  • Примечание. Еще одна важная функция - слоты - вы можете прочитать об этом здесь: https://rasa.com/docs/core/ слоты /
    В этом разделе не так много подробностей. Просто помните, в отличие от параметра максимальной истории, слоты обычно не затрагиваются на протяжении всей истории разговора, и слоты могут переводить разговор из состояния A в состояние B. Важно тщательно оценить тип слота, который вы хотите, поскольку они имеют особенности иначе. Больше информации в документации Rasa.
  • Загрузить данные - Когда у вас есть домен и тренировочные данные в формате Rasa Core, пора загружать данные, есть еще несколько параметров, которые важны в этом случае.
    - Коэффициент увеличения. Этот параметр после загрузки историй начнет случайным образом склеивать истории для создания более длинных историй. Если вы хотите, чтобы ваши тренировочные данные не увеличивались, вы можете пропустить это, установив для него значение 0 после тренировки. По умолчанию это 20.
  • Обучение - политики работают в ансамбле, то есть вы можете передать агенту несколько политик - по умолчанию политики Memoization и Keras используются для процесса обучения, каждая из них обучается отдельно, однако они используются. вместе в ансамбле, чтобы предсказать следующее действие, и только один побеждает в битве. Подробнее об этом позже.
  • Сохранение - после обучения модели она сохраняется в файловой системе или облачном хранилище по вашему выбору.

Прогнозирование процесса

После того, как у вас будет обученная модель, давайте углубимся в то, как делается прогноз.

Загрузить модель. Начнем с загрузки модели в память перед обслуживанием с использованием сервера (Flask) и выставлением конечной точки, связанной с определенным каналом, в нашем случае мы будем иметь дело с REST API.

Интерпретатор - Как я объяснял ранее, предполагается, что у нас есть работающий интерпретатор, который может читать исходный текст, поступающий от пользователя, и выдавать намерение пользователя вместе с некоторыми значимыми объектами, эти сущности, которые мы сохраняем как слоты, которые будут вести разговор.

CreateOrUpdate Tracker - Если это первое сообщение беседы, ядро ​​rasa создаст объект трекера с ключом - sender_id, который является входящим идентификатором пользователя, убедитесь, что этот идентификатор уникален для одного пользователя. в противном случае прогноз может быть некорректным для конкретного человека.
Объект трекера обычно содержит то, что обнаружил интерпретатор и / или есть ли новые слоты, которые устанавливаются с помощью вызова API, например день рождения пользователя. Объект трекера обычно хранится в tracker_store, который по умолчанию находится в InMemory, однако после индустриализации вы хотели бы масштабировать свой API, и важно, чтобы tracker_store был привязан к MongoTrackerStore или RedisTrackerStore. Вы можете проверить мой другой учебник, поскольку я создал RedisTrackerStore для многоязычного чат-бота. В этом эксперименте, поскольку я не занимаюсь промышленным развитием чат-бота, я буду использовать InMemoryTracker.

Функции. После того, как у вас есть объект отслеживания, вам теперь нужно будет определить, что присутствует в трекере, на основе политики, которую мы установили при обучении, и необходимых параметров, таких как max_history, после того, как эти функции будут сгенерированный, он будет передан ансамблю политик, который определит окончательный результат.

PolicyEnsemble - поскольку мы обучили разные политики, когда дело доходит до прогнозирования следующего действия, каждая из этих политик дает оценку для конкретного действия. Затем из всех оценок, выставленных каждой политикой, берется максимум, и в зависимости от того, какая победа, будет следующим действием.

Обновить трекер. После того, как вы спрогнозируете действие, вам нужно будет обновить трекер для следующего хода.

ExecuteAction - теперь вы, наконец, выполняете свое действие, будь то вызов API или сообщение, отправленное обратно пользователю.

Уф !! так много информации, я надеюсь, что это поможет прояснить основы ядра Rasa. В Части 2 мы применим эту концепцию к вышеупомянутому разговору, используя различные варианты политик, и посмотрим, как они отреагируют.