Данные и логирование
Откуда вообще берутся обучающие данные в RecSys: event log → лейблы, позиционное смещение и петля обратной связи. Самое важное в этом модуле — не модель, а понимание, как устроены данные, на которых всё держится.
⚠ Лог здесь синтетический (реальны только названия фильмов): у MovieLens нет impression/click-логов. Настоящие behavior-логи — на следующем implicit-feedback датасет-треке.
1 · Лог событий и позиционное смещение
Синтетический лог показа: каждая сессия показывает топ-выдачу, клики возникают по position-based модели (увидел × привлекательность). Видно, как CTR падает с позицией — это и есть позиционное смещение.
2 · Конструктор лейблов
Лейбл — это продуктовое решение, а не данность. Один и тот же лог под разным определением цели даёт разный размер выборки и долю позитивов.
3 · Петля обратной связи (rich-get-richer)
Обучаем тривиальную модель на наивных кликах и переранжируем — раунд за раундом. Без exploration экспозиция схлопывается на том, что случайно всплыло наверх, и хорошие айтемы так и не получают показов. ε (exploration) — противоядие.
Теория простым языком
Самый недооценённый вопрос в RecSys: откуда берутся обучающие данные? Модель учат не на «рейтингах из датасета», а на логах поведения — что показали, что кликнули, что досмотрели, что купили. Как превратить поток событий в обучающую выборку — и какие ловушки тут спрятаны — и есть тема этого модуля.
Событие, импрешн, лог
в ответе сервера → во viewport → рассмотрен → взаимодействие. Иначе можно записать «показ», которого человек физически не видел — и тогда no-click ≠ dislike вдвойне. В симуляторе выше вероятность examination(падающая с позицией) — это и есть модель того, был ли импрешн рассмотрен.Минимальная схема таблицы events: request_id, session_id, user_id, item_id, event_type (impression/click/watch/purchase), position, surface, model_version, experiment_id, timestamp. Выше на странице — живой синтетический лог по этой схеме.
▸Почему RecSys начинается не с модели, а с логов
Из событий — обучающая выборка
Лейбл (целевая переменная) — это продуктовое решение, а не данность. Из одного и того же лога можно собрать разные задачи:
CTR-лейбл: строки = импрешны; label = был ли клик CVR-лейбл: строки = клики; label = была ли покупка watch-лейбл: строки = клики; label = досмотр ≥ T секунд rating≥4: строки = оценки; label = оценка ≥ 4 (это MovieLens) next-item: строки = сессии; label = следующий кликнутый айтем
Покрути «конструктор лейблов» выше: одни и те же события под разным определением дают разный размер выборки и долю позитивов.
purchase в течение 1 дня / 7 дней / той же сессии, watch ≥ T в той же сессии. Без окна легко получить leakage (привязали покупку, случившуюся сильно позже и по другой причине) или потерять настоящий конверт. В нашем симуляторе purchase/watch происходят сразу в той же сессии (attribution = same-session) — в реальном проде окно надо задавать явно.Главные «≠» (ради них всё затевалось)
Почему нельзя наивно учиться только на кликах
Клики — полезный, но смещённый прокси (не «клики плохие»). Они смещены экспозицией и позицией: верхние позиции собирают клики просто потому, что их видят чаще. Если наивно взять «кликнутое = позитив, всё остальное = негатив», модель выучит позицию и популярность, а не вкус — и в петле обратной связи начнёт сама себя усиливать.
▸Почему impression-aware негативы честнее наивных
Наивный негатив «весь каталог минус клик» раздувает выборку мусором: туда попадают айтемы, которые пользователь не видел. Честнее брать негативы из показанного-но-не-кликнутого (impression-aware) — это то, что человек реально видел и не выбрал. Полная коррекция экспозиции (IPS / counterfactual) — отдельная тема (Фаза 14), здесь важно само различие.
Сильные стороны
- Логи событий — единственный источник правды о реальном поведении (не лабораторные оценки).
- Из одного лога — много задач (CTR/CVR/watch/next-item) под разные продуктовые цели.
- Impression-логи позволяют строить честные негативы и корректировать смещения.
Слабые стороны
- Клики смещены позицией/экспозицией — наивные лейблы учат артефактам показа.
- Прокси-метрики врут: click/watch/purchase ≠ удовлетворённость/ценность.
- Петля обратной связи: модель видит только то, что сама показала (selection bias).
⚠️ Что может пойти не так
- Нет impression-логов → нельзя отличить «не понравилось» от «не показали»; негативы становятся мусором.
- Лейбл = прокси: оптимизируя CTR, легко выучить кликбейт; нужны guardrail-метрики и долгосрочные сигналы.
- Позиционное смещение: верхние слоты собирают клики за счёт видимости, а не релевантности.
- Feedback loop без exploration: rich-get-richer, long-tail и новинки голодают.
- Утечка времени: лейбл нельзя строить из будущего относительно фич (см. модуль про валидацию).
🧠 Проверь себя: Почему «не показанный айтем» нельзя считать отрицательным примером?
Где это в жизни
В любой продакшен-системе (YouTube, маркетплейсы, ленты) обучение крутится вокруг логов показов и взаимодействий, а не «оценок». Качество данных и лейблов решает больше, чем выбор модели — поэтому это первый модуль инженерного трека. Дальше: корректная валидация (никакой утечки времени), feature store (те же фичи на обучении и в проде) и мониторинг.