Примечание. Этот блог был впервые опубликован в записи блога Freshworks.
Введение
Прогнозирование тональности электронной почты — хорошо известная проблема машинного обучения. Но создание ценности для бизнеса из электронных писем требует большего внимания к разработке данных и развертыванию модели в контексте продукта, для которого она будет использоваться. В этом блоге мы делимся нашим подходом к различным этапам развертывания модели машинного обучения в производственной среде. Ниже приводится список затронутых тем.
- Моделирование постановки задачи
- Исследовательский анализ данных
- Предварительная обработка функций
- Обучение модели
- Развертывание модели
- Возможности для дальнейшего улучшения
Моделирование постановки задачи
Основными пользователями Freshsales являются торговые агенты. Чтобы представить продукт, они обращаются к контактному лицу других предприятий и спрашивают об их требованиях, связанных с их продуктом, просят их назначить встречу для демонстрации и т. д.
Эти контакты, которые являются потенциальными клиентами, затем идут и изучают продукт, собирают требования и отвечают своими выводами. Эти разговоры становятся мощным сигналом в определении направления, в котором движется сделка. Это может помочь нам предсказать шансы на выигрыш или проигрыш сделки.
Таким образом, наша постановка задачи для бизнеса состоит в том, чтобы предсказать вероятность выигрыша или проигрыша сделки на основе переписки по электронной почте между агентами и контактными лицами.
Перевод постановки задачи для модели ML
Чтобы смоделировать это, нам нужно понять следующие сущности: агент, контакт, сделка и беседа по электронной почте.
Что происходит на стороне бизнеса
«Агент» узнает о компании ABC Corp и адресе электронной почты ее отдела кадров. Они добавляют эту информацию как «Контакт» на Freshsales (контакт3).
Затем агент создает «Сделку» (deal3) на Freshsales и связывает контакт3 с сделкой3.
После создания сделки и связывания ее с контактом они отправляют электронное письмо от Freshsales или любого другого почтового клиента с просьбой показать демонстрацию. contact3 видит электронное письмо и после нескольких разговоров решает приобрести план.
Затем агент отмечает сделку как выигранную в своей учетной записи Freshsales.
Что происходит на бэкенде
contact3 добавляется в таблицу contacts со своим адресом электронной почты.
Сделка3 создается в таблице deals с текущим состоянием — Открыто.
Наряду с этим таблица contact-deal-association регистрирует сделку3 как связанную с контактом3.
Затем при обмене электронными письмами они регистрируются в таблице email-беседы для Контакта, а не для Сделки.
Когда сделка закрывается, ее состояние меняется с Open на Won.
Теперь, когда мы развили понимание этого процесса, давайте попробуем определить цель наших моделей машинного обучения.
Мы обучили две модели. Первая модель (модель L1) предсказывает тональность одного электронного письма. Вторая модель (модель L2) берет настроения из серии электронных писем и прогнозирует вероятность выигрыша сделки.
Как получить размеченные данные для обучения
Прямого сопоставления между разговорами и соответствующей сделкой нет, но мы можем связать их, объединив разговор по электронной почте с таблицей contact-deal-association.
Наконец, у нас есть результат для закрытых сделок, выигранный или проигранный, который становится нашим ярлыком.
В следующей таблице представлены данные:

Исследовательский анализ данных (EDA)
Язык
Чтобы решить, нужна ли нам многоязычная языковая модель, мы попытались понять распределение языков по учетным записям. Для каждого письма мы получаем вероятности для топового языка с помощью модуля langdetect. И для каждого языка мы берем средние вероятности по всем письмам, сгруппированным по учетным записям.
- Из 1166 учетных записей 359 учетных записей имеют вероятность владения английским языком менее 0,9.
- На эти учетные записи приходится 20% электронных писем и 25% сделок.
- Распределение языков в этих 359 учетных записях показано на следующем графике.
Этот анализ показывает, что предпочтение следует отдавать многоязычной модели.
Длина предложений
В следующей таблице показано, как выглядят некоторые из этих писем:

