Что такое matrix factorization для рекомендаций?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Matrix Factorization для рекомендаций
Matrix Factorization — это техника в системах рекомендаций, которая разложит матрицу "user-item" на две меньшие матрицы. Это позволяет обнаружить скрытые паттерны в предпочтениях пользователей и предсказать rating для невидимых пар user-item.
Основная идея
Представим movie recommendation систему. У нас есть матрица user-item:
Movie1 Movie2 Movie3 Movie4
User1 5 3 ? 2
User2 ? 4 5 1
User3 2 1 4 ?
User4 3 ? 2 5
Где:
- Строки = пользователи (1000s)
- Столбцы = фильмы (10000s)
- Значения = рейтинг (1-5) или 0 если not watched
- ? = неизвестные рейтинги (что нам нужно предсказать)
Наблюдение: эта матрица разреженная (sparse) — большинство значений = 0 или ?
Matrix Factorization идея: матрица R большого ранга, но может быть аппроксимирована произведением двух матриц меньшего ранга:
R (n_users x n_items) ≈ U (n_users x k) * V^T (k x n_items)
Где k = число скрытых факторов (latent factors), например k=50
Интерпретация
U матрица (user embeddings):
- Каждый пользователь представлен вектором из k чисел
- Каждое число = "предпочтение" к скрытому фактору
- Например: [любит action, не любит romance, любит drama]
V матрица (item embeddings):
- Каждый фильм представлен вектором из k чисел
- Каждое число = "strength" скрытого фактора в фильме
- Например: [много action, немного romance, много drama]
Предсказание рейтинга:
rating(user_i, item_j) = dot_product(U[i], V[j])
= U[i,0]*V[j,0] + U[i,1]*V[j,1] + ... + U[i,k]*V[j,k]
Похожие пользователи -> похожие U[i] Похожие фильмы -> похожие V[j]
Математическое формулирование
Цель: минимизировать RMSE (Root Mean Squared Error) на известных рейтингах
L = sum((R[i,j] - U[i] @ V[j]^T)^2) + lambda * (||U||^2 + ||V||^2)
Где:
- первая часть = reconstruction error
- вторая часть = regularization (избегаем overfitting)
- @ = матричное умножение
Алгоритм: Alternating Least Squares (ALS)
Это стандартный алгоритм обучения Matrix Factorization:
- Инициализировать U и V случайно
- Повторять N раз: a. Зафиксировать V, оптимизировать U (least squares) b. Зафиксировать U, оптимизировать V (least squares)
# Шаг a: обновить U (с V зафиксирована)
for i in range(n_users):
U[i] = (V^T @ V + lambda*I)^-1 @ V^T @ R[i]
# Шаг b: обновить V (с U зафиксирована)
for j in range(n_items):
V[j] = (U^T @ U + lambda*I)^-1 @ U^T @ R[:,j]
Пример реализации
import numpy as np
from scipy.sparse import csr_matrix
class MatrixFactorization:
def __init__(self, n_users, n_items, n_factors=50, learning_rate=0.01, lambda_=0.01):
self.U = np.random.randn(n_users, n_factors) * 0.01
self.V = np.random.randn(n_items, n_factors) * 0.01
self.lr = learning_rate
self.lambda_ = lambda_
def fit(self, R_train, n_epochs=100):
"""
R_train: sparse матрица user-item ratings
"""
n_users, n_items = R_train.shape
for epoch in range(n_epochs):
# SGD: обновляем U и V для каждого known рейтинга
for u, i in zip(*R_train.nonzero()):
# Ошибка предсказания
r_true = R_train[u, i]
r_pred = np.dot(self.U[u], self.V[i])
error = r_true - r_pred
# Gradient descent
self.U[u] += self.lr * (2 * error * self.V[i] - self.lambda_ * self.U[u])
self.V[i] += self.lr * (2 * error * self.U[u] - self.lambda_ * self.V[i])
# Печать ошибки
if (epoch + 1) % 10 == 0:
rmse = self.compute_rmse(R_train)
print(f"Epoch {epoch+1}, RMSE: {rmse:.4f}")
def predict(self, user_id, item_id):
"""Предсказать рейтинг для пары (user, item)"""
return np.dot(self.U[user_id], self.V[item_id])
def compute_rmse(self, R_true):
"""Вычислить RMSE на known рейтингах"""
errors = []
for u, i in zip(*R_true.nonzero()):
r_true = R_true[u, i]
r_pred = self.predict(u, i)
errors.append((r_true - r_pred) ** 2)
return np.sqrt(np.mean(errors))
# Использование
R_train = csr_matrix([
[5, 3, 0, 2],
[0, 4, 5, 1],
[2, 1, 4, 0],
[3, 0, 2, 5]
]) # Sparse матрица
mf = MatrixFactorization(n_users=4, n_items=4, n_factors=2)
mf.fit(R_train, n_epochs=100)
# Предсказать рейтинг User1 для Movie3
rating = mf.predict(0, 2) # Было ? -> теперь предсказано
print(f"Предсказанный рейтинг: {rating:.2f}")
Преимущества Matrix Factorization
- Scalability — работает с huge матрицами (миллионы users и items)
- Efficiency — быстрое обучение и inference
- Interpretability — latent factors имеют смысл
- Холодный старт — может работать с новыми items через similarity
- Implicit feedback — работает с лайками, просмотрами, не только ratings
Ограничения
- Холодный старт проблема — новый пользователь или item = нечего рекомендовать
- Не использует side information — текст, категории, metadata не используются
- Локальные minima — SGD может застрять
- Fixed dimension — число факторов k фиксировано
Варианты и улучшения
1. Biased Matrix Factorization:
r_pred = mu + b_user[u] + b_item[i] + U[u] @ V[i]^T
Где mu = global mean, b_user/b_item = bias
2. SVD++ (Netflix Prize winner):
- Учитывает implicit feedback (просмотры без rating)
3. Non-negative Matrix Factorization (NMF):
- U и V >= 0 (легче интерпретировать)
4. Tensor Factorization:
- Учитывает время (ratings меняются со временем)
Современные подходы
- Neural Collaborative Filtering — вместо матрицы используем нейросеть
- Factorization Machines — объединяет MF с feature interactions
- Deep Learning — embedding layers + neural networks
НО Matrix Factorization остаётся baseline и часто лучше для sparse данных.
Практический совет
# Netflix Prize (2009): Matrix Factorization выиграл!
# Это был момент, когда стало ясно:
# "Collaborative Filtering на основе MF это мощный инструмент"
# Ещё сегодня, 2026:
# - Spotify использует MF variants
# - Amazon use для recommendations
# - TikTok добавляет MF к neural моделям
Matrix Factorization — это foundation современных рекомендательных систем. Даже если используешь deep learning, понимание MF критично для интервью.