Основная функция машинного обучения Hootsuite

В 2018 году компания Hootsuite предприняла шаги по расширению возможностей машинного обучения для нашего продукта, сформировав команду для предоставления предлагаемой службы тегов. В дополнение к этой функции нашей команде вместе с командами из Нью-Йорка и Бухареста была поставлена ​​задача создать озеро данных, соответствующее требованиям GDPR, для данных машинного обучения и шаблон конвейера развертывания для будущих сервисов машинного обучения. Ниже приводится отчет о окончательном дизайне системы для этого проекта.

Мотивация

Hootsuite, как часть своего предложения, объединяет все сообщения, направляемые через социальные каналы, такие как Twitter, Facebook и Instagram, в одну платформу. Все типы комментариев (ответы, сообщения и личные сообщения) можно увидеть и ответить на них, и, кроме того, Hootsuite также предлагает дополнительную функциональность: возможность помечать сообщения. Теги используются нашими клиентами для различных целей. Например, отчеты формируются по семантике входящих сообщений (жалобы, похвалы, запросы). Наша команда подумала, что можно будет предложить эти теги с учетом содержания, типа сообщения и социальной сети. Предлагаемая функция тегов сэкономит время наших клиентов и позволит им более эффективно использовать теги, как мы предлагаем те, которые они использовали раньше.

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

Пример пользовательского интерфейса для функции «Предлагаемые теги» показан на рисунке 1:

Требования к проекту

Проект начался с учетом следующих соображений:

  • Производительность. Система должна обеспечивать высокую скорость и точность прогнозов тегов. Он обслуживает прогнозы в реальном времени и не должен вызывать раздражающих задержек при возврате прогнозов. Он также должен быть точным.
  • Масштабируемость. Система должна иметь возможность масштабирования для всех пользователей тегов корпоративного уровня. Это означает, что мы обрабатываем и обучаем сотни ГБ данных и обслуживаем десятки тысяч предложений в день.
  • Повторное обучение. Первоначальный анализ поведения наших клиентов при добавлении тегов показал, что новые теги создаются / архивируются ежедневно. Наша система должна уметь распознавать эти новые теги и перестать предлагать те, которые были заархивированы.
  • Эксперименты. Чтобы продолжить разработку дизайна, система должна позволять нам проводить эксперименты, не затрагивая пользователей.
  • Модель непрерывной интеграции / возможности аудита. Любые изменения кода, используемого в службе, должны отслеживаться. Новые модели должны иметь возможность заменяться местами в производстве и сниматься с производства, не влияя на трафик.
  • Соответствие GDPR. Все хранимые данные должны соответствовать GDPR.
  • Возможности отката. Если в новой производимой модели есть ошибка, должна быть возможность быстро вернуться к предыдущей версии.
  • Различные среды. Наличие локальной, промежуточной и производственной сред позволяет проводить разработку с наименьшими шансами повлиять на производственный трафик. Код, который разрабатывается в локальной среде, должен работать как при постановке, так и при производстве одинаково.

Дополнительным критерием для проекта было сделать его максимально похожим на текущие рабочие процессы разработчиков в Hootsuite. Таким образом, проект можно было легко поддерживать и использовать в качестве шаблона.

Окончательная системная архитектура

Говорят, что никогда не следует изобретать велосипед. В этом проекте мы приняли эту пословицу максимально близко к сердцу, используя множество различных технологий в нашем конвейере развертывания. Исчерпывающий список: Github, Jenkins, Docker, AWS SageMaker, AWS ECR, AWS EMR, AWS Elasticsearch, AWS S3, Spark, SKLearn и Kubernetes. Базовая архитектура системы показана на рисунке 2:

