# Ранжирование: learning-to-rank

> Как обучить модель упорядочивать документы под запрос: pointwise, pairwise и listwise подходы, метрики MRR и NDCG, фичи «запрос-документ» и коварное смещение позиции в кликовых логах.

Раздел: [Продакшн и качество](https://ml-book.com/s/production/) · Страница темы: https://ml-book.com/t/learning-to-rank/ · Обновлено: 2026-07-09 · Источник: ml-book.com, учебник делается сообществом

## Интуиция

Поиск и рекомендации редко сводятся к «да/нет» или к предсказанию одного числа. На запрос находятся десятки кандидатов, и пользователю важно, *в каком порядке* они лежат: нужный документ на первой позиции — успех, тот же документ на десятой — почти провал. Задача обучения ранжированию (learning-to-rank, LTR) — научить модель раскладывать список так, чтобы релевантное всплывало наверх.

Ключевое отличие от классификации и регрессии: нам не важна абсолютная величина скора, важен только **относительный порядок**. Если модель одному документу дала 0.9, другому 0.4, а третьему 0.1 — метрика не изменится, пока сохраняется тот же порядок 1>2>3. Оценка всегда относительная и всегда *внутри одного запроса*: скоры документов из разных запросов сравнивать бессмысленно.

## Три семейства подходов

Все методы LTR учат функцию скора s = f(запрос, документ), а отличаются тем, на что смотрит функция потерь.

- **Pointwise.** Предсказываем релевантность каждого документа *по отдельности* — обычной регрессией или классификацией — и сортируем по предсказанию. Просто, переиспользует любой ML-инструмент. Но лосс не знает про порядок: он одинаково штрафует ошибку на первой и на сотой позиции и страдает от дисбаланса (нерелевантных документов на порядок больше, модель учится всем ставить «низко»).
- **Pairwise.** Учим, *какой из пары* документов релевантнее. Модель смотрит на пары (A, B) и минимизирует число инверсий — случаев, когда менее релевантный оказался выше. Классика — RankNet (логистический лосс на разнице скоров) и его наследник LambdaRank. Порядок уже в центре внимания.
- **Listwise.** Оптимизируем метрику *всего списка* целиком. LambdaMART — рабочая лошадка индустрии (градиентный бустинг + «лямбды», взвешивающие пары по вкладу в NDCG); ListNet сравнивает распределения перестановок. Именно listwise-методы обычно дают лучший NDCG, потому что напрямую целятся в него.

> **💡 Ключевая мысль**
>
> LTR оптимизирует порядок, а не абсолютные значения. Поэтому pointwise-регрессия, честно минимизируя ошибку по каждому документу, может проиграть в NDCG модели, которая хуже угадывает сами релевантности, зато точнее ставит нужное наверх.

> 🎛 Интерактивная визуализация — на странице темы: https://ml-book.com/t/learning-to-rank/

Переключи режимы. Pointwise честно предсказывает каждый документ по отдельности — но его цель это клики, раздутые «кликбейт»-признаком (кричащий заголовок ловит клики без реальной пользы). Модель тянется за этим сигналом, роняет по-настоящему лучший документ и NDCG проседает. Pairwise и listwise учатся на честных попарных сравнениях по истинной релевантности и восстанавливают идеальный порядок. Нажми «Истинная релевантность» — и сразу видно, кто где промахнулся.

## Метрики ранжирования

Раз важен порядок, метрики тоже позиционные — считаются на топ-k выдачи.

- **Precision@k** — доля релевантных среди первых k. Простая, но не различает порядок *внутри* топа и не учитывает степень релевантности.
- **MRR** (mean reciprocal rank) — обратный ранг первого релевантного документа, усреднённый по запросам: MRR = (1/Q) · Σ 1/rank_i. Нашли нужное на 1-й позиции → 1.0, на 2-й → 0.5, на 5-й → 0.2. Идеальна там, где ответ по сути один (навигационный поиск, QA).
- **NDCG** (normalized discounted cumulative gain) — золотой стандарт для *градуированной* релевантности. Собирается в три шага. Сначала DCG складывает выигрыш каждого документа с дисконтом по позиции: DCG@k = Σ_{i=1..k} (2^{reli} − 1) / log_2(i+1) Чем ниже позиция, тем больше делитель, поэтому релевантное внизу почти не приносит пользы. Затем считают IDCG — DCG идеального порядка (сортировка по убыванию релевантности). И нормируют: NDCG@k = DCG@k / IDCG@k

Нормировка нужна, чтобы метрика лежала в [0, 1] и была сравнима между запросами: у одного запроса пять отличных документов, у другого — один, и без деления на идеал их DCG несопоставимы. NDCG = 1 означает идеальный порядок, деградация внизу списка почти не штрафуется — ровно как в реальном поиске, где до десятой позиции никто не доходит.

## Фичи, двухэтапность и коварство кликов

Модель ранжирования работает не с сырым текстом, а с **признаками «запрос-документ»**: лексические совпадения (BM25, TF-IDF), семантическая близость эмбеддингов, свежесть, авторитетность источника, длина, историческая кликабельность. Именно поэтому LTR обычно стоит *вторым* этапом: сначала дешёвый retrieval (BM25 или [векторный поиск](https://ml-book.com/t/vector-search/)) отбирает сотни кандидатов из миллионов, затем тяжёлая LTR-модель точно упорядочивает эту сотню. Та же двухэтапка retrieval → ranking лежит в основе [рекомендательных систем](https://ml-book.com/t/recsys/) и [гибридного поиска с реранкингом](https://ml-book.com/t/hybrid-rerank/) — там роль точной модели играет cross-encoder, и его мы разбираем отдельно, здесь не дублируем.

Где брать обучающие метки? Асессорские оценки дороги, поэтому чаще учатся на **кликах** — и тут прячется главная ловушка. Клики несут **смещение позиции (position bias)**: верхние документы кликают чаще просто потому, что они *сверху*, а не потому что релевантнее. Наивно приняв «клик = релевантность», модель выучит «показывай наверху то, что уже наверху» — самоподтверждающаяся петля. Лечат это моделями клика (examination model), inverse propensity weighting (взвешивание кликов на вероятность быть замеченным) и разведочными перестановками выдачи.

> **⚠️ Подводный камень**
>
> Смещение позиции превращает клики в предвзятый сигнал: документ на первой строке собирает клики за саму позицию, а не за качество. Обучаясь на сырых кликах без поправки на позицию, LTR-модель консервирует старый порядок и не находит хорошие документы, которых раньше не показывала.

> **🎤 На собеседовании**
>
> - «Чем LTR отличается от регрессии?» — регрессия минимизирует ошибку абсолютного значения по каждому объекту; LTR оптимизирует относительный порядок внутри запроса, и абсолютные скоры сами по себе не важны.
> - «Что такое NDCG и зачем нормировка?» — DCG суммирует релевантность с дисконтом по позиции; нормировка на IDCG (идеальный порядок) загоняет метрику в [0,1] и делает её сравнимой между запросами с разным числом релевантных документов.
> - «Pointwise vs pairwise vs listwise?» — pointwise предсказывает релевантность по одному документу и сортирует; pairwise учит порядок в паре (RankNet); listwise оптимизирует метрику всего списка (LambdaMART) и обычно даёт лучший NDCG.
> - «Почему нельзя учить LTR на сырых кликах?» — position bias: верхнее кликают за позицию, модель закрепляет старый порядок; нужны IPW или модели клика.

## Связанные темы

- [Рекомендательные системы](https://ml-book.com/t/recsys/)
- [Гибридный поиск и реранкинг](https://ml-book.com/t/hybrid-rerank/)
- [Метрики качества](https://ml-book.com/t/metrics/)
- [Эмбеддинг-модели: как их обучают](https://ml-book.com/t/embedding-models/)

---

Интерактив, тест из 12 вопросов и карточки терминов — на странице темы: https://ml-book.com/t/learning-to-rank/
Весь учебник в markdown: https://ml-book.com/llms-full.txt · Оглавление для агентов: https://ml-book.com/llms.txt
