Как я строю рекомендательную модель фильмов: cold start, вектор вкуса и GPT

Как я строю рекомендательную модель фильмов: cold start, вектор вкуса и GPT

Выбрать фильм на вечер сложно даже одному человеку. А если нужно подобрать кинокартину для пары с разными вкусами, задача становится ещё сложнее.

Обычные подборки, жанровые фильтры и списки «что посмотреть» помогают лишь отчасти. Они работают как витрина, но не как персональная рекомендация — почти не учитывают зрительский опыт, индивидуальные предпочтения и то, какие фильмы человек уже смотрел.

Именно с этой проблемой я столкнулся при создании проекта NextFilm: не как каталог фильмов, а как рекомендательная система. Главный вопрос: как дать полезную рекомендацию новому пользователю, если о нём почти ничего не известно.

В моём понимании это и есть cold start — не абстрактная нехватка данных, а реальная ситуация: пользователь ждёт рекомендацию, а система не знает, что он смотрел, насколько широка его зрительская база и какие у него паттерны вкуса.

Почему жанров недостаточно

Наивный способ — рекомендовать по жанрам, популярности и общим рейтингам. Но жанр — слишком грубый признак.

Два человека могут любить фантастику, но один предпочитает медленные, атмосферные и философские фильмы, а другой — динамичные, зрелищные и сюжетно насыщённые. Формально жанр один, а ожидания — разные.

То же самое с универсальными подборками: они дают средний результат, но не решают задачу персонализации, особенно для зрителей с большим опытом, которые плохо реагируют на очевидные варианты.

Для меня это означало одно: чтобы быть полезной, система должна понимать не только «что нравится», но и какой у пользователя зрительский опыт.

Этап 1. Сбор стартовых сигналов

Первый шаг — не рекомендация, а сбор начального профиля. Важно понять, какие фильмы пользователь уже видел и как он к ним относится.

Это критично по двум причинам.

Во-первых, нужно отличать «фильм не нравится» от «не смотрел». Иначе модель делает ложные выводы.

Во-вторых, у пользователей разная зрительская база: один знает только хиты последних лет, другой — классику и авторское кино, третий — редкий зритель, знакомый лишь с громкими названиями.

Если обрабатывать все случаи одинаково, модель начинает «шуметь». Поэтому первый полезный шаг — собрать список просмотренных фильмов и получить по ним оценки.

С технической точки зрения эти оценки — первый надёжный сигнал. Они ещё не дают полного профиля, но показывают, где у пользователя сильные предпочтения, а где данных недостаточно.

Этап 2. Построение вектора вкуса

Когда оценок становится достаточно, можно переходить от «карты просмотренного» к модели предпочтений.

Для меня вкус — это не просто любимые жанры. Я разбиваю его на тонкие параметры: темп, эмоциональный тон, глубина, зрелищность, привычность формы, сюжетная плотность и другие.

Именно здесь оценки превращаются во внутренний вектор вкуса. Цель — не сказать «пользователь любит драму», а описать, какой тип фильма для него релевантен.

Такой подход лучше, чем жанровая сегментация. Он объясняет, почему два фильма из одного жанра могут быть очень разными для одного зрителя.

На этом этапе модель уже может делать осмысленные выводы. Но полагаться только на локальные данные рискованно: данных мало, а случайные совпадения могут сильно исказить результат.

Этап 3. Коллективный сигнал

Чтобы не замыкаться на локальном профиле, я добавляю внешний слой — коллективные оценки. Использую датасет MovieLens 25M от GroupLens: 25 млн оценок по более чем 62 тысячам фильмов.

Здесь важна не абстрактная математика, а прикладная логика: если пользователю понравился определённый набор фильмов, можно посмотреть, что ещё нравится людям с похожими паттернами.

Внешний датасет — не замена профилю, а дополнительный слой сигнала. С одной стороны, есть локальные предпочтения; с другой — коллективные зависимости, подтверждённые массовыми оценками.

На практике это гибридная схема: часть сигнала — от профиля пользователя, часть — от collaborative filtering по похожим оценкам.

Этап 4. Дообучение на новых сигналах

Модель не должна быть статичной. Если зафиксировать профиль после онбординга, качество быстро достигнет потолка.

По мере накопления новых оценок система пересматривает значимость признаков, обновляет веса и уточняет, какие факторы влияют на релевантность. Это дообучение на новых сигналах, или online updates.

Это особенно важно в кино: вкусы не только различаются, но и меняются. Пользователь может уставать от одних жанров и тянуться к другим.

Поэтому для меня рекомендательная система — не «один раз посчитанная формула», а постоянно уточняемая модель. Каждая новая оценка должна менять траекторию выдачи.

Этап 5. Зачем здесь GPT

Даже хорошие кандидаты могут быть плохо поданы. Базовая модель может выбрать релевантные фильмы, но выдача будет выглядеть странно: неупорядоченной, непонятной или «машинной».

Поэтому GPT в моём пайплайне не заменяет рекомендательную модель. Он стоит поверх неё — как финальный слой интерпретации и re-ranking.

Сначала система собирает кандидатов на основе оценок, вектора вкуса и коллективных сигналов. Затем LLM помогает осмысленно отсортировать, сгруппировать и подать результат.

Ключевое — не подменять модель «LLM-магией». GPT хорош в интерпретации и подаче, но базовая релевантность должна формироваться раньше — на уровне данных и ранжирования.

Что получается в итоге

Упрощённый пайплайн выглядит так:

  1. Собрать стартовые оценки и понять, что пользователь уже видел.
  2. Построить начальный профиль предпочтений.
  3. Превратить оценки в устойчивый вектор вкуса.
  4. Сопоставить сильные сигналы с коллективными паттернами из MovieLens 25M.
  5. Отранжировать кандидатов.
  6. Применить GPT как слой интерпретации и финальной сборки выдачи.

С инженерной точки зрения это попытка снизить долю случайных рекомендаций. Не предлагать «что-то популярное», а пройти от слабых сигналов к устойчивой модели пользователя.

Где у подхода ограничения

Схема не решает всё автоматически.

Во-первых, cold start остаётся самым уязвимым этапом. Чтобы дать качественные рекомендации, система требует от пользователя значимого старта — оценок нескольких фильмов. Если он не готов это сделать, сигналов слишком мало, и качество падает.

Во-вторых, есть риск переобучения на популярных фильмах. Чем сильнее массовые паттерны, тем чаще модель будет предлагать очевидные варианты.

В-третьих, LLM-слой нельзя переоценивать. Он улучшает подачу, но не исправляет фундаментальные ошибки базового ранжирования.

Поэтому главный интерес — в качестве всего пайплайна: какие сигналы собирать, как уменьшать шум, как дообучать и где ставить границу между классическим рекомендателем и LLM.

Почему мне это интересно

На первый взгляд, выбор фильма — простая задача. Но при реальном решении для одного человека или пары становится ясно: жанров, списков и красивой витрины недостаточно.

Интересно строить систему как рекомендательный пайплайн: с cold start, профилем, коллективным сигналом, дообучением и слоем интерпретации.

Самое важное — не просто подобрать фильм, а сделать рекомендацию релевантной при старте с малыми данными и постепенно повышать качество по мере накопления сигналов.

Читать оригинал