RecSys · учебник
Виджеты Повторение О проекте Все главы

Тренажёр

Метрики: посчитать руками и покрутить

На собеседовании метрики просят посчитать, а не описать. Здесь можно и потренироваться считать в уме, и увидеть, как метрика реагирует на изменение выдачи.

Тренажёр: посчитай метрику

Шестнадцать типов задач: ранговые метрики, матрица ошибок, AUC двумя способами, сглаженный CTR, IPS, сквозной Recall воронки, фильтр Блума, коллизии хешей. Ответ проверяется с точностью до 0.005; вводить можно дробью (2/5), десятичным числом (0.4) или процентами (40).

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

Все ранговые метрики на одной выдаче

Главный виджет страницы. Клик по строке переключает релевантность, стрелки меняют порядок, ползунок задаёт \(K\).

Что здесь надо увидеть
  1. Возьмите пресет «позитивы снизу» и поднимите оба позитива наверх стрелками. Precision@K и Recall@K не изменятся вовсе — они не видят порядка. А RR, AP и NDCG вырастут.
  2. Уменьшайте \(K\): Recall падает, Precision может расти — классический компромисс.
  3. Пресет «один позитив»: RR становится ровно \(1/\text{позиция}\), а NDCG — тем же числом, только с логарифмическим дисконтом вместо линейного.
  4. Включите градуированную релевантность — теперь клик по строке циклит 0 → 1 → 2. Precision и Recall просто бинаризуют оценки, а NDCG действительно различает «2» и «1».
  5. Следом переключите gain = 2^rel − 1. Числитель в DCG меняется, NDCG вместе с ним — при том же самом ранжировании. Единого «правильного» gain нет, это конвенция, и на собеседовании её проговаривают.
  6. Обратите внимание на названия: здесь один запрос, поэтому честно писать RR и AP. Буква M в MRR и MAP — это mean по запросам, и от того, по чему усреднять, зависит результат: отдельный виджет ниже.

AUC, порог и дисбаланс классов

Второй по частоте вопрос после Precision/Recall. Виджет показывает три вещи сразу: как порог двигает точку по кривым, чем ROC отличается от PR, и почему AUC — это доля правильно упорядоченных пар.

Что здесь надо увидеть
  1. Двигайте порог: precision и recall идут в противоположные стороны, а ROC-AUC не меняется вообще — он не зависит от порога, это свойство ранжирования, а не решающего правила.
  2. Двигайте долю позитивов при фиксированном качестве модели: с 5 % до 60 % ROC-AUC проходит путь 0.868 → 0.852 (шестнадцать тысячных), а AP обваливается с 0.890 до 0.341. Отсюда правило: на сильно несбалансированных задачах смотрят PR, а не ROC.
  3. Вкладка «AUC как доля пар»: посчитайте зелёные клетки и убедитесь, что доля в точности равна ROC-AUC по тем же точкам.
  4. Данные здесь детерминированные: ползунок выбирает точки из одного и того же зафиксированного пула, а не пересэмплирует выборку. Иначе шум оценки (при 5 % позитивов стандартное отклонение самого ROC-AUC доходит до 0.145) полностью съел бы эффект, который надо увидеть.

По чему усреднять: micro против macro

Буква M в MRR и MAP — это mean. Вопрос «а по чему вы усредняете» звучит на собеседовании сразу после «что такое MAP», и правильный ответ — «зависит от того, что мы хотим увидеть».

Что здесь надо увидеть
  1. Новичков по головам половина, а запросов от них — считанные проценты. Поэтому micro почти целиком определяется активными.
  2. Уроните метрику на новичках до нуля. Micro просядет на сотые доли, macro — на десятые. Релиз, который убивает онбординг, по micro выглядит нейтральным.
  3. Обратное тоже верно: macro переоценивает вклад тех, кто сделал один запрос и ушёл. Поэтому смотрят обе — и отдельно режут по когортам.

Что сказать на собесе: «Усреднение по запросам меряет средний запрос, усреднение по пользователям — среднего пользователя. При тяжёлом хвосте активности это разные числа, и деградацию новичков видно только во втором».

Калибровка: почему хорошего AUC мало

Вопрос-ловушка: «у модели AUC 0.85, можно ли её ставить в аукцион?» Ответ — нельзя, пока не проверили калибровку. AUC про порядок, аукцион про значения.

