В первой части этой серии я представил Соревнование по машинному обучению Outbrain Click Prediction. В этом посте описаны некоторые предварительные и важные задачи по науке о данных, такие как исследовательский анализ данных и разработка функций, выполненные для конкурса с использованием кластера Spark, развернутого в Google Dataproc.

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

Задача прогнозирования

В этом конкурсе Kagglers должны были ранжировать рекомендуемые объявления, уменьшая прогнозируемую вероятность кликов. Спонсируемая поисковая реклама, контекстная реклама, медийная реклама и аукционы с торгами в реальном времени — все они в значительной степени зависели от способности изученных моделей точно, быстро и надежно прогнозировать рейтинг кликов (CTR) объявлений.

Метрикой оценки была MAP@12 (средняя средняя точность при 12), которая измеряет качество ранжирования. Другими словами, учитывая набор объявлений, представленных во время посещения пользователя, этот показатель оценивает, было ли выбранное объявление ранжировано вашей моделью выше других объявлений. Метрика MAP@12 показана ниже, где |U| — общее количество посещений пользователями (display_ids) целевой страницы с рекламой, n — количество объявлений на этой странице, а P(k) – точность при отсечении k.

Этот конкурс предоставил очень большую реляционную базу данных в формате CSV, модель которой была показана в первом посте. Основными таблицами были clicks_train.csv (~87 миллионов строк) и clicks_test.csv (~32 миллиона строк), представляющие набор поездов и набор тестов соответственно.

Набор поездов (display_id, ad_id, clicked) содержал информацию о том, какие объявления (ad_id) были рекомендованы пользователю при посещении данной [целевой] страницы (display_id) и какое из объявлений было фактически нажато пользователем. Display_id и ad_id — это внешние ключи, позволяющие другим таблицам объединяться с дополнительным контекстом о посещении пользователя, целевой странице и страницах, на которые ссылается реклама.
Тестовый набор (display_id, ad_id) содержал те же атрибуты, за исключением флага clicked, как и ожидалось.

Ожидаемым решением был файл CSV с прогнозами для набора тестов. Первый столбец — это display_id, а второй — ранжированный список ad_id, разделенный пробелом.

display_id,ad_id
16874594,66758 150083 162754 170392 172888 180797
16874595,8846 30609 143982
16874596,11430 57197 132820 153260 173005 288385 289122 289915
...

Перекрестная проверка

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

Необходимо было отделить от clicks_train.csv процент сэмплов для валидационного набора (около 30%) и остальные семплы как обучающий набор. Модели машинного обучения обучались с использованием данных набора поездов, а их точность оценивалась на данных набора проверки путем сравнения прогнозов с метками истинности (кликами).

По мере того, как мы оптимизируем точность модели CV — тестируя различные подходы к проектированию функций, алгоритмы и настройку гиперпараметров, — мы ожидаем, что соответственно улучшится наш результат в таблице лидеров соревнований (LB) (набор тестов).

Для большинства соревнований Kaggle существует дневной лимит подачи (два в этом соревновании), а методы CV позволяют неограниченно оценивать подходы.

Для этого соревнования я использовал метод CV под названием holdout, который просто состоит в отделении фиксированного набора проверки от набора поездов. Например, еще одна распространенная стратегия оценки называется k-fold.

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

На рисунке ниже мы наблюдаем долю событий, распределенных по времени (15 дней) в обучающих и тестовых наборах. Около половины тестовых данных (clicks_test.csv) были отобраны в те же дни, что и набор поездов (вовремя), а другая половина была взята из двух дней сразу после этого, представляющих будущие прогнозы (вне времени).

Основываясь на этом наблюдении, моя CV-стратегия заключалась в том, чтобы отбирать образцы проверочного набора в соответствии с тем же временным распределением тестового набора. Ниже вы можете увидеть, как можно легко выполнить эту стратифицированную выборку с помощью Spark SQL Dataframe (кластер, развернутый в Google Dataproc). Для проверочного набора я отбирал 20 % каждого дня и все события за последние два дня (11 и 12).

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

Базовые прогнозы

До этого момента мне было трудно проводить исследовательский анализ данных, разрабатывать функции и реализовывать стратегию перекрестной проверки. По моему опыту, эти задачи обычно занимают около 60-80% ваших усилий в проектах машинного обучения. И если вы ошибетесь, они поставят под угрозу максимальную точность, которую могут достичь модели.

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

