Несколько дней назад завершился AI Journey Contest — ежегодное соревнование по машинному обучению от Сбера. В этой статье я расскажу о своем опыте участия в этом соревновании в прошлом году, его особенностях, а также подробно разберу решение, которое привело меня к победе.
О соревновании
В 2023 году конкурс включал пять треков, я победил в треке Personal AI, который был посвящен рекомендательным системам. Участники должны были решить три подзадачи:
Рекомендации треков в музыкальном сервисе
Рекомендации товаров на маркетплейсе
Рекомендации банковских продуктов
Победитель определялся по среднему качеству рекомендаций во всех трёх задачах.
Соревнование проходило в довольно нестандартном формате. Организаторы предоставили участникам только описание задачи и небольшой пример данных.
На основе этого необходимо было подготовить код для обучения моделей и генерации рекомендаций, который затем запускался на сервере организаторов, где были доступны полные данные. Качество сделанных рекомендаций автоматически оценивалось, и участникам давалась обратная связь в виде значения метрики, рассчитанной на части специальной тестовой выборки.
Отправлять свое решение можно было до 5 раз в день в течение полутора месяцев. По окончании соревнования финальные решения участников оценивались на оставшейся части тестовой выборки, значение метрики на которой использовалось для определения победителей.
Решения были ограничены по времени исполнения (100 минут на обучение и предсказание) и доступным вычислительным ресурсам (32 Гб оперативной памяти, GPU A100 80 ГБ).
Специфика соревнования заключалась в том, что участникам не были предоставлены полные данные. Обычно в соревнованиях по машинному обучению данные предоставляются в полном объеме, их можно использовать для анализа, обучения и тестирования моделей без отправки в проверяющую систему. Здесь же приходилось разрабатывать модели «вслепую», полагаясь лишь на результаты автоматических проверок, количество которых было ограничено.
Первая задача: рекомендации музыкальных треков
В рамках первой задачи необходимо было разработать алгоритм, который будет рекомендовать 10 треков (из 1,5 млн доступных в музыкальном сервисе), которые пользователь захочет прослушать в рамках продолжения сессии.
Решения оценивались по метрике Mean Average Precision. Метрика основывается на сравнении предложенных треков с реально прослушанными в продолжении сессии: чем больше пересечение, и чем выше «угаданные» треки находятся в списке рекомендаций, тем лучше значение метрики.
Данные в этой задаче представляли из себя сессии (последовательности прослушанных треков), где по каждому треку известен его уникальный идентификатор, момент начала прослушивания, длительность прослушивания, а также идентификатор исполнителя. У пользователя могло быть несколько сессий, и была возможность идентифицировать сессии одного пользователя. Кроме того, были доступны анонимизированные характеристики пользователей и треков.
Для обучения моделей были предоставлены сессии за 12 недель работы сервиса, а для тестирования — сессии за последующие 4 недели. Из тестовых сессий были исключены два последних трека (на основе сопоставления списка рекомендаций с этими двумя треками рассчитывалась метрика в задаче).
Подход к решению
При большом количестве треков и пользователей непосредственно оценить тяжелой моделью склонность каждого пользователя к каждому треку вычислительно сложно. В связи с этим, я использовал довольно распространенный в рекомендательных системах подход, состоящий из двух этапов:
Отбор кандидатов. Из миллиона треков различными способами отбираются несколько сотен кандидатов, которые с наибольшей вероятностью понравятся пользователю.
Реранжирование. Из этих кандидатов при помощи более сложной модели отбираются финальные топ-10 треков.
Отбор кандидатов
Отбор кандидатов я реализовал преимущественно при помощи статистики совстречаемости. На основе всех доступных сессий можно для каждого трека выделить и сохранить топ-N треков, которые чаще всего следовали после него, а затем применить эту статистику к последнему треку в сессии, для которой нужно сделать рекомендации. Такой подход можно всячески развить и усложнить. В частности, я брал в качестве кандидатов треки, которые чаще всего следовали за:
таким последним треком;
таким последним треком в этот конкретный день;
таким последним треком у этого пользователя;
такими последним и предпоследним треком;
такими последним и предпоследним треком в этот конкретный день;
такими последним и предпоследним треком у этого пользователя.
При расчете статистики можно отбирать топ-треков как по количеству, так и по длительности прослушивания. Кроме того, можно и нужно при расчете статистики использовать не только сессии, предоставленные для обучения, но и тестовые сессии.
Помимо этого, я брал в качестве кандидатов ранее прослушанные в рамках сессии треки. Этот простой подход особенно эффективен для музыкальных сервисов, так как пользователи часто возвращаются к ранее прослушанным трекам.
Для реализации формирования кандидатов я использовал библиотеку cudf — аналог pandas, работающий на GPU. Это позволило существенно ускорить операции groupby, merge и сортировки, активно использующиеся в расчетах статистики совстречаемости, что было критично в условиях ограничений на время исполнения решения.
Реранжирование
Для реранжирования отобранных кандидатов и формирования итогового списка рекомендаций я использовал CatBoostRanker. Выборка для обучения этой модели формировалась следующим образом:
Для обучения этой модели из сессий откладывались два последних трека — они использовались для формирования целевой переменной.
На остатках сессий рассчитывалась статистика совстречаемости и генерировались кандидаты вышеописанными методами.
Полученные кандидаты затем размечались: 1 — если кандидат совпадает с одним из двух реально прослушанных в рамках продолжения сессии треков, 0 — в противном случае.
Стоит отметить, что 0 и 1 в данном случае выступают не классами, а рангами, и модель обучается предсказывать для кандидатов такие скоры, чтобы кандидаты с рангом 1 (реально прослушанные) получали скор выше кандидатов с рангом 0. Подход к формированию обучающей выборке на примере одной сессии представлен на иллюстрации:
Для применения обученной модели мы всё так же генерируем кандидатов, делаем предсказания реранжирующей моделью, сортируем кандидатов по полученному скору, и выдаем топ-10 кандидатов в качестве рекомендаций.
Что касается переменных реранжирующей модели, то наиболее сильными из них были ранги кандидата по каждому из методов формирования кандидатов. Например, переменная, показывающая, входит ли кандидат в топ-N самых прослушиваемых треков после последнего трека в сессии, а если входит, то на каком месте в этом топе он находится.
Помимо рангов, хороший эффект давала переменная, описывающая то, как часто данный трек пропускают (слушают очень короткое время) и её вариации (как часто пропускают треки данного исполнителя, как часто конкретный пользователь пропускает треки данного исполнителя и т.д.). Это было связано с тем, что по условию задачи нужно было рекомендовать треки, которые пользователи прослушают хотя бы 30 секунд.
Вторая задача: рекомендации товаров на маркетплейсе
Вторая подзадача была схожа с первой: нужно было на основе взаимодействия пользователя с товарами на маркетплейсе (просмотр, добавление в избранное, покупка и т. п.) рекомендовать товары, которые пользователь захочет купить в будущем.
Решения оценивались по метрике NDCG: рекомендованные товары сравнивались с теми, которые пользователь купил в течение следующей недели. Чем больше пересечение, и чем выше «угаданные» товары находятся в списке рекомендаций, тем лучше значение метрики.
Данные представляли из себя историю взаимодействия пользователей с маркетплейсом за 4 недели: были известны идентификатор пользователя, идентификатор товара, категория товара, тип взаимодействия (просмотр/избранное/покупка) и дата. Кроме того, были предоставлены анонимизированные характеристики пользователей.
В качестве тестовой выборки был предоставлен набор пользователей, для которых нужно было сделать рекомендации на следующую неделю.
Общий подход к решению был схож с первой задачей — отбор кандидатов и реранжирование.
Отбор кандидатов
Ключевыми способами отбора кандидатов были методы, основанные на статистике, какие товары чаще всего встречались после N последних товаров в истории пользователя, с разными вариантами взвешивания в зависимости от типа взаимодействия с товаром в истории, и временем, прошедшим с момента взаимодействия.
В отличие от первой задачи, по условию нужно было рекомендовать новые для пользователя товары, поэтому кандидаты, с которыми пользователь уже взаимодействовал, наоборот, исключались.
Кроме того, использовался ещё один способ отбора кандидатов — на основе матричного разложения, а именно модели Alternating Least Squares из библиотеки implicit. В результате обучения такой модели получаются вектора пользователей и товаров. Для формирования кандидатов достаточно перемножить вектор пользователя с вектором каждого из товаров и отобрать топ самых релевантных.
Реранжирование
Наиболее важными переменными в модели реранжирования, как и в первой задаче, были ранги по каждому из методов отбора кандидатов, а также их агрегаты: медианный ранг кандидата; в скольких методах отбора кандидат входил в топ-10 и т. п.
Хороший прирост давали переменные, описывающие взаимодействие пользователя с товарами той же категории.
Наконец, поскольку рекомендовать нужно было товары, которые пользователь склонен именно купить, а не просто посмотреть, в модели использовались переменные, характеризующие конверсию (соотношение просмотров к покупкам) у товара-кандидата и его категории.
«Холодные» рекомендации
Важным особенностью этой задачи было то, что по половине клиентов, для которых нужно было сделать рекомендации, отсутствовала история. Для таких клиентов не применимы ранее описанные методы отбора кандидатов, и нужно было сделать так называемые «холодные» рекомендации. Мой подход к таким клиентам основывался на единственной доступной по ним информации (неких анонимизированных характеристиках). На основе этих переменных можно по другим пользователям, по которым доступна история покупок, построить модели склонности (бинарные классификаторы, предсказывающие, покупал пользователь данный товар, или нет) к нескольким сотням самых популярных товаров. А затем сделать этими моделями предсказания для новых пользователей и взять в качестве рекомендации те 20 товаров, предсказанная склонность к которым оказалась максимальной.
Третья задача: рекомендации банковских продуктов
Последняя задача заключалась в том, чтобы на основе истории взаимодействия клиента с банковскими продуктами, наборе анонимизированных характеристик клиента и продуктов порекомендовать 5 продуктов, которые клиент будет наиболее склонен приобрести. Эта задача отличалась от предыдущих тем, что множество продуктов, из которого нужно было сделать рекомендации, было сильно меньше: всего 19, что позволило отойти от двухстадийного подхода, и оценивать склонность каждого клиента к каждому продукту. В частности, я обучал 19 моделей, прогнозирующих вероятность взятия клиентом каждого из продуктов, после чего отбирал продукты с наибольшей вероятностью взятия. Это довольно типовая задача бинарной классификации, хороший результат в которой помогли получить feature engineering и ансамблирование.
Заключение
AI Journey Contest 2023 оказался необычным и достаточно сложным соревнованием, за счет формата (отсутствия непосредственного доступа к данным) и необходимости решать сразу три задачи вместо одной. Очень рад, что удалось победить в этом контесте.
По мотивам соревнования коллеги из Сбера подготовили Sber RecSys Benchmark — платформу, которая позволяет всем желающим тестировать собственные модели рекомендательных систем на различных наборах данных.