Что здесь надо увидеть
  1. Оба ползунка — монотонные преобразования скора. Порядок объектов не меняется вообще, поэтому ROC-AUC стоит намертво на одном и том же числе.
  2. А ECE, LogLoss и Brier при этом гуляют в разы. Сравните «средний прогноз» и «частоту по факту»: расхождение и есть систематическая ошибка калибровки.
  3. Нажмите Platt scaling. ECE падает примерно с 0.16 до 0.02, LogLoss с 0.65 до 0.48 — а AUC не меняется ни на единицу в четвёртом знаке. Калибровка чинится после обучения и ранжированию не мешает.

Что сказать на собесе: «AUC инвариантен к любому монотонному преобразованию скора, поэтому он ничего не говорит о калибровке. Там, где предсказание умножается на деньги — аукцион, бюджет, ожидаемая выручка — нужны LogLoss, ECE и калибровочная кривая».

Off-policy оценка: IPS, SNIPS и DR

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

Что здесь надо увидеть
  1. Облако точек — 200 независимых прогонов. У IPS среднее лежит ровно на истинном значении (он несмещён), но облако широкое: по одному логу можно ошибиться в разы.
  2. Тяните расхождение политик: ESS падает с 400 до 25 из 500 записей, разброс IPS растёт вчетверо. Вот что значит «оценка разваливается при слабом перекрытии».
  3. Включите клиппинг. При \(w \le 15\) смещение −0.053, но RMSE улучшается; при \(w \le 5\) смещение −0.164 и RMSE уже хуже, чем без клиппинга. У порога есть оптимум.
  4. DM смещён, но устойчив. DR обычно выигрывает по RMSE — он комбинирует модель награды с поправкой через веса.

Что сказать на собесе: «IPS несмещён при условии перекрытия политик и известных propensity. Его беда — дисперсия: вес \(1/p\) взрывается на редких действиях. Лечится самонормировкой, клиппингом или DR, и каждый способ платит смещением».

A/B: размер выборки, MDE и подглядывание

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

Что здесь надо увидеть
  1. Кривая MDE падает как \(1/\sqrt{n}\). Чтобы различить вдвое меньший эффект, нужно вчетверо больше данных — это и есть ответ на «а давайте померим +0.1%».
  2. Уменьшите базовую конверсию при том же относительном приросте: требуемая выборка вырастет, потому что абсолютная разница \(p_0 \cdot \text{lift}\) стала меньше.
  3. Вкладка «подглядывание» — это A/A-тест, настоящего эффекта нет вообще. Проверка один раз в конце даёт честные ≈5%, а ежедневная за две недели — около 22%. Каждый новый взгляд это ещё один шанс случайно пересечь порог.

Что сказать на собесе: «Фиксируем горизонт заранее, считаем MDE до старта. Если надо смотреть по ходу — берём последовательный критерий или alpha spending, иначе номинальные 5% превращаются в 20+%».

Recall@K против latency

Метрика кандидатогенерации никогда не сравнивается при фиксированном \(K\): кандгены стоят по-разному. Двигайте бюджет — победитель меняется.

Температура софтмакса

Численный пример к температуре: с косинусом логиты зажаты в \([-1;1]\), и без температуры софтмакс почти равномерный.

In-batch негативы и LogQ-коррекция

Не иллюстрация, а настоящее обучение — sampled softmax с in-batch негативами. Две модели видят один и тот же поток батчей: одна без коррекции, вторая с вычитанием \(\log Q\) из логита.

Что здесь надо увидеть
  1. Бирюзовые точки (с коррекцией) ложатся на диагональ «выучил = истина». Розовые — нет, и чем крупнее точка, то есть чем популярнее айтем, тем сильнее она уехала вниз.
  2. Сверьте числа: без коррекции корреляция выученного скора с \(\log p - \log Q\) ≈ 0.99. Модель выучила ровно то, что предсказывает теория для sampled softmax без коррекции — просто это не то, что нам нужно.
  3. Ранговая корреляция с истиной: ≈0.57 без коррекции против ≈0.96 с ней. В топ-5 модели без коррекции лезут редкие айтемы.
  4. Поставьте \(\alpha = 0\) — популярность становится равномерной, \(Q\) константа, и коррекция перестаёт что-либо менять. Это проверка на понимание: коррекция лечит именно перекос \(Q\), а не «шум».

