Модуль 17. Коллаборативная фильтрация¶
Чему вы научитесь в этом модуле
- Записывать задачу рекомендаций как заполнение разреженной матрицы взаимодействий.
- Объяснять коллаборативную фильтрацию: похожесть определяется по совместным лайкам, а не по описанию товара.
- Выводить матричное разложение и интерпретировать скалярное произведение факторов как предсказанную симпатию.
- Называть проблему холодного старта и описывать, чем её обычно компенсируют.
- Показывать, почему рекомендация популярного выглядит хорошо по офлайн-метрикам и при этом практически бесполезна.
Время: около двух недель. Пререквизиты: модуль 3 (скалярное произведение и матрицы).
Ноутбук: открыть в Colab · notebooks/17-collaborative-filtering.ipynb
Зачем нужен этот модуль¶
Рекомендательные системы — самое массовое применение машинного обучения: лента, интернет-магазин, стриминговый сервис решают, что показать, миллиарды раз в день. И это прикладная психология внимания: система оптимизирует не то, что вы хотели бы найти, а то, на что вы отреагируете. С этой стороны к ней мы вернёмся в модуле 19; пока разберём механику.
Вся задача помещается в одну картинку: есть матрица взаимодействий. Строки — пользователи, столбцы — товары, в клетках — лайки, оценки, покупки. Матрица почти пустая: каждый пользователь видел ничтожную долю всех товаров. Рекомендовать — значит угадать значения пустых клеток: что пользователь оценил бы высоко, если бы до этого товара добрался.
Коллаборативная фильтрация¶
Первый и самый живучий подход вообще не смотрит на содержание товара. Ему неважно, про что фильм и какого цвета кофта. Он анализирует только совместные лайки.
Идея в одну строку: тем, кому нравится то же, что и вам, нравится и то, чего вы ещё не видели. «Коллаборативная» — потому что рекомендация собирается из поведения множества пользователей, а не из свойств конкретного товара.
Существуют два зеркальных варианта. По пользователям (user-based): найти пользователей, похожих на вас, и предложить то, что любят они. По товарам (item-based): для товара, который вам нравится, найти товары, которые лайкают те же самые люди. Похожесть в обоих случаях — косинусная близость из модуля 3: столбец (или строку) матрицы превращаем в вектор и измеряем угол между ними.
Выберите пользователя. Сердечком отмечено то, что он уже любит; звездой — то, что рекомендует система; фон остальных элементов — предсказанный балл. Рекомендация приходит не из описания товара, а из того, что его лайкают те же самые люди, которым нравятся уже понравившиеся вам вещи. Система не знает, что «боевик» — это боевик; она знает, что его лайкают вместе с триллером.
Матричное разложение¶
Метод ближайших соседей работает, но плохо масштабируется: миллион пользователей — миллион сравнений на каждую рекомендацию. Более эффективная идея — сжать всех пользователей и все товары в короткие векторы.
Матричное разложение: приблизить огромную разреженную матрицу \(R\) произведением двух узких матриц:
Каждая строка \(U\) — короткий вектор пользователя, каждая строка \(V\) — вектор товара, оба живут в одном скрытом пространстве из \(k\) чисел. Предсказанная симпатия пользователя к товару — их скалярное произведение: то самое из модуля 3, измеряющее согласованность направлений. Совпали вкус и свойства — высокая предсказанная оценка.
Примечательно, что эти \(k\) чисел никто не задаёт вручную. Их находит градиентный спуск из модуля 4, минимизируя ошибку на известных клетках. И после обучения оси скрытого пространства нередко оказываются осмысленными: одна отвечает за измерение «серьёзное против лёгкого», другая — за жанр. Это по сути те же эмбеддинги из модуля 9, только выученные не из изображений, а из поведения пользователей.
Холодный старт¶
У коллаборативной фильтрации есть встроенная слепая зона. Новому пользователю нечего рекомендовать: он ещё ничего не лайкнул, его вектор пуст. Новый товар невидим: его никто не оценил, столбец пустой. Это холодный старт, и чистая CF на нём беспомощна.
Компенсируют его тем, на что CF принципиально не смотрит, — содержанием. Пока поведенческих данных нет, рекомендуют по свойствам: жанр, автор, цена. Как только лайки накопились, слово переходит к CF. Отсюда гибридные системы, которые вы соберёте в модуле 18.
Чем это обманывает¶
Первое честное ограничение — смещение к популярному. Популярный товар лайкают все, поэтому он оказывается похожим на всё и проникает в рекомендации каждому. Рекомендательная система, которая просто советует самое популярное, наберёт приличную офлайн-метрику — и при этом будет совершенно бесполезной: она не сообщает пользователю ничего, чего тот не увидел бы и без неё.
Отсюда база из модуля 1, которую обязана обыгрывать любая рекомендательная модель: «рекомендовать топ популярного». Это тривиальная база, и, как показал модуль 1, обыграть её осмысленно труднее, чем кажется. Модель, которая её не превосходит, ничего не рекомендует — она пересказывает рейтинг.
Скалярное произведение — сквозная нить курса. В модуле 3 оно измеряло похожесть векторов, в модуле 10 — сходство запроса и ключа в механизме внимания, здесь — совпадение вкуса пользователя и свойств товара. Один и тот же приём — угол между векторами — лежит в основе регрессии, внимания и рекомендаций. А смещение к популярному отсюда ведёт прямо в модуль 19: то, что система показывает чаще, лайкают чаще, и петля обратной связи замыкается.
Практическая часть¶
Часть 1. Работа с ноутбуком¶
Откройте notebooks/17-collaborative-filtering.ipynb. Только numpy и matplotlib, вычисления занимают секунды.
Что содержится внутри:
- Матрица взаимодействий и item-item CF с нуля: косинусная близость по столбцам, рекомендация для конкретного пользователя.
- Матричное разложение градиентным спуском: раскладываем \(R\) на \(U\) и \(V\), восстанавливаем пустые клетки. Скрытые факторы улавливают кластеры вкуса.
- Холодный старт: новому пользователю CF выдаёт бессмыслицу, откат на популярное спасает ситуацию.
- Смещение к популярному: база «топ популярного» против CF по честной метрике. Обыграть популярное труднее, чем кажется.
Часть 2. Собственная матрица¶
Возьмите любой источник совместных предпочтений: свои оценки фильмов вместе с друзьями, покупки, звёзды на репозиториях.
- Соберите матрицу взаимодействий. Насколько она разрежена?
- Посчитайте item-item рекомендации для себя. Осмысленны ли они?
- Постройте базу «топ популярного». Обыгрывает ли её ваша CF?
- Найдите товар с холодным стартом и объясните, что бы вы порекомендовали вместо пустоты.
Задание¶
- Реализуйте item-item CF на косинусной близости и покажите рекомендации для трёх пользователей.
- Разложите матрицу на \(U\) и \(V\) градиентным спуском. Постройте ошибку восстановления как функцию числа факторов \(k\).
- Постройте базу «рекомендовать топ популярного» и сравните с CF по метрике на скрытых клетках. Честно ли CF её обыгрывает?
- Введите нового пользователя без лайков и покажите, что выдаёт CF, а затем что даёт откат на популярное.
- Возьмите два скрытых фактора и нарисуйте товары точками в этом двумерном пространстве. Складываются ли они в осмысленные кластеры?
Проверка усвоения¶
- Что такое матрица взаимодействий и почему она разрежена?
- Чем коллаборативная фильтрация отличается от рекомендации по содержанию?
- Как интерпретируется скалярное произведение векторов пользователя и товара?
- Кто назначает скрытые факторы — и что их на самом деле находит?
- Что такое холодный старт и чем его компенсируют?
- Почему «рекомендовать популярное» — одновременно сильная база и слабый рекомендатель?
- Где ещё в курсе встречалось то же скалярное произведение?
Что дальше¶
В модуле 18 — нейронные рекомендатели и ранжирование: two-tower, последовательные модели, метрики ранжирования. И главный вопрос прикладных рекомендаций: почему офлайн-метрика и онлайн-эффект расходятся — модель, лучшая на исторических данных, в продакшене проигрывает, потому что данные она изменяет самим фактом своей работы.
Рекомендация — это заполнение пустых клеток матрицы. Коллаборативная фильтрация делает это по совместным лайкам, матричное разложение — скалярным произведением коротких векторов, а базой всему служит скучное «рекомендовать популярное».
Принцип
Рекомендатель, который не обыгрывает «топ популярного», ничего не рекомендует — он пересказывает рейтинг. Как и в модуле 1, тривиальную базу необходимо посчитать первой.