Какой должна быть максимальная длина токенов для обучения модели? Для этого мы смотрим на некоторые статистические данные о количестве слов в электронных письмах.
90% предложений содержат менее 170 слов, а 95% — менее 300 слов.
После удаления 5% выбросов среднее количество слов равно 54. Вся статистика для обоих классов одинакова.
Очистка данных, предварительная обработка признаков, разработка признаков
Винрейт аккаунта — это отношение выигранных сделок к общему количеству сделок. Мы удалили данные с аккаунтов, у которых винрейт > 0,9 или винрейт ‹ 0,1
Мы удалили электронные письма, содержащие менее 4 слов. Большинство из них состоят из таких слов, как «одобрено», «хорошо, спасибо» и т. д.
Каждая сделка должна иметь хотя бы 1 электронное письмо от клиента. И для каждой сделки мы рассматриваем электронные письма только до последнего электронного письма клиента. Поскольку электронные письма от агентов обычно звучат более позитивно, мы обнаружили, что включение всех электронных писем агентов позволяет прогнозировать более высокую вероятность выигрыша сделки. Следовательно, электронные письма от агента после последнего электронного письма клиента не учитываются.
Чтобы очистить текст электронной почты, мы используем внутренний модуль на основе bert, который идентифицирует части электронных писем, содержащие подписи, приветствия и тексты отказа от ответственности, и удаляет их из электронной почты.
Мы добавили токен, обозначающий отправителя электронного письма: __cust__, если отправитель является клиентом, и __agent__, если оно от агента. Все электронные письма предваряются соответствующим токеном.
Мы также попытались добавить идентификатор учетной записи перед текстом, предполагая, что модель научится предсказывать настроение, принимая во внимание идентификатор в контексте. Но этот эксперимент не дал большого улучшения в счете.
Обучение модели
Для обучения модели настроений на уровне разговора мы использовали API Trainer. Это позволило нам легко экспериментировать с различными предварительно обученными моделями NLP, настраивать tensorboard для мониторинга и Mlflow для регистрации параметров и метрик. Мы извлекли выгоду из других функций, таких как сохранение контрольных точек, выполнение оценки после определенного количества шагов и ранняя остановка.
Самое главное, мы использовали обучение с несколькими графическими процессорами, которое обрабатывается API. Он использует параллелизм данных внутри.
Для первоначальной настройки мы сначала начали с обучения distilbert-base-uncased только для англоязычных учетных записей. Затем мы обучили модель, которая могла дать хорошие результаты и для других языков. Для этого мы поэкспериментировали с xlm-roberta и distilbert-base-multilingual-case, взяв последние 5 электронных писем агента и последних 5 клиентов для всех сделок. Мы обнаружили, что xlm-roberta дает немного лучшие результаты, поэтому, наконец, мы обучили его, используя последние 20 агентов и последние 20 электронных писем клиентов.
Для обучения мы использовали инстанс p3.8xlarge с 4 графическими процессорами Tesla V100. При длине последовательности 128 и размере пакета на устройство 128 мы тренировались в течение 6 эпох, что заняло 7,5 часов на наборе данных из 1,05 млн разговоров.
После того, как мы обучили модель уровня разговора, нам нужно было обучить другую модель, используя предсказанные значения тональности серии разговоров, чтобы предсказать вероятность выигрыша сделки. Однако использование одного и того же набора данных для обучения обеих моделей приведет к переобучению второй модели. Чтобы избежать этой проблемы, мы обучали первую модель 5 раз, каждый раз удерживая 20% данных.
- Рассмотрим набор данных из 10 идентификаторов разговоров. Чтобы получить оценки для идентификаторов 0 и 1, исключите их при обучении первой модели. Чтобы получить оценки для конв. 2 и 3, снова обучите первую модель, но исключите эти идентификаторы.
- training_ids: [2, 3, 4, 5, 6, 7, 8, 9] val_ids: [0, 1]
- training_ids: [0, 1, 4, 5, 6, 7, 8, 9] val_ids: [2, 3]
- training_ids: [0, 1, 2, 3, 6, 7, 8, 9] val_ids: [4, 5]
- training_ids: [0, 1, 2, 3, 4, 5, 8, 9] val_ids: [6, 7]
- training_ids: [0, 1, 2, 3, 4, 5, 6, 7] val_ids: [8, 9]
Теперь используйте предсказанные оценки этих val_ids для обучения второй модели.
Вторая модель — это модель XGBooost. Мы берем массив последних 5 оценок тональности электронных писем агента и последних 5 оценок тональности электронных писем клиентов. В следующей таблице представлены данные:

Метрики
- Модель L1 (xlm-roberta): AUC — 0,72, точность: 0,67
- Модель L2 (XGBooost): AUC — 0,84, точность: 0,77
Развертывание модели
Мы использовали оптимизацию onnx, чтобы уменьшить задержку модели L1. На диаграмме показано улучшение времени вывода с оптимизацией onnx и без нее. AUC квантованной + оптимизированной модели onnx составила 0,8393, что является очень номинальной разницей.
Пропускная способность (показатель того, сколько единиц информации система может обработать за заданный промежуток времени) развернутой модели составляет приблизительно 53 запроса в секунду.
Упомянутая выше модель xlm-roberta и модель Xgboost развертываются с помощью Sagemaker. Мы получаем электронные письма от полезной нагрузки через поток kafka, а потребитель отправляет запросы на конечную точку Sagemaker.
Возможности для дальнейшего улучшения
Электронные письма, такие как ответы об отсутствии на работе и приглашения на встречи, не наводят на мысль о настроении. Мы планируем удалить такие письма в следующей версии.
Наши коллеги Шриватса Наримха и Четан Бхат разработали архитектуру под названием CAPE-NET для классификации потоков электронной почты, которую можно изучить для нашего варианта использования.
Для модели L2 мы просто использовали последние 5 оценок настроений агентов и клиентов. Мы планируем поэкспериментировать с расстановкой партитур и использовать еще некоторые возможности.