Чат-боты и я

Я был одним из первых, кто применил технологию чат-ботов. Я создавал чат-ботов последние два года, используя платформы НЛП, такие как Microsoft LUIS, Dialogflow, wit.ai и т.д. через Rasa, и на его основе Мы создали чат-бота и провели семинар на PyDelhi Conference 2017.

НЛП и я

В этом году я хотел отточить свои навыки машинного обучения и сузил круг своих интересов только до НЛП. После раунда токенизации, тегирования POS, моделирования тем и классификации текста пришло время собрать все это воедино в рамках чат-бота, но я понятия не имел, как это сделать.

Это было примерно в то же время, когда Rasa прислал мне свой информационный бюллетень с призывом к первым PR. Я раздвоил репо, настроил среду и немного поигрался с ней.

Примерно через неделю эксперт по машинному обучению Сирадж Раваль объявил о вызове 100DaysOfMLCode, который поднял мой энтузиазм на новый уровень, и я захотел сделать это наверняка. Я решил посвятить все 100 дней тому, чтобы сосредоточиться только на НЛП, начиная с чтения и понимания кодовой базы Rasa NLU.

Прежде, чем ты прыгнешь

Этот блог предназначен для тех, кто хочет понять концепции машинного обучения, лежащие в основе технологий чат-ботов. Если вы новичок в использовании чат-ботов и НЛП, я настоятельно рекомендую вам пройти по следующим ссылкам, понять основы и создать чат-бота с помощью RasaNLU, прежде чем углубляться.

  1. Что такое, почему и как работает чат-бот
  2. Создание чат-бота с использованием RasaNLU

Заявление об ограничении ответственности:

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

RasaNLU построен с использованием python. Было бы лучше, если бы у вас были базовые знания Python, чтобы понимать фрагменты кода.

Считывание кода - отправная точка

Отправную точку любого репозитория можно найти, просмотрев его документацию. Это будет первый файл, который вы импортируете из пакета, или файл, который вы выбрали из командной строки.

РасаНЛУ имеет две точки входа - Поезд и Сервер.

  1. Обучающая часть генерирует модель машинного обучения, когда вы вводите обучающие данные - train.py.
$ python -m rasa_nlu.train \
    --config sample_configs/config_spacy.yml \
    --data data/examples/rasa/demo-rasa.json \
    --path projects

2. В части server сгенерированная модель машинного обучения обслуживается через API.

$ python -m rasa_nlu.server --path projects

Поскольку server.py нужна модель, созданная train.py, давайте начнем с обучающей части.

Обучение

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

1. Конфигурация

На этом этапе аргументы командной строки, передаваемые в train.py файл, анализируются и загружаются в объект конфигурации cfg. Конфигурация обучения определяется config_spacy.yml. Он содержит два основных языка информации о вашем боте и используемую библиотеку NLP.

> cat config_spacy.yml
language: "en"
pipeline: "spacy_sklearn"

Объект cfg также содержит путь к вашим обучающим данным и путь для хранения моделей после завершения обучения.

2. Загрузка данных обучения

С RasaNLU вы можете считывать данные обучения с вашего локального компьютера или внешнего API. Это удобно, когда вы хотите получить данные из уже существующей базы данных. В этом случае вам нужно написать api, который генерирует данные в формате, совместимом с форматом данных обучения Rasa. Для этого вам нужно написать слой поверх вашей базы данных.

Функция load_data считывает данные из соответствующих путей и возвращает объект TrainingData.

{
  "text": "show me chinese restaurants",
  "intent": "restaurant_search",
  "entities": [
    {
      "start": 8,
      "end": 15,
      "value": "chinese",
      "entity": "cuisine",
      "extractor": "ner_crf",
      "confidence": 0.854,
      "processors": []
    }
  ]
}

3. Обучение модели машинного обучения

На этом этапе загруженный TrainingData передается в NLP pipeline и преобразуется в модель машинного обучения. Трубопровод Aspacy выглядит примерно так, как на изображении.

Первым шагом является создание объекта Trainer, который принимает параметр конфигурации cfg и строит pipeline. конвейер, состоящий из components. Каждый component отвечает за определенную операцию NLP.

Функция Trainer.train выполняет итерацию по конвейеру и выполняет задачу НЛП, определенную компонентом. Вы можете думать о train функции как о контроллере, который управляет различными компонентами в конвейере и обновляет контекст вывода или информации, полученной из каждого компонента.

context = {}
for i, component in enumerate(self.pipeline):
    updates = component.train(working_data, self.config,**context)
    if updates:
        context.update(updates)

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

  1. Этап предварительной обработки - где данные преобразуются для извлечения необходимой информации.
  2. Средство извлечения сущностей и классификатор намерений - Предварительно обработанные данные используются для создания моделей машинного обучения, которые выполняют классификацию намерений и извлечение сущностей.
  3. Стойкость - Сохранение результата

Предварительная обработка

3.1 SpacyNLP

