Коллаборативная фильтрация — алгоритм рекомендаций, который ищет людей со схожими вкусами. Узнайте, как он работает и как внедрить его в Python. Начните сейчас!
Вы когда-нибудь задумывались, как Netflix предлагает сериалы, которые вы смотрите запоем? Или как Spotify собирает плейлист, будто знает вас лично? Секрет — в коллаборативной фильтрации, алгоритме, который не понимает ни фильмов, ни музыки, но находит людей со схожими вкусами. В этой статье разберём, как работает коллаборативная фильтрация, напишем простую реализацию на Python и обсудим её ограничения.
Представьте вечеринку, где вы никого не знаете. Кто-то замечает вашу футболку с Arctic Monkeys и говорит: «О, ты тоже их любишь?» Затем выясняется, что вы оба смотрели «Разделение» и играли в Baldur's Gate 3. Через пять минут вы понимаете — у вас почти одинаковые вкусы. Когда этот человек советует «Укрытие», вы доверяете, хотя ничего о нём не знаете. Потому что незнакомец уже доказал: вам нравится одно и то же. Это и есть коллаборативная фильтрация.
Алгоритм не хранит описания фильмов, не анализирует жанры или актёров. Для него каждый фильм — просто столбец в огромной таблице оценок. Вместо этого он задаёт вопрос: «Кто ещё ведёт себя как вы?» Если два пользователя поставили одинаковые оценки «Железному человеку», «Барби» и «Титанику», система считает их «вкусовыми близнецами». Когда один из них высоко оценивает «Матрицу», алгоритм предполагает, что и второму она понравится.
Коллаборативная фильтрация появилась в начале 1990-х. Исследователи проекта GroupLens заметили: люди, которые соглашались в прошлом, часто соглашаются и в будущем. Amazon, Netflix и Spotify применили эту идею в своих рекомендациях. Сегодня почти каждая крупная платформа использует коллаборативную фильтрацию как часть гибридной системы.
Для расчёта «похожести» пользователей нужна числовая метрика. Один из популярных способов — косинусная мера. Представьте оценки пользователей как векторы: вы — [5, 4, 1, 5], Келли — [5, 4, 1, 4]. Косинус угла между этими векторами показывает, насколько направления совпадают. Значение близкое к 1 означает почти идентичные предпочтения, к 0 — отсутствие связи. Формула выглядит пугающе: cos(θ) = (A·B) / (||A|| ||B||), но интуиция проста: чем ближе направления векторов, тем больше похожи вкусы.
Другой подход — корреляция Пирсона, которая учитывает смещения в оценках (например, если один пользователь ставит оценки на балл выше). Для практического применения можно использовать библиотеки вроде scikit-learn, но давайте напишем простую реализацию с нуля.
import numpy as np
def cosine_similarity(user1, user2):
"""Вычисляет косинусную меру между двумя векторами оценок."""
# Пересекающиеся элементы (где обе оценки не None)
mask = ~np.isnan(user1) & ~np.isnan(user2)
if np.sum(mask) == 0:
return 0.0
a = user1[mask]
b = user2[mask]
dot = np.dot(a, b)
norm_a = np.linalg.norm(a)
norm_b = np.linalg.norm(b)
if norm_a == 0 or norm_b == 0:
return 0.0
return dot / (norm_a * norm_b)
# Пример: оценки пяти фильмов (NaN — нет оценки)
alice = np.array([5, 4, 1, 5, np.nan])
bob = np.array([4, 5, 1, 4, np.nan])
carol = np.array([1, 1, 5, 2, 4])
print(cosine_similarity(alice, bob)) # ~0.99 — почти близнецы
print(cosine_similarity(alice, carol)) # ~0.63 — не очень похожиКлассический подход: находим пользователей с похожими оценками и рекомендуем то, что им понравилось, а вы ещё не видели. Недостаток — при большом количестве пользователей вычисления становятся дорогими, и новые пользователи получают пустые рекомендации.
Вместо пользователей сравниваем сами товары. Если тысячи зрителей, посмотревших «Интерстеллар», также смотрели «Прибытие» и «Бегущий по лезвию», система группирует эти фильмы. Когда вы смотрите один из них, алгоритм рекомендует остальные. Такой подход более стабилен и часто используется в интернет-магазинах.
В раннем Netflix можно было ставить звёзды, но современные системы обходятся без них. Они анализируют поведение: досмотрел ли пользователь фильм, пересматривал ли, что добавил в «Избранное», на чём остановился через две минуты. Это называется имплицитной обратной связью. Она часто надёжнее явных оценок, потому что отражает реальные действия, а не намерения.
Новому пользователю нечего рекомендовать, ведь о нём нет данных. Решение: просить оценить несколько фильмов при регистрации или показывать популярный контент, пока не накопится история.
Только вышедший фильм ещё никто не оценил, поэтому алгоритм не может его рекомендовать. Решение: использовать контентную фильтрацию (анализ жанра, актёров) до накопления оценок.
Ваши предпочтения меняются: в 2018 вы смотрели мелодрамы, а в 2026 — аниме. Старые оценки мешают. Решение: взвешивать недавние действия сильнее старых.
Рекомендации работают лучше при большом количестве данных. У популярных фильмов миллионы оценок, у независимых — сотни. Алгоритм продвигает блокбастеры, а скрытые жемчужины остаются незамеченными.
Система может случайно усилить ваши предпочтения: если Netflix рекомендует криминальные драмы, вы их смотрите, и алгоритм становится ещё увереннее, что вам это нравится. Возникает петля обратной связи, снижающая разнообразие рекомендаций.
Теперь, когда вы знаете принцип, попробуйте реализовать простую рекомендательную систему на Python. Возьмите набор данных MovieLens (его легко найти в открытом доступе), постройте матрицу оценок «пользователь-фильм» и вычислите косинусную близость между пользователями. Затем для конкретного пользователя найдите топ-10 похожих и порекомендуйте фильмы, которые они высоко оценили, а ваш пользователь ещё не видел. Это отличное упражнение для портфолио и понимания основ рекомендательных систем.
Коллаборативная фильтрация — мощный инструмент, но не панацея. Современные платформы комбинируют её с контентной фильтрацией, глубоким обучением и гибридными подходами. Начните с простого — и вы поймёте, как строятся настоящие рекомендательные системы.
Хочешь закрепить знания на практике?
Решай задачи на Algolit — интерактивная платформа для обучения
Начать бесплатно →