Бандиты: ε-greedy, UCB, Thompson

Три алгоритма на одних и тех же ручках. Прогоните 500 шагов и сравните форму кривых regret.

Виджеты по механизмам систем

Здесь собраны метрики и статистика. Интерактив по устройству самих систем — длинный хвост, воронка, эмбеддинги и косинус, ALS, MMR, хеширование, фильтр Блума, PID-блендинг, PLE, attention, semantic IDs, ANN, негативы — врезан в соответствующие недели и собран в каталоге виджетов.

Формулы, которые спрашивают

Precision@K

\(\frac{\#\{\text{рел. в топ-}K\}}{K}\) — доля релевантных среди выданных.

Recall@K

\(\frac{\#\{\text{рел. в топ-}K\}}{\#\{\text{всех рел.}\}}\) — какую часть достали.

HitRate@K

1, если в топ-\(K\) есть хотя бы один релевантный.

MRR

\(\frac{1}{\text{позиция первого релевантного}}\), усреднённое по запросам.

AP@K

\(\frac{1}{|R|}\sum_{k} \mathrm{P@}k \cdot rel_k\) — точность на каждой «удачной» позиции.

NDCG@K

\(\frac{\sum_k g(rel_k)/\log_2(k+1)}{\mathrm{IDCG@}K}\); gain можно задать своим — вплоть до цены.

ROC-AUC

\(P\bigl(s(\text{поз}) > s(\text{нег})\bigr)\) — доля правильно упорядоченных пар; связка = 0.5.

Precision / Recall

\(\frac{TP}{TP+FP}\) и \(\frac{TP}{TP+FN}\). F1 — их гармоническое среднее.

FPR

\(\frac{FP}{FP+TN}\) — ось X у ROC. Recall (TPR) — ось Y.

Сглаженный CTR

\(\frac{c+\alpha}{n+\alpha+\beta}\) — иначе один показ с одним кликом даёт CTR = 1.

LogLoss

\(-\frac{1}{N}\sum y\log p + (1-y)\log(1-p)\) — в отличие от AUC, чувствителен к значениям, а не только к порядку.

ECE

\(\sum_b \frac{n_b}{N}\bigl|\overline{p}_b - \overline{y}_b\bigr|\) — средний разрыв между уверенностью и фактом по корзинам.

IPS

\(\frac{1}{N}\sum_i \frac{r_i \mathbb{1}[a_i = \pi(x_i)]}{p_i}\) — несмещён, но дисперсия растёт как \(1/p\).

ESS

\(\frac{(\sum w)^2}{\sum w^2}\) — сколько «эффективных» наблюдений осталось после перевзвешивания.

Размер выборки

\(n = \frac{2(z_{1-\alpha/2}+z_{\beta})^2 \bar p(1-\bar p)}{\Delta^2}\) на группу; MDE — то же, решённое относительно \(\Delta\).

Ловушки, на которых валят
  • Recall при нулевом числе релевантных не определён — договоритесь, что это 0, и скажите об этом вслух.
  • AP нормируется на \(|R|\) (как в большинстве учебников) или на \(\min(|R|, K)\) — уточните конвенцию, иначе числа не сойдутся.
  • NDCG зависит от определения gain: \(rel\) против \(2^{rel}-1\) дают разные числа.
  • ROC-AUC нечувствителен к дисбалансу, PR — чувствителен. Это буквально следующий вопрос после «что такое AUC».
  • Связки в скорах дают 0.5 к паре — иначе AUC получится завышенным.
  • Метрику усредняют по запросам, а полезно ещё и по пользователям: иначе активные когорты перетянут среднее.
  • AUC ничего не говорит о калибровке. Любое монотонное преобразование скора оставляет AUC ровно тем же и при этом может полностью сломать значения.
  • IPS без перекрытия политик бессмысленен. Если целевая политика выбирает то, чего логирующая почти не показывала, оценка формально несмещена, но её разброс делает её бесполезной — смотрите на ESS.
  • Подглядывание в A/B ломает уровень значимости. Пять процентов превращаются в двадцать, если смотреть каждый день без поправки.