Чтобы использовать spacy, нам нужно создать объект NLP spacy в зависимости от языка, указанного в файле конфигурации. Если spacy не поддерживает указанный язык, возникает ошибка.

>>> import spacy
>>> nlp = spacy.load('en')

3.2 SpacyTokenizer

На этом этапе каждая обучающая выборка из вашего обучающего файла преобразуется в список токенов (слов). В конце этого шага у нас есть bag of words.

>>> tokens = nlp("Suggest me a chinese food")
["suggest", "Me", "a", "chinese", "food"]

3.3 SpacyFeaturizer

Теперь, когда у нас есть набор слов, мы можем скормить их алгоритмам машинного обучения. Однако алгоритм машинного обучения понимает только числовые данные. Работа featurizer - преобразовывать лексемы в векторы слов. В конце этого шага у нас будет список чисел, который будет иметь смысл только для моделей машинного обучения. Токен Spacy поставляется с векторным атрибутом, который упрощает преобразование.

>>> features = [token.vector for token in tokens]
[ 1.77235818e+00  2.89104319e+00  1.34855950e+00  4.57144260e-01
 -1.24784541e+00  3.25931263e+00 -6.40985250e-01 -1.46328235e+00
 -5.12969136e-01 -2.17798877e+00 -3.69897425e-01  4.26086336e-01...

3.4 RegexFeaturizer

RasaNLU поддерживает регулярное выражение в обучающих примерах, например, в случае захвата таких объектов, как почтовый индекс, номер мобильного телефона и т. Д. В таком случае RegexFeaturizer ищет шаблоны регулярных выражений в TrainingExamples и отмечает 1.0, если токен соответствует шаблону else 0. Этот шаг не требует простора, поскольку функциональность специфична для Rasa.

found = []
for i, exp in enumerate(self.known_patterns):
    match = re.search(exp["pattern"], message.text)
    if <match_in_token>:    
        found.append(1.0)
    else:
        found.append(0.0)

Извлечение сущности

3.5 NER_CRF EntityExactor

NER_CRF - один из известных алгоритмов, используемых для извлечения именованных сущностей. NER означает Распознавание именованных сущностей, а CRF - это условные случайные поля, которые управляют всей статистикой извлечения сущностей.

"entities": [
    {
      "start": 8,
      "end": 15,
      "value": "chinese",
      "entity": "cuisine",
      "extractor": "ner_crf",
      "confidence": 0.854,
      "processors": []
    }

Параметр extractor в обучающих данных позволяет вам выбирать между extractors, поддерживаемым Rasa, а параметр preprocessor определяет список операций, которые должны быть выполнены перед NER. Документация РасаНЛУ объясняет список различных экстракторов и варианты их использования.

Приведенный выше пример объекта проходит серию преобразований перед подачей в алгоритм CRF. В конце обучения генерируется модель CRF ML, обученная на выборках сущностей.

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

  1. https://spacy.io/usage/training#annotations
  2. Https://nlu.rasa.com/entities.html?highlight=extractor

3.6 EntitySynonymMapper

EntitySynonymMapper создает сопоставление между сущностью и ее синонимами, предоставленными обучающим файлом. Созданный вами чат-бот должен понимать все варианты сущности. Этот картограф обрабатывает различные варианты одного объекта.

# Input -> Training_data.json
"entity_synonyms": [
      {
        "value": "vegetarian",
        "synonyms": ["veg", "vegg", "veggie"]
      }
# Output -> entity_synonym.json
{'veggie': 'vegetarian', 'vegg': 'vegetarian'}

Классификация намерений

3.7 SklearnIntentClassifier

Этот классификатор использует sklearn SVC with GridSearch с intent_names в качестве меток после LabelEncoding и text_features, сгенерированные функцией featurizer в качестве данных для создания модели машинного обучения.

# training data
>>> X_train = 
[ 1.77235818e+00  2.89104319e+00  1.34855950e+00 4.57144260e-01 -1.24784541e+00  3.25931263e+00 -6.40985250e-01 -1.46328235e+00...
# features
>>> Y = ["greet", "bye", "restaurant_search", "greet"...
>>> Y_train = LabelEncoder().fit_transform(Y)
>>> Y_train
[0, 1, 2 ,0...
# training the ML model
>>> clf = GridSearchCV(SVC(...))
>>> clf.train(X_train, Y_train)

4. Сохранение модели в постоянном пути

Rasa позволяет хранить данные в облачном хранилище, таком как AWS, GCS или Microsoft Azure, или в вашей локальной системе. Параметр persisted_path определяет эту конфигурацию для вас и сохраняет обученную модель в соответствующей позиции. Конечный результат после обучения всех компонентов конвейера - это объект Intepreter, который генерирует и сохраняет следующие файлы, которые позже используются на этапе serve.

crf_model.pkl
entity_synonyms.json
intent_classifier_sklearn.pkl
regex_featurizer.json
training_data.json
model_metadata.json

Была ли эта публикация вам полезна?
Удерживая кнопку хлопка, крикни мне в твиттере. ❤️

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