Я оставлю подробное обсуждение каждой из служб до следующих разделов поста, а пока давайте пройдемся по основному потоку:

  1. Необработанные данные поступают из различных источников и помещаются в S3 с помощью службы, написанной на Scala и размещенной в Kubernetes.
  2. Метаданные (например, дата и владелец данных) хранятся в AWS Elasticsearch.
  3. Служба, написанная на Spark и размещенная на AWS EMR, используется для обработки данных в форме, пригодной для обработки алгоритмом машинного обучения.
  4. Обработанные данные сохраняются в S3.
  5. На этом этапе AWS SageMaker запускает обучающий экземпляр и использует обработанные данные для создания обучающих артефактов (обученных моделей) и сохраняет их в S3.
  6. Артефакты проверяются на качество, а затем загружаются в обслуживающий экземпляр.
  7. Обслуживающий экземпляр получает запросы от службы логического вывода, которая действует как конечная точка для всего входящего трафика. Такие службы, как панель инструментов Hootsuite, будут вызывать эту службу и перенаправлять запросы на наш сервер вывода. Сервис Inferences действует как преобразователь запросов, а также как способ хранения входящих запросов и исходящих прогнозов для будущего анализа.

Озеро данных

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

Хранилище S3

Данные хранятся в нашем озере данных на основе S3. Мы получаем данные из различных источников (например, нашу шину событий на базе Apache Kafka) и сохраняем их в формате Parquet. Первоначально мы рассматривали возможность использования ORC; но хотя производительность загрузки и записи с ORC была немного лучше, мы решили использовать Parquet, поскольку он лучше поддерживает библиотеки Python, схемы можно определять с помощью Protobuf, а также поддерживаются вложенные структуры данных.

В целях соблюдения GDPR мы храним метаданные в Elasticsearch. Это позволяет нам легко находить данные и удалять их, если мы получим запрос от любого из наших клиентов. Мы храним данные в нашей необработанной корзине в течение 6 месяцев, так как этого было достаточно для обучения.

Обработка искры

Мы размещаем и запускаем задание обработки Spark в AWS EMR, которое преобразует данные из нашей необработанной корзины в требуемую форму, необходимую для приема службой обучения модели. Для нового проекта мы пишем новые процессоры, использующие те же необработанные данные. В начале предлагаемого проекта тега мы написали настраиваемое задание Scala и разместили его в Kubernetes; однако мы обнаружили, что из-за размера набора данных (~ 500 ГБ) параллельные вычисления необходимы, и поэтому мы перешли на Spark.

Алгоритм машинного обучения

Предлагать теги для социальных сообщений - это проблема машинного обучения с несколькими ярлыками. Алгоритм, который используется для прогнозирования тегов по содержанию сообщения, основан на статье Базовые линии и биграммы: простая, хорошая тональность и классификация тем. Мы используем модификацию этого алгоритма, в которой использовалась векторизация TFIDF вместо функций, основанных на подсчете биграмм, и логистическая регрессия вместо SVM. Этот метод обсуждается Джереми Ховардом в его курсе fast.ai по машинному обучению. Обучаем по одной из этих моделей для каждого из тегов (см. Стратегию OneVsRest). Затем мы упаковали каждую из этих моделей тегов в класс Predictor для каждого из наших клиентов, как показано на рисунке 3 ниже:

Подобная упаковка моделей позволяет нам написать несколько удобных функций для моделей. Например, каждая модель обучается, а затем тестируется на имеющемся наборе данных. Затем он оценивается с использованием значения AUC. Если нижняя граница доверительного интервала для этого значения AUC (см. Доверительные интервалы для области под кривой ROC) падает ниже приемлемых уровней, то мы отключаем модель. Таким образом, только те модели тегов, которые действительно хороши в прогнозировании, могут возвращать прогнозы в окончательной системе. Этот порог был настроен с помощью удобных возможностей настройки гиперпараметров SageMaker.

Тренировочная операция

