Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Привет, Хабр! На связи Денис Киров, руководитель отдела тестирования "дочки" ДОМ.РФ, компании «Цифровые технологии» и Дмитрий Сичкар, главный инженер по нагрузочному тестированию. Но расскажем мы сегодня не про тестирование программных продуктов, а про контроль качества работы компании в целом.
Корпорации борются за улучшение эффективности и качества работы сотрудников, а для того чтобы проверить, эффективна ли какая-либо внедренная методология, нужен числовой коэффициент. Сейчас мы рассматриваем такую метрику эффективности, как удовлетворенность бизнес-заказчика. Для замера подобного показателя чаще всего используется NPS (Net Promoter Score) – индекс потребительской лояльности, проще говоря, обратная связь. Сбор данной метрики в ручном режиме мы внедряем, собирая обратную связь от заказчика с точки зрения удовлетворенности работы команд, конкретных сотрудников, взаимодействующих с заказчиком напрямую, и это интересная и полезная статистика, которую можно анализировать и на основании нее принимать какие-либо управленческие решения. Но мы захотели попробовать автоматизировать сбор этого показателя.
Обсуждение идеи, анализ и планирование реализации MVP
Первый вопрос, которым мы озадачились: что вообще мы будем оценивать, откуда брать данные? Мы поняли, что чаще всего существенные успехи и явный негатив подсвечивается в чатах с бизнес-заказчиком. Для теста решили посмотреть основной и самый многолюдный чат в мессенджере «Телеграм», где есть все сотрудники со стороны заказчика, которые взаимодействуют с нами, и там, действительно, подсвечиваются все успехи, например, успешный и долгожданный релиз, а также все негативные моменты, например, когда что-то работает не в соответствии с ожиданиями, либо сроки нарушены.
После того, как мы определились, откуда мы берем информацию мы смогли более четко сформулировать поставленную задачу – нам необходимо проводить семантический анализ сообщений в бизнес – чатах и классифицировать его. Задача классификации – хорошо автоматизируемая вещь при помощи алгоритмов машинного обучения.
Далее пришло время проанализировать технологический стэк, выбрать необходимые инструменты и библиотеки, продумать архитектуру решения.
Система должна состоять из нескольких модулей, каждый из которых решает свою задачу и взаимодействует между собой:
Модуль сбора сообщений из Телеграм-чатов
Хранилище данных, куда кладутся сообщения
Модуль предобработки данных
Модуль с обученной ML-моделью
Хранилище данных с результатами
Визуализатор результатов
Далее нам нужно было определиться с технологическим стэком:
Поскольку мы решаем задачу анализа данных и классификации, то язык программирования был выбран Python 3,
Для взаимодействия с Телеграмом – библиотека telebot,
В качестве первого хранилища данных – встраиваемая БД SqlLite,
Для работы с данными – библиотеки numpy и pandas, а также библиотеки непосредственно для работы с текстом – NLTK, pymorphy3,
Sklearn – библиотека машинного обучения, которая включает в себя все основные методы ML,
Influxdb – noSQL хранилище данных, которое мы будем использовать для хранения полученных результатов,
Grafana – всеми любимый «визуализатор» данных, там мы подготовим дашборд с результатами.
На рисунке ниже изображена схема системы в общем виде:
Реализация MVP проекта
После того, как задача была проанализирована, и технологический стек определен, мы приступили непосредственно к реализации MVP.
Модуль парсинга
Для MVP мы решили не использовать реальный бизнес-чат, а создали отдельный, в который добавили бота, созданного через bot_father.
Вынесли в конфигурационный файл токен для бота, реализовали парсинг интересующих параметров и запись их в БД.
Также настроили работу парсера в режиме реального времени.
Поскольку в бизнес-чатах есть пользователи, чьи сообщения анализировать не надо (все, кроме основных бизнес – заказчиков), мы реализовали отдельный конфигурационный файл, куда вносятся идентификаторы пользователей, чьи сообщения идут в систему, остальные отсекаются.
Информация, которую мы сохраняем:
идентификатор чата,
заголовок чата,
дата и время получения сообщения,
текст сообщения.
Далее нам было необходимо собрать наборы данных для обучения модели, для этого мы решили использовать ранее разработанный первый модуль и заодно его протестировать.
Мы стали пересылать в данный чат сообщения с последующей разметкой данных на «позитивные» и «негативные».
Пример негативного сообщения:
Пример позитивного сообщения:
Сбор датасета сразу показал две проблемы, которые мы не сразу учли: это эмодзи в сообщениях и картинки / стикеры. Парсер не может обрабатывать такие сообщения, и, чтобы не терять данные, мы вынесли часть предобработки в модуль парсера, а именно удаление эмодзи, стикеров и картинок из получаемых сообщений:
Модуль предобработки данных
Данный модуль является очень важным, так как от качества обработки данных зависит точность классификации. Вот, что мы реализовали в данном модуле:
Реализация словаря стоп-слов – это те слова, которые не влияют на эмоциональный окрас текста, от них очищается полученное сообщение,
Очистка текста от знаков препинания,
Приведение текста к нижнему регистру,
Перевод всех слов в инфинитив (леммантизация текста).
Также в данном модуле происходит «векторизация» слов, так как модель работает с числами, а не словами.
В следующем модуле при обучении был собран словарь: при переводе слов в коды неизвестные слова отбрасываются.
На выходе из данного модуля передается обработанный и векторизированный текст, который уже классифицирует обученная модель.
Модуль с обученной ML-моделью
Для того чтобы реализовать ML-модель, решающую задачи классификации текста, мы решили использовать два метода машинного обучения: «мешок слов» и «логистическую регрессию».
Чтобы качественно обучить модель, нужен большой набор данных, и того размеченного набора, который мы собрали при тестировании модуля парсинга, было недостаточно. Поэтому мы стали искать в интернете размеченные наборы данных, подходящие под нашу задачу. Мы нашли набор, в котором собраны комментарии по работе банков – позитивные и негативные.
В набор мы добавили также и наши собранные данные, таким образом получился «смешанный» комплект.
После сбора набора данных мы были готовы пробовать обучать модель, экспериментируя с различными настройками для повышения точности.
Что такое “мешок слов”, о котором говорилось ранее? Это представление текста в виде массива, состоящего из отдельных слов и количественного показателя их использования. Применяется при анализе естественного языка. Результатом представления является словарь в виде уникальных слов и их количества по предложениям и всему тексту в целом. Мы подали на вход набор данных, и на выходе получили словарь, про который говорилось в описании модуля предобработки данных. Он выглядит следующим образом:
Далее применялся метод машинного обучения – логистическая регрессия. Она является одним из статистических методов классификации с использованием линейного дискриминанта Фишера. Не углубляясь в математику, логистическую регрессию можно охарактеризовать следующим образом: в методе логистической регрессии не производится предсказание значения числовой переменной исходя из выборки исходных значений. Вместо этого значением функции является вероятность того, что данное исходное значение принадлежит к определенному классу. Это то, что нам нужно. На этапе MVP мы решили выделить два класса: негативный окрас и позитивный окрас.
Разбили выборку на тренировочный набор и тестовый набор в процентном соотношении 80 на 20 и получили неплохой результат – точность 0,95. Поскольку в набор данных были добавлены наши собранные сообщения, то такая точность нас устроила для MVP, и мы сохранили модель.
Далее мы запустили все реализованные модули и провели полноценное тестирование, пересылая в тестовый чат реальные сообщения из бизнес – чата, все сообщения были классифицированы правильно, поэтому мы посчитали, что тестирование пройдено успешно и перешли к финальной части - сохранению результатов и визуализации.
Модуль сохранения данных и визуализация
На выходе из предыдущего модуля мы получаем 0 – если окрас полученного сообщения негативный и 1 – если позитивный. Для хранения результатов мы решили использовать time – series DB – InfluxDB. Поэтому был реализован модуль сохранения данных.
В хранилище мы передаем пользователя, который написал сообщение и результат классификации модели.
В итоге мы получаем дашборд в Grafanaг в котором в режиме реального времени отображается картина за выбранный временной интервал, а также присутствует историчность для анализа.
Индекс рассчитывается по следующей формуле:
Берем общую сумму значений за выбранный временной интервал, делим на количество значений и умножаем на 100. Получается нормированный коэффициент, приведенный к процентам, где 100% — это “бизнес-заказчик полностью удовлетворен”, 0% — “бизнес-заказчик совсем не удовлетворен”.
На этапе MVP мы решили результат интерпретировать следующим образом:
0% – 50% - плохо (красный цвет)
50% - 70% - удовлетворительно (желтый цвет)
70% - 100% - отлично (зеленый цвет)
Также помимо общего коэффициента удовлетворенности мы реализовали детализацию по пользователям, чтобы понимать, кто конкретно доволен, а кто нет:
Заключение
Нами был разработан MVP, который показал хорошие результаты и будет обязательно развиваться в дальнейшем. Данный проект показывает, что для мониторинга эффективности можно применять различные решения, включая машинное обучение, и от идеи до работающего прототипа всего один шаг, который обязательно нужно делать. Мы добились сбора еще одного показателя, который позволяет нам анализировать удовлетворенность заказчика без дополнительного сбора обратной связи и за тот период, который нас интересует. Данная метрика должна помочь принимать различные управленческие решения, заблаговременно понимать, если есть какие-либо проблемы.