Где можно встретить рекомендательные системы?
С рекомендательными системами можно столкнуться там, где есть большое множество товаров и пользователей, которые хотят найти нужные для себя товары. Рекомендательные системы помогают отобрать наиболее релевантные для пользователя объекты, тем самым экономя его время. Приведём несколько примеров:
- YouTube рекомендует пользователям видео;
- На сайтах интернет-магазинов можно встретить блоки с рекомендациями товаров;
- Музыкальные сервисы наподобие Spotify или Яндекс.Музыки рекомендуют музыкальные треки.
Что такое «релевантные для пользователя товары» – это нетривиальный вопрос, который решается отдельно для каждой задачи исходя из бизнес-логики.
Поиск vs рекомендации
Отметим, что, хотя задачи поиска и рекомендаций кажутся похожими и, как мы увидим, могут использовать схожие методы, у них есть одно важное отличие: в задаче поиска есть сформулированный запрос от пользователя, а в задаче рекомендаций явного запроса нет, есть только история взаимодействий пользователя с объектами и наша надежда на то, что мы верно распознали его скрытые желания. Это различие объясняет некоторые особенности дизайна рекомендательных систем, которые мы подробнее обсудим в конце этого параграфа, при разборе классического пайплайна рекомендательной системы.
Формализация задачи
Explicit и Implicit feedback
Введём ряд обозначений. Пусть у нас есть множество пользователей и множество объектов . Для каждого пользователя есть множество объектов , с которыми он взаимодействовал и которым поставил рейтинги . Рейтинг (его также называют фидбеком) – это некоторая характеристика взаимодействия пользователя с объектом; про него можно думать, как про некоторый таргет, который мы выбрали для оптимизации рекомендательной системы.
Таким образом, задачу рекомендательных систем можно переформулировать в следующем виде: для каждого пользователя необходимо оценить значение для и выбрать несколько товаров с наибольшим . Иными словами, надо научиться среди непоказанных пользователю товаров находить те, которые заинтересовали бы его больше всего.
Приведем несколько примеров фидбека:
- Для товара – факт добавления в корзину;
- Для музыки – дослушали ли трек до конца;
- Для статьи – лайк/дизлайк;
- Для видео – время его просмотра или факт просмотра, например, наполовину.
Как правило, фидбек разделяют на два типа – explicit и implicit. Из-за различия для каждого фидбека есть разные техники обработки и использования, которые будут обсуждаться в параграфе про матричные факторизации.
Explicit, или явный фидбек – это такие действия пользователя, по которым точно можно понять, понравился ли ему объект. Это может быть оценка, поставленная, фильму, лайк/дизлайк к видео или рецензия на купленный товар. Такого фидбека очень мало, но он наиболее точно характеризует отношение пользователя к товару.
Implicit, или неявный фидбек – это любая другая информация о действиях пользователя на сайте. Он выступает в качестве прокси к явному фидбеку. Например, факт того, что пользователь досмотрел видео до конца, не говорит о том, понравилось ли оно ему, однако можно сделать предположение, что большинству досмотревших видео до конца оно понравилось. Приведем основные примеры неявного фидбека: клик на статью, время просмотра видео, покупка товара. Обычно такого сигнала в разы больше, чем явного, однако он более шумный, и не стоит доверять ему так же, как явному. Например, при оптимизации кликов на статью может получиться так, что рекомендательная система научится находить кликбейт, а не интересные пользователю статьи – это может плохо отразиться на сервисе в долгосрочной перспективе.
Ранжирующая модель
Задачу построения рекомендательной системы можно формулировать в качестве задачи классификации (клик/не клик) или регрессию (сколько звёзд пользователь поставит объекту), но это не самые распространённые стратегии.
Обратим внимание, что нам на самом деле не обязательно уметь точно оценивать рейтинги . Достаточно уметь для пользователя и набора объектов генерировать перестановку этих объектов в порядке убывания рейтинга. Модель, решающую данную задачу, называют ранжирующей.
Опишем классический пайплайн применения ранжирующей модели для одного пользователя. На вход подаются признаки пользователя и объекта, и для пары пользователь-объект на основе этих признаков выдается некоторое число, ответ модели. Далее мы сортируем объекты в порядке его убывания. Из полученной перестановки обычно берут несколько первых объектов для показа пользователю.
Более подробно о том, как решается задача ранжирования, вы можете прочитать в соответствующем параграфе.
Коллаборативная фильтрация
Рассмотрим матрицу взамодействий пользователя, приведённую выше. Что можно порекомендовать Кате, исходя из исторических данных? Можно заметить, что взаимодействия Кати похожи на взамодействия Пети (так как они оба лайкали объекты 1 и 8). Иными словами, их интересы в чём-то похожи, поэтому Кате можно порекомендовать, например, объект 3 (так как он понравился Пете). Можно проделать аналогичное упражнение с Петей и сделать вывод, что ему не стоит рекомендовать объект 10.
Можно решать и транспонированную задачу: для лайкнутого пользователем объекта искать похожие, то есть те, которые пользователи достаточно часто лайкали вместе с ним. Например, объекты 1 и 8 похожи друг на друга, так как их лайкали одни и те же пользователи, и точно так же похожи 1 и 3.
Проиллюстрированный выше подход называют коллаборативной фильтрацией. Он объединяет семейство методов рекомендаций, использующих сходство по истории взаимодействия между пользователем и товаром. Рассмотрим конкретные простые методы коллаборативной фильтрации.
User2User рекомендации
Введём меру похожести двух пользователей , которая тем больше, чем выше сходство между и . Для пользователя рассмотрим множество похожих на него пользователей где – настраиваемый гиперпараметр, в чём-то аналогичный порогу бинарного классификатора.
Допустим, мы хотим теперь оценить рейтинг , который пользователь поставил бы объекту . Сделаем это, опираясь на рейтинги, которые ставили похожие на пользователи. Например, можно взять взвешенное среднее:
Модуль добавляется для того, чтобы корректно обработать непохожих пользователей, то есть с пары с отрицательной похожестью, которая может возникнуть, если при построении взять достаточно маленькое .
Можно пойти дальше и усовершенствовать метод оценивания. У пользователей могут быть разные диапазоны оценок: кто-то ставит почти всегда в диапазоне 1-3, а кто-то предпочитает стаить 4-5. Иными словами, для разных пользователей оценка «нормально» (и соответственно, оценки «хорошо» и «плохо») могут соответствовать разным значениям рейтинга. Для устранения этой проблемы, можно брать не сырой рейтинг пользователя , а его отклонение от среднего всех оценок пользователя: . Таким образом, мы учитываем только разброс вокруг среднего и итоговая оценка будет выглядеть так:
Можно пойти еще дальше и учесть дисперсию оценок пользователей:
где – множество объектов, с которыми взаимодействовал пользователь .
В заключение приведём несколько вариантов оценки схожести пользователей:
- Мера Жаккара: где – множество понравившихся айтемов;
- Скалярное произведение общих рейтингов: ;
- Корреляция Пирсона:
- Дисконтированная корреляция Пирсона. Так как айтемов в пересечении в действительности не всегда может быть достаточно много, можно дисконтировать похожести, посчитанные по небольшому множеству айтемов, домножая корреляцию на .
Item2Item рекомендации
Теперь попробуем решать транспонированную задачу. Введем меру похожести объектов . Если нам нужно оценить рейтинг, который пользователь поставил бы ещё не виденному им объекту , то мы можем рассмотреть множество близких к объектов и оценить аналогично user2user подходу:
Меру схожести объектов можно задать как adjusted cosine:
где – множество пользователей, оценивших товар . Обратите внимание, что – это средняя оценка пользователя, а не объекта, то есть это не корреляция Пирсона – на практике данный подход обычно работает лучше.
Особенности коллаборативной фильтрации
Выделим ключевые особенности методов, основанных на коллаборативной фильтрации, о которых следует помнить при разработке рекомендательных систем:
- Они не опираются ни на какую дополнительную информацию кроме матрицы оценок , предполагая, что этого должно быть достаточно для улавливания качественного сигнала о схожести пользователей и товаров;
- Предложенные методы не применимы для новых объектов и пользователей – для них просто нет истории или она недостаточно информативна для того, чтобы методы могли давать более-менее точные оценки;
- Так как методы коллаборативной фильтрации основаны только на истории прошлых взаимодействий, рекомендательная система, построенная исключительно на их основе будет постепенно вгонять пользователя в информационный пузырь: эти методы не предполагают открытия новых интересов у пользователя, они способны только эксплуатировать уже имеющиеся.
Content-based рекомендации
Также помимо коллаборативной фильтрации существует content-based подход для построения рекомендаций: измерение похожести между объектами на основе их содержания. Например, две статьи про то, как заменить колесо на велосипеде можно считать похожими с точки зрения содержания. Иными словами, входом для content-based модели являются разные контентные признаки и характеристики товара (например, текст статьи, время публикации, картинки), а выходом является некоторое числовое представление объекта (эмбеддинг). Отметим, что никакую коллаборативную информацию такие модели не используют, они ничего не знают про других пользователей и про их взаимодействие с объектами. Например, Bert является чисто контентной моделью – он переводит текст в эмбеддинг.
Пусть у нас есть некоторый контентные эмбеддинги для каждого товара – например, мы применили обученный Bert для получения векторных представлений статей. Тогда мы можем посчитать скалярное произведение (или косинусное расстояние) до оценённых пользователем объектов и оценить рейтинги, как:
где – скалярное произведение или косинусное расстояние между двумя векторами, – множество оценённых пользователем объектов, а – гиперпараметр. Таким образом, высокие рейтинги получат объекты, похожие на те, что понравились пользователю – мы получили простую ранжирующую модель.
Плюс контентного подхода в том, что, в отличие от чисто коллаборативного подхода, он одинаково хорошо работает на новых и старых айтемах, так как контентные модели основаны только на статичной контентной информации, которая всегда доступна. Из минусов можно отметить, что похожесть по контенту может ещё больше загонять пользователя в информационный пузырь: например, контентная модель вряд ли сможет к кофемашине порекомендовать кофейные зерна, в то время как коллаборативный подход получит сигнал о том, что товары являются дополняющими напрямую из действий других пользователей.
Отметим, что существуют гибридные модели, совмещающие в себе коллаборативный и контентный сигналы. Например, такой моделью является DSSM.
Подробнее о контентных моделях вы узнаете в соответствующем параграфе.
Классический пайплайн рекомендательной системы
Мы разобрали несколько классических подходов к построению рекомендаций, теперь нужно обсудить, как это скомпоновать в единую рекомендательную систему.
Для начала сформулируем ряд свойств, которыми должна обладать хорошая рекомендательная система:
- При ранжировании товаров в порядке убывания нам хотелось бы учитывать как можно больше сигналов/фичей (как пользователя, так и объекта);
- Рекомендательная система должна работать достаточно быстро;
- Должен быть несложный механизм, позволяющий понятно учитывать «бизнес-логику» (например, если при прочих равных мы больше хотим показывать свежие статьи).
Для соблюдения первого пункта, очевидно, нужна ранжирующая модель. В качестве самой модели часто применяют бустинг – на табличных данных он, как правило, cправляется лучше, плюс он быстрее нейронных сетей с точки зрения времени применения.
Здесь не будет лишним упомянуть про feedback loop. Для обучения ранжирующей модели мы обычно берем прошлую историю взаимодействия пользователей с показанными ему объектами, считаем и составляем на основе этих оценок обучающий датасет. Таким образом, обучая новую модель, мы с некоторыми оговорками будем учиться предсказывать старую модель. Поэтому есть риск, что она застрянет в локальном оптимуме, из которого сложно выбраться. В качестве решения этой проблемы можно, например, подмешивать в выдачу случайные объекты и давать им больший вес в функции потерь. Таким образом, у нас появляется некоторое подмножество объектов, которые не были смоделированы нашей моделью. В качестве дополнительного плюса такого подхода мы в какой-то степени будем выбивать пользователя из его информационного пузыря, показывая объекты из категорий, которыми он еще не интересовался.
В реальной рекомендательной системе обычно от нескольких миллионов товаров и хотя бы несколько сотен тысяч пользователей в день (а чаще несколько миллионов). Обученная CatBoost модель на 5000 объектов отрабатывает где-то за 100-125ms на CPU. Фичи пользователей и объектов постоянно меняются, поэтому на каждый запрос пользователя мы должны заново скорить все объекты. Но тогда только на скоринг мы будем тратить порядка 25 секунд, а если это не CatBoost, а, например, нейронная сеть, то, скорее всего, ещё больше. Это очень существенные и необоснованные затраты.
В действительности, пользователю наверняка интересна лишь небольшая часть имеющихся у нас товаров. Можно попытаться сузить множество до потенциально интересных пользователю объектов и уже для них применить «тяжёлую» ранжирующую модель, которая определит финальную выдачу. Этот подход называется отбором кандидатов. К отбору кандидатов предъявляют два требования:
- он должен быть быстрым;
- он должен иметь хорошую полноту поиска подходящих пользователю объектов, то есть в полученной после отбора кандидатов подмножестве должны в избытке находиться интересные пользователю статьи/фильмы/продукты;
Приведем несколько подходов к отбору кандидатов:
- Эвристики: самые популярные товары, популярные за последних дней, популярные среди жителей этого города, недавно опубликованные;
- Коллаборативные: item2item или user2user рекомендации. Мы можем в оффлайне предподсчитывать все необходимые статистики и строить таблички из пользователя в множество подходящих айтемов или из айтема в айтемы. Также есть более сложные подходы на основе матричных разложений, о которых будет рассказано в соответствующем параграфе;
- Контентные методы: берём content-based эмбеддинги объектов и строим быстрый индекс для поиска ближайших объектов (например, HNSW). Подробнее о быстром поиске ближайших соседей вы можете почитать в параграфе про метрические методы. Далее, можем взять понравившиеся пользователю товары и найти похожие на них.
Обычно отбор кандидатов состоит из набора разных источников кандидатов, где каждый источник по смыслу пытается покрыть какой-то пользовательский аспект.
Двухступенчатая рекомендательная система уже обладает двумя хорошими свойствами, осталось предложить механизм, который позволит учитывать бизнес-логику. Под бизнес-логикой здесь понимается некоторое качество рекомендательной системы, которое хотелось бы иметь, но которое достаточно нетривиально, чтобы мы не стали зашивать его в саму ранжирующую модель. Приведем примеры возможных пожеланий:
- Реже показывать старые видео в ленте;
- Реже показывать слишком длинные видео или видео, снятые в плохом качестве;
- Обеспечить разнообразную для пользователя выдачу. Например, если пользователь интересуется кошками и машинами, А ранжирующая модель всем видео про кошек дала большую оценку, чем любому видео про машины, то получится, что лента пользователя будет состоять только из кошек, хотя ему также интересны и машины.
Все эти свойства подразумевают под собой небольшое переупорядочивание объектов после применения ранжирующей формулы. Этот механизм называется переранжированием (реранкингом).