Для обучения моделей машинного обучения требуется довольно много вычислительной мощности, и именно для этого создан SageMaker! В нашем текущем процессе обучения используется ml.m5.4xlarge. Для обучения модели мы просто упаковываем код в образ Docker, сохраняем его в AWS ECR и указываем SageMaker на изображение и данные обучения и укажите, какие ресурсы использовать. Поскольку мы хотим, чтобы этот процесс был доступен для всех наших разработчиков, но также подлежал аудиту и проверке кода, мы требуем, чтобы весь связанный код сохранялся в Github. После того, как код проверяется и отправляется в главную ветку, наш сервер Jenkins запускает задания по обучению и развертыванию. Весь процесс развертывания показан ниже на рисунке 4:

Наш сервер Jenkins может запускать любые необходимые команды SageMaker с помощью команд AWS CLI или Python SDK.

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

  • Нашим разработчикам не требуются разрешения IAM для включения и выключения инстансов EC2 (как того требует SageMaker). Таким образом, любой из наших разработчиков может развернуть службу машинного обучения. Это основная цель Hootsuite, поскольку мы хотим, чтобы все наши команды могли использовать машинное обучение как инструмент для решения своих проблем
  • Поскольку обучающий код хранится в изображениях, легко вернуться к предыдущим обучающим заданиям.
  • Трубопровод может работать автономно каждый день для переподготовки.
  • Разработчики никогда не имеют доступа к данным PII и смотрят только на результаты обучающих операций через агрегированную статистику. Это важно для соблюдения GDPR.

Метрики

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

Тем не менее, мы включаем другие показатели в конце нашего обучающего прогона, чтобы мы могли получить представление о поведении моделей. Как я упоминал ранее, каждая из моделей тегирования оценивается на протяженном наборе проверки, на котором мы вычисляем F2, AUC, потери Хэмминга, а также множество других показателей. Это позволяет нам получить хорошее представление о поведении системы в целом.

Системный мониторинг и обнаружение сбоев

Чтобы определить, когда производительность падает или когда наша служба вывода не возвращает прогнозы, мы построили информационные панели с помощью Interana. Если наш сервис начинает возвращать ошибки с аномальной скоростью, мы получаем уведомление в нашем канале Slack. Эти шаги важны для сокращения времени простоя.

Переподготовка

Наши клиенты ежедневно создают новые теги, поэтому наша система также должна иметь возможность ежедневно переобучаться. Поскольку развертывание каждого из необходимых заданий (обработка данных, модели обучения, развертывание нового сервера вывода) было бы утомительно выполнять вручную каждый день, мы создали задание Cron в Jenkins, которое будет запускать каждый шаг за нас. Чтобы гарантировать, что мы не развертываем плохие модели, мы пишем тесты качества моделей и интеграции, которые остановят это развертывание, если что-то пойдет не так. Таким образом, мы можем не вмешиваться и получать уведомления только в случае ошибки.

Акт окончательной балансировки и производительность

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

Чтобы проверить наш сервис машинного обучения, мы провели A / B-тест, в ходе которого мы представили половину нашей бета-когорты с последним использованным тегом в качестве предложения, а половину - с нашим прогнозом машинного обучения. Хотя система машинного обучения работает лучше, чем недавняя система тегов, мы обнаружили, что гибридная система работает даже лучше, чем машинное обучение или только недавно использованные системы тегов.

Наши показатели немного разнятся изо дня в день, однако, мы постоянно принимаем 60–65%.

Заключение

Построить системы машинного обучения производственного уровня непросто. К счастью, инструменты, которые могут помочь, с каждым днем ​​становятся все более распространенными. Следите за новыми проектами команды машинного обучения Hootsuite в будущем. Если у вас есть какие-либо вопросы по этому проекту, не стесняйтесь обращаться ко мне в LinkedIn: https://www.linkedin.com/in/tylerlanigan/.

Я хотел бы поблагодарить Джонатана Мейерса из нашего офиса в Нью-Йорке, Итана Обушона из нашего офиса в Торонто, а также команды Бухарестской и Ванкуверской команд за их помощь в проектировании и создании озера данных. Спасибо моим товарищам по команде Хонто Мингу, Сэму Реху и Эндрю Гормли за то, что они в целом потрясающие и усердно работали над предложенным проектом тегов вместе со мной.