"Контекстная реклама в Avito: что под капотом?"
Вадим Аюев и Андрей Остапец (Avito)
Из этого доклада вы узнаете об основных этапах создания и обучения моделей, на основе которых работает контекстная реклама в Avito: как собираем и готовим данные, обучаем модели, как реализовано тестирование и внедрение.
Python Data Science meetup @ Avito 13.08.2016
2. Strictly ConfidentialStrictly Confidential
О чём будем говорить?
• Как выглядит контекстная реклама на Авито
• Как показать объявление
• Как строить простые модели
• Можно ли сделать модель лучше
• Фиды для профессиональных пользователей
• Обучение и тестирование моделей
Python Data Science Meetup, 2016-08-13
4. Strictly ConfidentialStrictly Confidential
Как показать объявление
• Отбирается множество объявлений, релевантных запросу
пользователя.
• Мы хотим, чтобы участники сами боролись за рекламные
места.
• Мы не хотим жёстко закреплять стоимость клика.
• Решение – аукцион среди рекламодателей.
• Для каждого объявления просим указать ставку (bid) –
максимальное количество денег, которое рекламодатель готов
заплатить (за клик).
Python Data Science Meetup, 2016-08-13
5. Strictly ConfidentialStrictly Confidential
Аукцион
• GSP – обобщённый аукцион второй цены
• 𝑐𝑜𝑠𝑡1𝑠𝑡 =
𝑏𝑖𝑑2𝑛𝑑 𝐶𝑇𝑅2𝑛𝑑
𝐶𝑇𝑅1𝑠𝑡
• CTR – «кликабельность». В нашем случае – вероятность
получения клика по объявлению.
Advert_id Bid CTR Bid * CTR Place
1 10 0.5 5 3-rd
2 8 0.8 6.4 1-st
3 8 0.7 5.6 2-nd
Python Data Science Meetup, 2016-08-13
6. Strictly ConfidentialStrictly Confidential
Наивная модель вычисления CTR
• Отношение кликов к показам: 𝐶𝑇𝑅 =
𝑐𝑙𝑖𝑐𝑘𝑠
𝑖𝑚𝑝𝑟𝑒𝑠𝑠𝑖𝑜𝑛𝑠
• Проще не бывает. Всё считаем в реальном времени.
• Очень неточная + много открытых проблем:
• Что делать с новыми объявлениями? Что делать с
объявлениями с небольшим числом показов?
Python Data Science Meetup, 2016-08-13
7. Strictly ConfidentialStrictly Confidential
Простая модель вычисления CTR
• Считаем вероятность клика по (похожим) обычным
объявлениям: 𝐶𝑇𝑅𝑖𝑡𝑒𝑚𝑠 =
𝑐𝑙𝑖𝑐𝑘𝑠 𝑖𝑡𝑒𝑚𝑠
𝑖𝑚𝑝𝑟𝑒𝑠𝑠𝑖𝑜𝑛𝑠 𝑖𝑡𝑒𝑚𝑠
• Считаем вероятность клика по (похожим) рекламным
объявлениям: 𝐶𝑇𝑅 𝑎𝑑𝑣𝑒𝑟𝑡𝑠 =
𝑐𝑙𝑖𝑐𝑘𝑠 𝑎𝑑𝑣𝑒𝑟𝑡𝑠+𝛼
𝑖𝑚𝑝𝑟𝑒𝑠𝑠𝑖𝑜𝑛𝑠 𝑎𝑑𝑣𝑒𝑟𝑡𝑠+
𝛼
𝐶𝑇𝑅 𝑖𝑡𝑒𝑚𝑠
• Считаем вероятность клика по искомому рекламному
объявлению: 𝐶𝑇𝑅 =
𝑐𝑙𝑖𝑐𝑘𝑠+𝛽
𝑖𝑚𝑝𝑟𝑒𝑠𝑠𝑖𝑜𝑛𝑠+
𝛽
𝐶𝑇𝑅 𝑎𝑑𝑣𝑒𝑟𝑡𝑠
• Здесь 𝛼 и 𝛽 – положительные константы.
• Простой, понятный и надёжный механизм. Частично
обновляется в реальном времени.
• Всё ещё не очень точная. Есть проблемы, например, почему
одинаковые объявления имеют разный CTR?
Python Data Science Meetup, 2016-08-13
8. Strictly ConfidentialStrictly Confidential
Теперь добавим немного machine learning
• Получим выборку на модели “холодного старта”
• Построим более умную модель
• Запустим в production
• Почему бы сразу не организовать конкурс?
• https://www.kaggle.com/c/avito-context-ad-clicks
Python Data Science Meetup, 2016-08-13
9. Strictly ConfidentialStrictly Confidential
Модель вычисления CTR
• Что хотим получить? Какую задачу решаем?
• Обучающая выборка, построенная на наивной модели
• Здесь x1, x2, …, xN – переменные (обозначим как x),
характеризующие контекст показа РО (время показа РО,
операционная система пользователя, IP, цена в объявлении и
т.д.); y – целевое действие (был клик или нет).
• Нужно построить такую модель f, для которой f(x) ≈ y.
# x1 x2 x3 … xN y
1
2
…
M
Python Data Science Meetup, 2016-08-13
10. Strictly ConfidentialStrictly Confidential
Модель вычисления CTR
• Как эффективно строить различные модели f при различных
условиях (характеристиках x и y) – предмет изучения machine
learning.
• Логистическая регрессия: 𝑓 𝐱 =
1
1+exp − 𝑥1 𝑤1+𝑥2 𝑤2+⋯+𝑥 𝑁 𝑤 𝑁
• Здесь w1, w2, …, wN – некоторые вещественные значения
(«веса», обозначим как w).
• Обучение такой модели будет сводиться к подбору w так,
чтобы минимизировать ошибку, например:
𝑙 𝐱 = −𝑦 log 𝑓 𝐱 − 1 − 𝑦 log 1 − 𝑓 𝐱
• Как подбирать веса? Например, итерационно, методом
стохастического градиента: 𝐰𝑡+1 = 𝐰𝑡 − 𝜂 𝑡 𝐠 𝑡, где 𝐠 𝑡 - градиент
ошибки работы модели в пространстве весов (𝐠 𝑡 = 𝐱 𝑡 𝑓 𝐱 𝑡 −
Python Data Science Meetup, 2016-08-13
11. Strictly ConfidentialStrictly Confidential
Модель вычисления CTR: как улучшить
• Добавить нелинейности – взаимодействия признаков (feature
interactions). Например, для признака x1 = категория и x2 = цена
можем ввести синтетический признак xN+1 = x1 * x2.
• C одной стороны, признаков станет много, с другой есть
опасность переобучиться и/или получить много ненужных
переменных. Решение – введение регуляризатора.
• Категориальные данные. Обычно каждый категориальный
признак, содержащий K уникальных значений,
«раскладывается» в K бинарных переменных. Т.е. размерность
данных растёт пропорционально числу уникальных значений в
таких признаках (см. куки, идентификаторы объявлений, IP-
адреса), а с добавлением взаимодействия между такими
признаками, всё станет совсем печально.
• Что делать?
Python Data Science Meetup, 2016-08-13
12. Strictly ConfidentialStrictly Confidential
Модель вычисления CTR: hashing trick
• Рассчитываем синтетический признак (на основе взаимодействия
2 и более признаков) и считаем от него хэш.
• Полученный хэш делим по модулю на 2K (максимальную
размерность признакового пространства)
• Теперь имеем разреженный вектор размерности 2K с 1 в
единственном индексе (остальные 0).
• То же самое делаем и для остальных признаков (в том числе и
для категориальных, для чего искусственно можно сделать их
категориальными).
• Таким образом, количество ненулевых значений в разреженном
обучающем векторе не будет превышать числа признаков.
• Итоговая модель описывается коэффициентами при ненулевых
«столбцах» разреженной матрицы признаков (все векторы вместе)
Python Data Science Meetup, 2016-08-13
13. Strictly ConfidentialStrictly Confidential
Модель вычисления CTR: FTRL
• В результате пришли к процедуре обучения модели:
𝐰𝑡+1 = argmin
𝐰
𝐰
𝑠=1
𝑡
𝐠 𝑠 +
1
2 𝑠=1
𝑡
𝜎𝑠 𝐰 − 𝐰𝑠 2
2
+ 𝜆 𝐰 1
где 𝑠=1
𝑡
𝜎𝑠 =
1
𝜂 𝑡
• Модель является дообучаемой (on-line learning), т.е. найденные
веса корректируются при обучении на новых данных.
• Модель возвращает вероятность клика по РО.
• Использование модели описано в работе “Ad Click Prediction: a
View from the Trenches”
Python Data Science Meetup, 2016-08-13
14. Strictly ConfidentialStrictly Confidential
Модель вычисления CTR: используемые признаки
• Признаки, описывающие объявление, например:
• Домен
• Цена
• Текст (объявление, заголовок)
• Микрокатегория
• …
• Признаки, описывающие пользователя, например:
• IP
• Cookie
• UA
• Факт логина
• …
• Признаки, описывающие поисковое окружение, например:
• Позиция показа объявления
• Время поиска
• Категория поиска
• Поисковый запрос
• …
Python Data Science Meetup, 2016-08-13
15. Strictly ConfidentialStrictly Confidential
Связанные задачи: обработка фидов
• Фид – файл в разметке YML (пока), в котором лежат текстовые
описания потенциальных рекламных объявлений.
• Задача: на основе данных из файла сопоставить каждому
товару микрокатегорию в дереве контекста Авито.
Python Data Science Meetup, 2016-08-13
16. Strictly ConfidentialStrictly Confidential
Связанные задачи: обработка фидов
• Текстовые данные превращаем в векторы большой
размерности путём нормализации слов и их последующего
кодирования (bag of words, tf-idf).
• Целевая переменная – микрокатегория, к которой принадлежит
это объявление.
• Как получить обучающую выборку (разметить данные из фидов
наших клиентов)? С помощью асессоров.
• Разметка включает указание микрокатегории товара, откуда мы
можем получить категорию и подкатегорию.
• Задача: построить модель, которая бы по текстовому описанию
товара возвращала для него TOP-5 вероятностей
принадлежности к микрокатегориям контекста и указывала,
насколько TOP-1 является правдоподобной.
Python Data Science Meetup, 2016-08-13
17. Strictly ConfidentialStrictly Confidential
Связанные задачи: обработка фидов
• Обучаем 3 модели (линейные классификаторы) на разных
уровнях (целевые переменные – категории, подкатегории,
микрокатегории). Без hashing trick, но с L1-регуляризацией.
• Как обучить логистическую регрессию разделять более чем 2
класса? One-vs-all схема, т.е. для разделения P классов строим
P моделей, получаем вероятности от каждого из них,
нормируем результаты.
• Алгоритм определения категории:
• Считаем прогноз на уровне микрокатегорий и отбираем 5
возможных кандидатов с максимальной вероятностью.
• У выбранных микрокатегорий, считаем прогноз на уровне
подкатегорий.
• У выбранных подкатегорий, считаем прогноз на уровне
категорий.
• Складываем 5 троек получившихся вероятностей,
выбираем тройку с максимальной суммой.
Python Data Science Meetup, 2016-08-13
18. Strictly ConfidentialStrictly Confidential
Связанные задачи: обработка фидов
• Из тестовой выборки выделяем валидационную, на которой
настраиваем пороги.
• Точность на контроле – 86%, точность работы модераторов –
88%.
• Суммарный объём товаров в фидах – более 7 миллионов
товаров.
Python Data Science Meetup, 2016-08-13
19. Strictly ConfidentialStrictly Confidential
Инфраструктура
• Более подробно про инфраструктуру рассказали на РИТе 2016:
• http://backendconf.ru/2016/abstracts/2097.html («Успеть за
100 миллисекунд: контекстная реклама на Sphinx» /
Дмитрий Хасанов)
Рисунок из ”Hidden Technical Debt in Machine Learning Systems”, 2014
Python Data Science Meetup, 2016-08-13
20. Strictly ConfidentialStrictly Confidential
Обучение моделей прогноза CTR
• Имеем разные места хранения данных: MongoDB и HP Vertica.
Разная ёмкость, разная скорость обработки запросов, разный
характер данных (вычислимые vs. статичные).
• Вносится задержка на очистку данных от «мусора».
• Процедура обучения (нахождение коэффициентов в модели
FTRL) занимает некоторое время.
• Результат: загрузка данных, предобработка и обучение
моделей (всё на Python!) происходит на выделенных серверах
раз в 6 часов; на выходе – коэффициенты модели,
передаваемые в сервис (Sphinx UDF).
Python Data Science Meetup, 2016-08-13
21. Strictly ConfidentialStrictly Confidential
Тестирование моделей off-line
• Хотим улучшить модель, например, протестировать новый
признак. Как это сделать?
• Грузим (вычисляем) новый признак из данных.
• Обучаем на некоторой выборке пару моделей: с признаком и
без.
• Проверяем обе модели на тестовой выборке: снизится ли
ошибка прогноза клика (LogLoss, AUC) и на сколько?
• Всё ещё недостаточно хорошо: новая модель «в бою» будет
приводить к изменению ранжирования в аукционе,
следовательно, пользователи будут видеть что-то другое и
целевые метрики могут непредсказуемо измениться.
Python Data Science Meetup, 2016-08-13
22. Strictly ConfidentialStrictly Confidential
Тестирование моделей on-line: сплит-тестирование
• Как делить трафик: по пользователям, по показам.
• Разделение должно быть корректным и повторимым.
• Целевые метрики на группах должны быть устойчивыми (А/А-
тесты, в том числе на неравновесных распределениях).
• hash(hash(cookie) + salt) % groups
• Желательно сохранять работающую старую модель на
небольшом объёме трафика.
Python Data Science Meetup, 2016-08-13
23. Strictly ConfidentialStrictly Confidential
Вместо выводов
• Конкурсы по data science – это очень хорошо.
• Кстати, у нас есть ещё: http://dataring.ru/competitions/avito-
category/
• Применимость моделей определяется инфраструктурой
(большие ансамбли моделей, с которыми побеждают на
конкурсах, на практике не работают).
• Всё, кроме нагруженной части непосредственного расчёта
CTR, можно сделать в Python.
• Дружная команда с короткой коммуникацией – залог успеха.
Python Data Science Meetup, 2016-08-13
24. Strictly ConfidentialStrictly Confidential
Vadim Ayuyev
Leading Data Scientist, Avito
vayuyev@avito.ru
Andrey Ostapets
Senior Data Scientist, Avito
aostapets@avito.ru
Python Data Science Meetup, 2016-08-13