На примере системы управления ретаргетинговой рекламой в Facebook для онлайн туристических агентств
Alexander Makeev
makeev.alex@gmail.com
https://ua.linkedin.com/in/alexandermakeev
1. ЛЯМБДА-АРХИТЕКТУРА С
ОБРАТНОЙ СВЯЗЬЮ
На примере системы управления ретаргетинговой рекламой в Facebook для
онлайн туристических агентств
Александр Макеев, 2016 г.
3. ЗАДАЧА
• В сфере туризма существует проблема длинного цикла продажи
• Потенциальный клиент может летом зайти на сайт онлайн туристического агентства
(ОТА) чтобы подобрать тур на Новый год
• Если сайт ОТА – это не Booking.com, то имеющиеся поисковые алгоритмы едва ли
умеют релевантно ранжировать списки отелей
• После тщетных попыток что-то найти большинство клиентов уходят
• Требуется инструмент для возврата потерянных клиентов
• Один из таких инструментов – ретаргетинговая реклама
• Этим и займёмся!
4. РЕТАРГЕТИНГОВАЯ РЕКЛАМА
Два типа обычной ретаргетинговой рекламы:
1. Яркие фото девушек с кокосами на фоне
изумрудного моря с крайне информативными
лозунгами
«А ты готов к отдыху?»
2. Ещё месяц вас будут преследовать отели «ПО
СКИДКАМ ТОЛЬКО СЕГОДНЯ», которые вы уже
видели и закрыли потому что вам они не
понравились
ЭтО раЗдрАжаеТ, ДА?
посмотрел
отели
ушёл
зашёл в
Facebook
увидел
рекламу
зашёл на сайт
ОТА
круговорот
клиента
в рекламе
5. ПРАВИЛЬНЫЙ РЕТАРГЕТИНГ
Через рекламу
предложить супер-
варианты
Понять
клиента
Собрать
данные
• Собрать все имеющиеся данные по каждому
клиенту: параметры поиска, просмотренные
отели, возвраты, отправленные заявки и т.д.
• На основании всей предыдущей истории
создать портрет клиента: его предпочтения,
финансовые возможности, семейное
положение
• Подобрать статистически наиболее
релевантные варианты отдыха и предложить
их через ретаргетинговую рекламу
6. НЮАНСЫ СЕГМЕНТА ТУРИЗМА
• Клиенты очень редко точно знают, что именно они хотят
• В большинстве случаев более-менее стабильна только информация о том, в какую
страну хочет попасть турист, каким составом, примерные даты и начальный бюджет
• В отличии от розницы с номенклатурной базой максимум в тысячи позиций по
каждой товарной группе, в туризме количество вариантов туров в одну страну
исчисляется миллионами
• Нет возможности сделать кросс-продажу
• Зато туристы каждый год куда-то путешествуют. И это круто!
• С возрастом туриста растут бюджеты и предсказуемость направлений
7. СИСТЕМА ДОЛЖНА ОБЕСПЕЧИВАТЬ
• Сбор, хранение и первичный анализ исторических данных
• Сегментацию пользователей на основании поисковых запросов
• Получение актуальных цен на отели под каждый сегмент
• Качественные рекомендации отелей основываясь на поведенческих паттернах и
собранной статистики
• Создание изображений отелей с дополнительными информационными слоями
(названия отелей, параметры сегментов, цены, скидки)
• Создание и обновление рекламных объявлений
• Сбор и обработку рекламной аналитики Facebook
11. СБОР ДАННЫХ О ПОЛЬЗОВАТЕЛЯХ
• Цель: сбор всех доступных данных о посещении каждой страницы
в рамках сессии каждого посетителя
• Трекер активности посетителей сайта
• Фротент-часть на JS
• Переработанный скрипт Piwik
• Бекенд-часть на Go
• NGINX reverse-proxy
• 4-8 golang backends
• Является прокси-слоем к алгоритмам рекомендательной системы
• Возвращает JSONP список рекомендованных отелей
13. ЛЯМБДА-АРХИТЕКТУРА
• Быстрое in-memory хранилище для данных пользователей с активными
сессиями
• Медленное постоянное хранилище для всех исторических данных
(сохранение с потенциальной задержкой)
• Данные всегда хранятся в первозданном виде для дальнейших
манипуляций
• Как правило кортежи очень широкие: десятки атрибутов
• В классической архитектуре преобразование и формирование датасета
(выполнение функции трансформации) производится на лету в serving-слое
используя данные из обоих хранилищ
• Отличие от классики: перед преобразованием данные из постоянного
хранилища один раз загружаются в сессионное. Далее данные
записываются одновременно в оба хранилища, но serving-слой использует
только сессионное.
14. ХРАНЕНИЕ ИСТОРИЧЕСКИХ ДАННЫХ
• Данные хранятся в виде иммутабельных raw-логов
• Постоянное хранилище
• Сейчас используется MongoDB
• После выхода за пределы возможностей – Hadoop/HBase
• Сессионное хранилище
• Используется Redis (в дальнейшем – Aerospike)
• При активизации сессии пользователя из постоянного хранилища
загружаются все его исторические данные
• Все последующие события в рамках сессии сохраняются
одновременно в сессионное и постоянное хранилища
• Время жизни данных – несколько часов
15. EXTRACT TRANSFORM LOAD
• Слой обработки сырых данных
• На выходе – датасет, пригодный для дальнейшей работы
рекомендательной системы
• Сейчас с объёмом данных справляется однопоточный
обработчик, в дальнейшем Hadoop + Spark + Python
• В realtime используется для получения обработанной истории
конкретного пользователя
• В пакетном режиме используется для получения обработанной
истории всех пользователей, на которой проводится обучение
алгоритмов рекомендательной системы
• Языки реализации слоя: Go и Python
16. КРИТЕРИИ ВЫБОРА ХРАНИЛИЩ
• MongoDB
• schemaless
• fast
• scalable
• Redis
• fast
• Hbase
• columnar
• scalable
• Aerospike
• extremely fast
• scalable
• powerful inline scripting language Lua
18. РЕКОМЕНДАТЕЛЬНАЯ СИСТЕМА
• Входные данные:
• История просмотров страниц
• Активные пользовательские сегменты
• История отправки заявок на туры
• История продаж из CRM
• Статистика рекламных объявлений из Facebook Insights
• Алгоритмы:
• Для пользователей без истории – статистически наиболее эффективные
предложения для каждого сегмента
• При наличии истории просмотров – мульти-классовая классификация с
помощью XGBoost (получение вероятности по каждому классу-отелю)
• В разработке – классификация с помощью нейронной сети прямого
распространения
19. Redis
АРХИТЕКТУРА РЕКОМЕНДАТЕЛЬНОЙ
СИСТЕМЫ
Сервис обучения XGBoost
ХранилищеETL
Сохранённая в
файл модель
XGBoost
XGBoost
XGBoost
Пул микросервисов
рекомендательной системы
raw data
оповещениясервисовоб
изменениимодели
Realtime
tracker
Supervisor
NGINX
states
cache
Redis
20. ОБУЧЕНИЕ МОДЕЛИ РЕКОМЕНДАТЕЛЬНОЙ
СИСТЕМЫ
• Через заданный промежуток времени cron-задача закидывает в
RabbitMQ сообщение о том, что нужно переобучить модель
• Процесс, занимающийся обучением, получает сообщение и производит
действия:
• Вычитка всех накопленных исторических данных
• Первичная очистка от кортежей, которые не могут быть использованы
при обучении модели
• Формирование финального Python Pandas DataFrame
• One-hot encoding
• Normalizing
• Тренировка xgboost.XGBClassifier
• Проверка качества модели
• Сохранение модели в файл
• Запись в Redis структуры с данными о новой модели
21. ОБЗОР МИКРОСЕРВИСОВ
• Основная нагрузка рекомендательной системы приходится на пул
микросервисов
• Каждый микросервис – это однопоточное приложение на Python
+ Tornado на отдельном порту
• Микросервисы запускаются и мониторятся с помощью Supervisor
• Для всего пула в качестве фронтенд и балансировщика нагрузки
используется NGINX
22. ЗАГРУЗКА НОВОЙ МОДЕЛИ
• В Redis хранится ID самой свежей модели
• Во время инициализации микро-сервис получает ID текущей
модели, загружает её из файла и инициализирует экземпляр
XGBoost
• С имеющейся рассчитанной и предзагруженной моделью сервис
отвечает на запросы
• После каждого запроса происходит проверка на наличие новой
модели
• Если появилась новая модель, то сервис просто завершает свою
работу и вместо него Supervisor запускает новый экземпляр
сервиса
23. ОБРАБОТКА ЗАПРОСА
• Запрос к сервису содержит ID пользователя, для которого
необходимо сделать рекомендацию отелей
• Сервис проверяет наличие необходимых данных в сессионном
хранилище
• Если данные не полные, то догружает недостающие из
постоянного хранилища в сессионное
• Формирует датасет, пригодный для работы XGBoost:
• Cleaning
• One-hot encoding
• Normalizing
• Выполняет предзагруженную модель
• Возвращает список ID рекомендованных отелей
24. ПРОБЛЕМЫ ПРОГНОЗИРОВАНИЯ
• Недостаточный объём данных для обучения алгоритмов
рекомендательной системы
• Огромное количество отелей и как следствие необходимость собирать
огромное количество данных для обучения
• Невозможность использовать основную метрику качества
рекомендаций – конверсию в клиенты
• Многоканальная природа продаж пакетных туров
• Невозможность учёта факторов качества оффлайн-обслуживания
клиентов
• Большое количество субъективных факторов при окончательном выборе
места отдыха
• Проблема long-tail из статистически непопулярных отелей, выбор
которых не попадает под статистически значимые поведенческие
паттерны
26. АКТУАЛИЗАТОР ЦЕНОВЫХ ПРЕДЛОЖЕНИЙ
• Непрерывно работающий сервис, получающий обновлённые
ценовые предложения от операторов
• Цены получаем в разрезе каждого из сегментов
• Сохраняется история изменения цен
• На основании истории производится поиск резких падений цен
• Для найденных предложений в рекламных объявлениях
указывается процент падения цены
• Актуальные цены используются при формировании продуктового
каталога для рекламной системы FB
27. ГЕНЕРАТОР ИЗОБРАЖЕНИЙ
• Каждое изображение формируется индивидуально под каждый
рекламный блок
• На изображение отеля накладываются слои:
• название
• некоторые параметры сегмента
• актуальная цена
• процент снижения цены
• URL изображения используется при формировании продуктового
каталога
• Для формирования изображений используется PHP+GD
• Количество соответствует объёму генерируемого продуктового
каталога: сотни тысяч изображений
28. ПУБЛИКАЦИЯ ОБЪЯВЛЕНИЙ
• Используется Facebook Ads API
• Чтобы соответствовать требованиям и ограничениям API для
каждого аккаунта создаётся собственная очередь в RabbitMQ и
монопольный консьюмер, отправляющий запросы к API
• Для каждой страны создаётся рекламная кампания, внутри
которой единоразово формируются рекламные объявления,
использующие каталоги продуктов
• Свежие каталоги продуктов формируются и загружаются в FB
после каждой завершённой актуализации цен
• Для работы с Facebook API используется PHP
29. ГРУППИРОВКА ЗАДАЧ RABBITMQ
• Публикация объявлений – комплексная задача, состоящая из нескольких
шагов:
• Получение актуальных цен
• Создание рекламной кампании
• Генерация изображений
• Формирование продуктового каталога
• Публикация каталога
• Некоторые подзадачи можно делать параллельно, некоторые строго
одну за другой. Одна задача может после своего выполнения добавить
в очередь следующую.
• Каждому пакету задач задаётся уникальный ID, по которому можно
отследить прогресс выполнения задачи или определить по логам место
сбоя
• В планах: механизм конфигурирования взаимосвязей между
подзадачами и автоматизация запуска последовательностей
31. СБОР И ОБРАБОТКА СТАТИСТИКИ
• Для получения статистики используется FB Ads Insights API
• Сбор статистики производится cron-задачей раз в сутки
• Статистика собирается и суммируется в разрезе каждого отеля
• Основной критерий оценки – CTR
• Отели с низким CTR:
• имеют пониженный весовой коэффициент в алгоритмах
рекомендательной системы
• уходят на модерацию в админку
• могут быть полностью удалены из ротации
32. ОБРАТНАЯ СВЯЗЬ
• Результат работы рекомендательной системы
используется для показа рекламных объявлений
• Главный критерий качества работы рекомендательной
системы – конверсия, но использовать её для
оптимизации алгоритма невозможно из-за длинного
цикла продажи
• В качестве критерия качества используется CTR
• Обратная связь внутри рекламной системы:
1. результат работы алгоритма рекомендаций
ротируется в рекламе
2. собираются метрики качества объявлений
3. метрики являются одним из основных факторов в
работе алгоритма рекомендательной системы
Анализ поведения
аудитории
Формирование
рекомендаций
Показ рекламных
объявлений
Анализ статистики
33. СЛОЖНОСТИ РЕАЛИЗАЦИИ
• Разрывы в общем потоке данных (FB privacy agreement):
• нет технической возможности узнать через FB API какие именно
объявления, в какой последовательности и сколько раз были показаны
каждому из посетителей
• нет возможности узнать, кому именно мы рекомендуем предложения по
отелям
• Таким образом система работает с полностью анонимизированными
посетителями
• Все этапы работы системы сильно растянуты во времени и фактически
между этапами получения данных из трекера, работы рекомендательной
системы, реакцией пользователей на объявления, сбором статистики и
приходом агрегированных метрик в виде фич в модель рекомендательной
системы, могут проходить часы или даже дни
36. ELASTICSEARCH + LOGSTASH
• Логирование с помощью UDP-сообщений в Logstash
• очень быстро
• но что-то может бесследно исчезнуть
• Далее Logstash пакетами сохраняет лог в Elasticsearch
• возможность полнотекстового поиска
• визуализация данных с помощью Kibana
• Кроме текста сообщения сохраняются:
• дата и время
• источник
• PID процесса
• код сообщения
• уровень сообщения (error, warning, etc)
• ID сообщения в случае пакетной обработки
• Error trace
38. НАГРУЗОЧНОЕ ТЕСТИРОВАНИЕ
• Тестовая конфигурация сервера: 8 ядерный Intel(R)
Xeon(R) CPU E3-1271 v3 @ 3.60GHz, RAID1 SSD,
32Gb RAM
• NGINX with upstream 10 Go tracker processes
• Нагрузка: соседний сервер в том же ДЦ, скрипт:
• Запросы идут на трекинг просмотра страницы и
получение списка рекомендованных отелей без
использования кеширования
• Результаты тестирования стабильны при любом
количестве конкурентных клиентов: 1300-1400
запросов в секунду
• Bottleneck: количество ядер процессора (почти
100% загрузка)
• Решение потенциальной проблемы:
горизонтальное масштабирование
• На данный момент односерверное решение
гарантирует обработку трафика в 30 миллионов
запросов в сутки при расчёте что 50% трафика
приходится на 3 самых активных часа суток
• Это полностью покрывает потребности всего
украинского туристического рынка
#!/bin/sh
for i in 1 10 20 50 100 200
do
ab -n 10000 -c $i -e log-${i}.csv -g plot-${i}.tsv URL
done
На самом деле клиенты могут уходить с сайта по самым разным причинам. Они могут быть даже вполне довольными, но закрыть браузер и на следующий день уже не вспомнить, где они были.
Два слова о том, что такое ретаргетинговая реклама и переходим к технической части. Идея простая. Клиент заходит на сайт, рекламная система трекает просмотренный страницы или какие-то ключевые действия на сайте. После того, как клиент уходит и заходит в свою любимую социальную сеть или, например, что-то ищет в Гугле, и тут-то по его душу и приходит ретаргетинговая реклама, которая знает, что вы побывали на целевом сайте и что-то там смотрели. Дальше возможны вариации. Все крупные рекламные сети предоставляют обширнейший функционал по тонкой настройке рекламные кампаний. Но по разным причинам эти инструменты не используются. В самом примитивном виде клиенту откручивается одна и та же реклама с идиотскими призывами к действию. Более продвинутые рекламные агентства используют информацию в нашем случае о посещённых отелях и потом через рекламу предлагают посмотреть эти отели ещё раз. ЗАЧЕМ?! Я ушёл, потому что мне не понравились эти отели. Зачем их показывать мне ещё раз? В общем при всём богатстве инструментов рекламные агентства продолжают брать микроскоп и заколачивать им гвозди в наши мозги. Раздражает? Ещё как…
Теперь о правильном ретаргетинге. Сразу хочу подчеркнуть: то, о чём мы будем говорить далее, касается только ОТА. В сфере розничной торговли работают другие механизмы. Основные нюансы на следующем слайде.
Итак, идея правильного ретаргетинга, которая тестировалась в моём стартапе: нужно ПОНЯТЬ что хочет клиент. Если я смогу правильно распознать потребности – я смогу показать ему ПОЛЕЗНУЮ рекламу. Да, такая бывает. Не впарить «туры в Египет недорого только сегодня», а сделать ему такое предложение, которое попадёт точно в цель.
Именно в туризме можно развернуться на задаче подбора идеального варианта отдыха для клиента. Т.к. чаще всего клиента