Мой подход №1 уже был описан в первом посте этой серии, просто используя исторический CTR для ранжирования объявлений без использования машинного обучения. Это был популярный базовый подход среди конкурентов, поскольку он давал оценку LB (MAP@12) 0,637. Просто для справки: официальный базовый уровень конкурса составлял 0,485, полученный путем ранжирования объявлений исключительно по их идентификаторам (случайный подход).

Сообщество Kaggle очень щедро делится идеями и подходами даже во время соревнований. Один из кагглеров поделился обнаруженной им утечкой данных. Эта утечка, основанная на наборе данных page_views.csv, выявила фактически нажатые объявления примерно для 4% посещений пользователей (display_ids) тестового набора. Для соревнования по машинному обучению обмен утечкой данных был своего рода честной игрой и создал новую основу для конкурентов. Мой подход № 2 заключался в том, чтобы использовать прогнозы подхода № 1 и корректировать рейтинг объявлений только для объявлений с просочившимися кликами, помещая их поверх других объявлений. Затем мой балл LB подскочил до 0,65317, и утечка данных использовалась во всех моих оставшихся заявках на конкурс, как и у других участников.

У большинства объявлений было очень мало просмотров (менее 10) для расчета статистически значимого CTR. Итак, моя интуиция подсказывала, что предварительные знания о вероятности кликов для других категориальных значений будут иметь некоторую предсказательную силу для невидимых событий. Таким образом, я вычислил средний CTR не только для идентификаторов объявлений, но и для других категориальных значений, то есть P(клик | категория), и для некоторых двухпарных комбинаций: P(клик | категория1, категория2).

Категориальные поля, средний CTR которых обеспечивает более высокую прогностическую точность оценки CV, были ad_document_id, ad_source_id, ad_publisher_id, ad_advertiser_id, ad_campain_id, атрибуты документа (category_ids, topic_id, entity_ids) и их комбинации с event_country_id, которые моделировали региональные предпочтения пользователей.

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

В этом уравнении d — это количество отдельных объявлений, имеющих общее значение категории, а v — количество просмотров этих объявлений. Высокое значение d означает, что категориальное значение является слишком общим для использования в конкретном объявлении (например, «тема=политика»), что приводит к более низкому показателю CTR.
Высокий показатель v указывает на то, что объявления с таким категориальным значением имели много просмотров, что повышает статистическую значимость CTR. Например, CTR для конкретной кампании (категориальное значение) может быть более специфичным для объявления, чем при использовании исторического CTR рекламодателя (более высокий d), поэтому, возможно, в кампании было недостаточно просмотров ( v‹10, например) для статистической значимости, что приводит к более низкой достоверности CTR конкретной кампании по сравнению с историческим CTR рекламодателя.
Преобразование L og также применяется для сглаживания функции для очень популярных категорий/объявлений. Наконец, мы нормализуем показатель в диапазоне от 0,0 до 1,0, разделив его на m, которое представляет справочное число средних просмотров отдельных объявлений (v/d) для максимального уверенность (1,0). Я использовал m = 100 000 для этого соревнования.

Подход №3 заключался в средневзвешенном значении всех выбранных CTR по категориям, взвешенных по их доверию CTR. Такой подход улучшил мой балл LB до 0,65498.

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

Модели машинного обучения

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

Совместная фильтрация — матричная факторизация ALS

Коллаборативная фильтрация (CF) — пожалуй, самый популярный метод для рекомендательных систем. CF позволяют моделировать интересы пользователей, собирая информацию о предпочтениях или вкусах от многих других пользователей (сотрудничество) для предоставления персонализированных рекомендаций (фильтрация). Таким образом, этот метод был естественным первым кандидатом для оценки.

Матричная факторизация с чередующимися наименьшими квадратами (ALS) может применяться как основанная на модели CF для большой матрицы пользователей и элементов. Мы использовали реализация Spark ALS, которая обеспечивает распределенную обработку по кластеру и поддерживает неявные данные обратной связи (например, просмотры, клики, покупки, лайки и публикации), а также явные данные обратной связи (например, рейтинги фильмов или книг).

Первым шагом было создание разреженной матрицы полезности пользователей и документов (страниц контента, на которые ссылается реклама). Матрица заполнялась количеством просмотров каждого документа каждым пользователем. Преобразование журнала было необходимо для сглаживания подсчета просмотров, поскольку некоторые пользователи (или боты) просматривали одну и ту же веб-страницу много раз в течение 15 дней сбора данных о соревнованиях.

