Матричные разложения
Раскладываем матрицу user-item на латентные факторы — база всех современных подходов
Идея матричных разложений
Коллаборативная фильтрация на основе kNN работает, но масштабируется плохо. Матричные разложения — элегантная альтернатива: вместо поиска соседей мы раскладываем матрицу оценок R на произведение двух маленьких матриц. Каждому пользователю и товару соответствует вектор «латентных факторов» — скрытых характеристик.
R — матрица оценок (m×n), P — матрица пользователей (m×k), Q — матрица товаров (n×k)
Что такое латентные факторы? Для фильмов это могут быть «комедия vs драма», «новый vs классический», «экшн vs спокойный». Мы не задаём их явно — модель находит сама. Предсказание оценки — скалярное произведение векторов пользователя и товара.
Предсказание: скалярное произведение латентных векторов
SVD — Singular Value Decomposition
Классическое SVD из линейной алгебры раскладывает любую матрицу:
U — ортогональная (m×m), Σ — диагональная (m×n), V — ортогональная (n×n)
Проблема: классическое SVD требует полностью заполненную матрицу. А в рекомендациях 99% ячеек пустые — пользователь оценил только малую часть каталога. Поэтому напрямую SVD не применимо, и нам нужны модификации.
Funk SVD — оптимизация через SGD
Simon Funk предложил простое решение на Netflix Prize (2006): не раскладывать всю матрицу, а минимизировать ошибку только на известных оценках. Оптимизируем через стохастический градиентный спуск (SGD):
K — множество известных оценок, λ — регуляризация
- Суммируем ошибку только по известным парам (u, i) — пропуски игнорируем
- Добавляем L2-регуляризацию, чтобы не переобучиться
- SGD обновляет p_u и q_i после каждой оценки — быстро сходится
- Часто добавляют bias-ы: r̂_ui = μ + b_u + b_i + p_u·q_i (глобальное среднее + bias пользователя + bias товара)
ALS — Alternating Least Squares
Альтернативный подход к оптимизации: вместо SGD чередуем два шага. Фиксируем Q — находим оптимальное P (обычный метод наименьших квадратов). Затем фиксируем P — находим оптимальное Q. Повторяем до сходимости.
- Каждый шаг — решение линейной системы уравнений, а не градиентный спуск
- Каждый подшаг — выпуклая задача → гарантированно находим оптимум
- Легко параллелится: обновления p_u для разных пользователей независимы
- Идеально подходит для распределённых систем (Apache Spark MLlib)
ALS vs SGD — когда что?
SGD — быстрее на одной машине, легко реализовать, хорошо работает с explicit feedback. ALS — лучше параллелится (стандарт в Spark), естественнее работает с implicit feedback, стабильнее сходится. Для production-систем с миллионами пользователей ALS + Spark — типичный выбор.
Implicit Feedback
В реальности явных оценок (1-5 звёзд) мало. Чаще есть только implicit feedback: клики, просмотры, покупки, время на странице. Hu, Koren & Volinsky (2008) предложили модификацию матричных разложений для этого случая.
Ключевая идея: вводим два понятия. Preference — нравится или нет (бинарная). Confidence — насколько мы уверены в этом.
p — preference (бинарная), c — confidence (растёт с количеством взаимодействий)
Если пользователь купил товар 5 раз — мы более уверены, что он нравится, чем если купил 1 раз. А отсутствие взаимодействия не означает «не нравится» — может, пользователь просто не видел товар.
NMF — Non-negative Matrix Factorization
NMF — разложение с ограничением: все элементы P и Q должны быть ≥ 0. Это даёт интерпретируемость: латентные факторы можно читать как «степень принадлежности» к теме.
- Фактор = тема/жанр, значение = «насколько этот фильм — комедия»
- Нет отрицательных значений → легче объяснить бизнесу
- Используется не только в RecSys: тематическое моделирование, анализ изображений
- Обычно чуть хуже по качеству, чем SVD/ALS, но выигрывает в интерпретируемости
Регуляризация в матричных разложениях
Без регуляризации матричное разложение легко переобучается — особенно при разреженных данных. Стандартные приёмы:
- L2-регуляризация весов (λ·(||P||² + ||Q||²)) — основной метод, всегда используется
- Bias-ы пользователей и товаров — вынесение систематических отклонений отдельно
- Число латентных факторов k — чем больше k, тем больше параметров и риск переобучения. Типичные значения: 20-200
- Ранняя остановка по валидационной метрике (RMSE на отложенных оценках)
Библиотека Surprise
Surprise — Python-библиотека для экспериментов с рекомендациями. Из коробки: SVD, SVD++, NMF, kNN-based CF, кросс-валидация.
from surprise import SVD, Dataset, accuracy
from surprise.model_selection import cross_validate
# Загружаем встроенный датасет MovieLens 100K
data = Dataset.load_builtin('ml-100k')
# SVD с 50 латентными факторами
algo = SVD(n_factors=50, n_epochs=20, lr_all=0.005, reg_all=0.02)
# 5-fold кросс-валидация
results = cross_validate(algo, data, measures=['RMSE', 'MAE'], cv=5, verbose=True)
print(f"Mean RMSE: {results['test_rmse'].mean():.4f}")Итого
- Матричные разложения: R ≈ P·Qᵀ — находим латентные факторы пользователей и товаров
- Классическое SVD не работает с пропусками → используем Funk SVD (SGD) или ALS
- ALS — стандарт для больших систем (Spark), SGD — быстрее на одной машине
- Implicit feedback: вводим confidence weights — чем больше взаимодействий, тем увереннее
- NMF — интерпретируемое разложение (все значения ≥ 0)
- Регуляризация обязательна: L2, bias-ы, выбор числа факторов k
- Surprise — отличная библиотека для старта экспериментов
Материалы
Классическая статья по матричным разложениям в RecSys
Документация библиотеки Surprise
Лекция Стэнфорда по матричным разложениям
Оригинальная статья по implicit feedback в матричных разложениях