[Из песочницы] Как Мефодий стал Анной: опыт разработки и запуска классификаторов голосовых сообщений. Часть 1

Цель и задача

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


Как Мефодий стал Анной. Серия №1

Начнём!

Меня зовут Юля, я инженер отдела машинного обучения крупного провайдера. К нам в call-центр за день поступает около 3000 звонков от клиентов. Каждый оператор принимает в среднем по 100 звонков в день. Ну и что? Казалось бы, что такого принять 100 звонков. Но тематик обращений в компании огромное множество, оператору нужно разбираться во всех продуктах, сервисах и процессах компании. Если взять самые типовые обращения клиентов, то их можно будет сгруппировать на 40(!) тем, а есть ещё не типовые обращения, которые тоже нужно уметь обрабатывать.
image

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

Идея хорошая, почему бы не сделать… простой IVR? (система предварительно записанных голосовых сообщений, маршрутизирует звонки внутри call-центра, используя информацию, вводимую клиентом на клавиатуре телефона с помощью тонального набора. wiki)

image

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

Мы мучать клиентов IVR-ом не захотели и поставили задачу — классифицировать запрос абонента по первой сказанной фразе. Таким образом, по озвученному запросу и будет происходить маршрутизация между операторами.


Данные

Операторы тех.поддержки по итогу каждого звонка выставляют тему обращения уже около 10 лет. Мы выделили самые многочисленные 16 групп, так и появилась из этих тем разметка. Далее выгрузили записи 120к разговоров на различные темы, распознали канал клиента с помощью Yandex.SpeechKit, при этом разделяли фразы по тишине.

Напомню, что у меня была цель классифицировать первоначальный запрос клиента, поэтому из каждого звонка отобрали только первую фразу. Итого, данные представляли собой 120к фраз клиента в текстовом формате с разметкой от операторов. Стандартная предобработка текста: удаление стоп-слов, нормализация текста, (фишечки: присоединение частицы «не» к следующему слову) и данные готовы. Более подробно о нашем pipeline предобработки расскажу в другой статье.


Классификация

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


Таблица со сравнением результатов экспериментов

Лучшее качество выдал стандартный набор TF-IDF и логистическая регрессия. В таблице представлена метрика f-score. В некоторых экспериментах помимо текста были добавлены дополнительные 11 признаков о клиенте (context) на момент звонка. В надежде, что это хоть как-то поднимет качество. Контекст — это булевые признаки, отрицательный ли сейчас у клиента баланс, назначен ли ремонт по адресу и другие, характеризующие клиента в текущий момент. Но даже с контекстом качество оставляет желать лучшего, удалось достичь лишь 72%.


Анализ ошибок

Без анализа ошибок качество классификации было не улучшить. Разобрав случаи, где ошибаются модели, выявили следующие типичные проблемы:


  • плохая разметка
  • дисбаланс классов
  • людям сложно сформулировать мысль
  • распознавание речи


Разметка

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


Баланс классов

Существует несколько подходов к балансировке классов.


Подробнее
  1. Under-sampling. Рандомное удаление примеров из больших классов.
  2. Over-sampling. Рандомное добавление примеров из минорных классов.
  3. Synthetic Minority Over-sampling. Рандомное добавление примеров из наименьших классов, но немного изменяя их.

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


Людям сложно формулировать мысли

Прочитав несколько первых фраз, мы заметили, что 36% запросов содержали неинформативный текст, например: «алло, здрасьте» или «алло, а у меня вопрос». Только после того, как оператор спрашивал: «какой у вас вопрос?», клиент формулировал проблему.

Таким образом, брать только первую фразу клиента из разговора неправильно, кто-то был просто не в состоянии сформулировать сходу запрос. Поэтому для каждой первой фразы была рассчитана «информативность». Если модель не отнесла запрос с высокой уверенностью ни к одному из классов, то есть все классы получили равное значение вероятности, значит сообщение неинформативно и нужно взять вторую фразу. А если класс и так уже определяется с высокой вероятностью, значит достаточно первой фразы.

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


Распознавание речи

При анализе ошибок, заметили некорректности в распознавании текста, из-за которых неправильно определялся класс. Например, слово «баланс» иногда заменялось на «банан». Решили сравнить распознавание от Яндекс и Гугл. Гугл показал себя лучше на наших данных, но не настолько, чтобы за него переплачивать, цена выше почти в два раза.


Сравнение распознавания речи двумя системами.

image


Итоги анализа ошибок

После анализа и исправления ошибок смогли улучшить качество до средней f-score в 84%, лучшее качество по прежнему выдавала логистическая регрессия.


Прирост качества по каждому классу


Выводы

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

Первым делом нужно разобраться с данными и разметкой. Не стоит сразу обучать нейронные сети, на некорректных данных большой пользы от этого не будет. Чтобы избежать потери времени и своих сил, достаточно проанализировать ошибки на «простых» моделях.

Увидимся во второй серии, где поговорим, как запустить в продуктив обученную модель. Послушаем примеры, как принимает звонки робот Мефодий, и разберёмся, почему он стал Анной.

© Habrahabr.ru