После многих попыток настройки гиперпараметров Spark Matrix Factorization ALS лучшая модель (представленная ниже) получила оценку MAP перекрестной проверки (CV) 0,56116, что намного ниже, чем предыдущие базовые уровни. Таким образом, эта модель не использовалась в моем окончательном ансамблевом решении.

Возможной причиной такого плохого результата был холодный запуск пользователей — среднее количество просмотров страниц пользователем составляло всего 2,5 из коллекции из более чем 2 миллионов страниц, что затрудняло для подхода CF определение предпочтений пользователей и выполнение такого анализа. большая и разреженная матрица.

Градиентные деревья решений

Стандартный CF использует только матрицу полезности между пользователями и элементами (документами). Для этого конкурса было огромное количество атрибутов, связанных с контекстом посещения, целевой страницей и рекламой. Таким образом, мы попробовали подход Обучение рейтингу, чтобы воспользоваться такой богатой дополнительной информацией.

Используемой моделью машинного обучения были Градиентные деревья принятия решений (GBDT), которые представляют собой ансамбль многих деревьев решений (слабых учеников). Подобно Случайным лесам (RF), каждое отдельное дерево обучается с подвыборкой обучающих экземпляров (т.н. бэггинг) и подвыборкой атрибутов (бэггинг признаков), чтобы получить отдельные модели с разными точками зрения на данные. В отличие от RF, GBDT присваивает больший вес обучающим экземплярам, ​​ошибочно классифицированным предыдущими деревьями, повышая точность модели и делая ее более надежным классификатором.

Я протестировал два фреймворка GBDT, реализация которых была очень быстрой и экономичной для больших наборов данных: XGBoost и LightGBM. В нашем контексте они позволили сосредоточиться на оптимизации рейтинга объявлений для данного посещения пользователем страницы (display_id) вместо того, чтобы пытаться предсказать, были ли нажаты отдельные объявления или нет. XGBoost с ранжированием объективно оптимизированного обучения на основе метрики MAP (официальная метрика оценки соревнований), в то время как LightGBM оптимизирован на основе другой метрики ранжирования под названием NDCG.

Атрибуты, используемые в моделях XGBoost, более подробно описанные в первом посте, — это идентификаторы категорий One-Hot Encoded (OHE), средний CTR по категориям и их достоверности, сходство контекстных документов (косинусное сходство между профилями целевых страниц — категориями, темы, объекты и профили рекламных документов), сходство предпочтений пользователей (косинусное сходство между профилем пользователя и профилем рекламных документов). Такое количество атрибутов, особенно идентификаторов категорий OHE, приводит к очень разреженным векторам признаков с размерностью более 126 000 позиций и только 40 ненулевыми признаками.

Настройка гиперпараметров XGBoost сложна, и это руководство по настройке оказалось для меня очень полезным. Лучшая модель XGBoost (Подход №4) получила оценку LB 0,66821 (гиперпараметры показаны ниже) — большой скачок по сравнению с базовыми моделями. На обучение ушло около трех часов на одном сервере с 32 процессорами и 208 ГБ ОЗУ (тип машины n1-highmem-32 в Google GCE).

Для моделей LightGBM я использовал в качестве входных данных только числовые атрибуты (CTR и сходство), игнорируя категориальные поля OHE. Обучение на таких данных проходило довольно быстро, менее 10 минут. Удивительно, но с LightGBM (подход №5) я смог получить лучшую модель, чем с XGBoost (оценка LB 0,67073). Моя гипотеза состоит в том, что многомерные категориальные признаки, закодированные с помощью OHE, усложнили получение случайного набора очень предсказуемых упакованных признаков для построения деревьев. Фактически, некоторые конкуренты сообщили об отдельных моделях GBDT с оценкой выше 0,68, используя исходные категориальные идентификаторы в том виде, в каком они были предоставлены (без OHE или хэширования признаков), вероятно, потому, что тысячи деревьев в ансамбле GBDT могли игнорировать шум и моделировать такое представление идентификаторов.

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

objective = lambdarank
boosting_type = gbdt
num_trees = 30
num_leaves = 128
feature_fraction = 0.2
bagging_fraction = 0.2
max_bin = 256
learning_rate = 0.2
label_gain = 1,30

Подробнее о части III

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

Первоначально опубликовано на https://medium.com 26 июля 2017 г.