Инструменты и кейс на MovieLens
Финальный урок: обзор библиотек рекомендаций и сквозной мини-кейс рекомендателя фильмов в духе датасета MovieLens — целиком на stdlib.
MovieLens — классический открытый датасет оценок фильмов, на котором традиционно учат и сравнивают рекомендательные алгоритмы.
Обзор инструментов
В реальных проектах алгоритмы из курса не пишут с нуля — берут проверенные библиотеки. Важно понимать, какая для чего.
| Библиотека | Сильна в | Когда брать |
| Surprise | Явный фидбэк, SVD/KNN, оценка метрик | Учебные и небольшие проекты на оценках |
| implicit | Неявный фидбэк, ALS, BPR, быстро | Клики/покупки, продакшн средних масштабов |
| LightFM | Гибрид: CF + контентные признаки | Холодный старт, нужны фичи товаров |
| RecBole | Десятки моделей, включая deep/sequential | Исследования, сравнение подходов |
Также в экосистеме: FAISS/HNSWlib и векторные БД для ANN-этапа, XGBoost/LightGBM/CatBoost для ранжирования, PyTorch для two-tower и трансформеров. Эти инструменты требуют сторонних пакетов, поэтому код ниже — не на них, а сквозная демонстрация идей на stdlib.
Кейс: рекомендатель фильмов
Соберём всё в один маленький конвейер на оценках в духе MovieLens: item-based похожесть фильмов → персональный прогноз для пользователя → отбор top-N. Данные крошечные, но логика — настоящая.
import math
from collections import defaultdict
# оценки пользователь -> {фильм: оценка}
ratings = {
"Аня": {"Матрица": 5, "Дюна": 4, "Титаник": 2, "Аватар": 4},
"Борис": {"Матрица": 5, "Дюна": 5, "Аватар": 4},
"Вера": {"Титаник": 5, "Дневник": 5, "Матрица": 1},
"Глеб": {"Матрица": 4, "Дюна": 4, "Аватар": 5, "Дневник": 1},
}
# вектор оценок по фильму (item -> {user: rating})
item_vec = defaultdict(dict)
for u, rs in ratings.items():
for film, r in rs.items():
item_vec[film][u] = r
def cosine(a, b):
common = set(a) & set(b)
if not common:
return 0.0
num = sum(a[u] * b[u] for u in common)
na = math.sqrt(sum(v*v for v in a.values()))
nb = math.sqrt(sum(v*v for v in b.values()))
return num / (na * nb) if na and nb else 0.0
def recommend(user, n=2):
seen = ratings[user]
scores = {}
for film in item_vec:
if film in seen:
continue
num = den = 0.0
for liked, r in seen.items():
s = cosine(item_vec[film], item_vec[liked])
num += s * r
den += s
if den > 0:
scores[film] = num / den
return sorted(scores.items(), key=lambda x: -x[1])[:n]
for film, score in recommend("Борис"):
print(f"Борису: {film} (прогноз {round(score, 2)})")Вывод:
Борису: Титаник (прогноз 4.73) Борису: Дневник (прогноз 4.71)
Борис любит фантастику (Матрица, Дюна, Аватар). Из невиденного «Титаник» получает чуть более высокий прогноз, чем «Дневник». Прогнозы близки и завышены — это честная иллюстрация ограничений крошечных данных: фильмы пересекаются почти по одним и тем же пользователям, поэтому их item-item похожести высоки и слабо различают вкусы. На реальном MovieLens с тысячами оценок такие различия становятся куда выразительнее, а нормировка похожестей и вычитание средних делают прогнозы аккуратнее.
Как работает под капотом и куда расти
Этот кейс — компактная item-based CF: тот же приём, что у Amazon, только на оценках вместо кликов. В настоящем MovieLens-пайплайне дальше идёт всё, что мы изучили: разложение матрицы для борьбы с разреженностью, контентные признаки фильмов для холодного старта, two-tower и ANN для масштаба, бустинг для ранжирования, метрики precision@k/NDCG и A/B-тест для проверки. Начав с такого ядра и постепенно подключая библиотеки, вы пройдёте путь от учебного примера до промышленной системы.
Частые ошибки
- Сразу хвататься за deep learning. На малых данных простая item-based CF или MF часто не уступает; усложняйте по необходимости.
- Брать библиотеку не под тип фидбэка. Surprise — про оценки, implicit — про клики; перепутать значит мучиться.
- Оценивать кейс только глазами. Даже маленький рекомендатель надо мерить метриками на отложенной выборке.
Итоги
- Surprise — для оценок, implicit — для неявного, LightFM — гибрид, RecBole — исследования.
- Реальный кейс собирает весь курс: похожесть, разложение, контент, масштаб, метрики.
- Item-based CF на оценках MovieLens — рабочее ядро, с которого удобно начинать.
- Усложнять модель стоит по мере роста данных, а качество всегда подтверждать метриками и A/B.