6% лучших решений из 2587 соревнующихся команд

Конкурс

Ссылка на страницу конкурса: https://www.kaggle.com/competitions/otto-recommender-system/overview

Репозиторий решения GitHub: https://github.com/ajisamudra/kaggle-otto-multi-objective-recsys

Задание

Вырезано из обзора соревнований

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

Следовательно, задача

Учитывая последовательность действий клиентов в режиме реального времени, предскажите 20 самых популярных товаров, которые каждый покупатель хочет нажать, добавить в корзину и заказать”.

Иллюстрация от OTTO о модели, которую мы хотим построить.

Показатель оценки

Данные

Данные состоят из 4 столбцов: сеанс, помощь, ts и тип. Вроде бы все просто, но мы можем подходить к данным с помощью различных алгоритмов. OTTO сделала набор данных общедоступным здесь https://github.com/otto-de/recsys-dataset.

session - the unique session id
events - the time ordered sequence of events in the session
aid - the article id (product code) of the associated event
ts - the Unix timestamp of the event
type - the event type, i.e., whether a product was clicked, added to the user's cart, or ordered during the session

Учитывая этот формат набора данных, это похоже на соревнование H&M, где данные не готовы к обучению. Нам нужно спроектировать конвейер данных и предварительно обработать его, прежде чем мы вызовем model.fit().

Статистика набора данных

При более подробном рассмотрении данных в наборе поездов есть 12,89 млн сеансов и 1,86 элемента. Сессия эквивалентна 1 уникальному пользователю за данный период наблюдения. Всего 216 млн событий, из которых 194 млн кликов, 16,9 млн корзин и всего 5 млн заказов. Это огромный набор данных с небольшой долей событий заказа.

Как насчет статистики на уровне сеанса? Гистограмма количества событий за сеанс выглядит следующим образом.

number of events per session
mean: 16.80
std: 33.58
min: 2
50%: 6
75%: 15
90%: 39
95%: 68
max: 500

Это широкий диапазон значений. Модель должна быть в состоянии рекомендовать релевантные элементы, указанные как минимальное событие от 2 и максимальное событие от 500.

Решение

Решением стала двухэтапная модель, в которой есть (1) поиск кандидатов и (2) ранжирование.

Поиск кандидатов

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

В качестве модели отзыва я использовал различные стратегии.

1. Все прошлые элементы в сеансе
2. Нажмите элемент-совместное посещение
3. Покупки предмета-совместное посещение
4. Buy2buy предмет-совместное посещение
5. Популярные предметы за неделю< br /> 6. Элемент ближайших соседей во встраивании Word2Vec
7. Элемент ближайших соседей в встраивании Matrix Factorization

С помощью этих стратегий у нас есть средневзвешенный отзыв@150 = 0,6339 и подробный отзыв для каждого события следующим образом: отзыв клика@150 0,62512, отзыв корзины@150 0,50515 и отзыв заказа@150 0,6998.

Рейтинг

Ранжирование будет больше ориентироваться на точность. Это означает, что модель направлена ​​на исправление порядка сотен кандидатов и выбор только 20 лучших элементов.

У меня есть 1 модель для каждого будущего события, т.е. клик, корзина, заказ. Для каждой модели событий я использую CatBoostRanker, CatBoostClassifier и LGBMClassifier. Судя по экспериментам, у CatBoostRanker были лучшие оценки CV, чем у других. Я использую баллы из этих 3 разных алгоритмов, чтобы сделать ансамблевые баллы.

Отрицательная выборка
В контексте ранжирования машинного обучения обучающие данные должны содержать как положительные, так и отрицательные выборки. Положительные образцы — это фактические события сеанса, мы помечаем их как 1 (нажатие/добавление в корзину/заказ). Отрицательные образцы — это образцы, которые мы помечаем как 0 (полученные на шаге 1, но фактически не нажатые/не добавленные в корзину/не заказанные). Зачем нужны отрицательные образцы? Потому что мы будем использовать ранжирование ML не только для сортировки товаров, которые были нажаты/добавлены в корзину/заказаны в ходе сеанса, но также и для элементов, которые не были нажаты/добавлены в корзину/заказаны в ходе сеанса. Я случайным образом выбираю отрицательных кандидатов, чтобы соотношение положительное:отрицательное = 1:10. Я экспериментировал с другим соотношением (1:10, 1:15, 1:20), но существенных различий в баллах CV не было, поэтому я решил использовать 1:10, потому что это наименьшее значение, и с его помощью я могу сэкономить немного памяти.

Функции
Есть 3 типа функций:
1. Функция сеанса. groupby(“session”).agg() . Пример: сколько длится сеанс в минутах, сколько уникальных item_id в сеансе, сколько кликов/корзины/заказов

2. Функция элемента. groupby(“помощь”).agg() . Пример: сколько кликов/корзины/заказов за неделю, каков cvr кликов к заказу, среднее/стандартное количество кликов/корзин/заказов за последнюю неделю (чтобы зафиксировать аномальную тенденцию)

3. Функция элемента сеанса. groupby([“сеанс”, “помощь”]).agg(). Пример: сколько кликов/корзины/заказов, time_lapsed_since_the_last_event, оценка давности

4. Функции сходства (косинусное сходство, евклидово расстояние) между последним элементом в сеансе и элементом-кандидатом. Пример: косинусное сходство во встраивании Word2Vec/Matrix Factorization.

Поскольку большинство положительных кандидатов были получены из `прошедших элементов в сеансе`, есть одна важная функция, на которую опирается ранжировщик, а именно экспоненциальный затухающий показатель недавности. Он придает больший вес недавним предметам, чем старым. Другим вариантом этой функции является экспоненциально затухающая оценка давности с учетом типа, где я добавляю вес различным типам событий: щелчку/добавлению в корзину/заказу.

Ансамбль

Я использовал средневзвешенное значение оценок нормализованных моделей. Поскольку оценка каждого алгоритма имела разный диапазон значений, мне нужно выполнить нормализацию, чтобы диапазон был между 0 и 1.

Обучение и закрытие

Конкурс научил меня многому о реальных системах рекомендаций, и одной из проблем был огромный набор данных. Учитывая ограниченный объем памяти (2x 8 ГБ), мне нужно тщательно подумать о том, как мне обрабатывать данные. Решением этой проблемы является выборка и фрагментация данных. Выборка, чтобы распределение выборки оставалось таким же, как распределение генеральной совокупности.

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

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

2. Раздражать. Я использовал его для поиска кандидатов и создания признаков сходства. Это быстрее, чем векторы с необработанными ключами, с компромиссом в точности.

3. Трилайт. Я использовал его для более быстрого вывода LGBM.

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

Я надеюсь, что этот пост может быть полезным для всех, кто хочет реализовать подобные проекты в будущем. Спасибо, что читали все это время!