Ранжирование: learning-to-rank
Как обучить модель упорядочивать документы под запрос: pointwise, pairwise и listwise подходы, метрики MRR и NDCG, фичи «запрос-документ» и коварное смещение позиции в кликовых логах.
Интуиция
Поиск и рекомендации редко сводятся к «да/нет» или к предсказанию одного числа. На запрос находятся десятки кандидатов, и пользователю важно, в каком порядке они лежат: нужный документ на первой позиции — успех, тот же документ на десятой — почти провал. Задача обучения ранжированию (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, потому что напрямую целятся в него.
Переключи режимы. Pointwise честно предсказывает каждый документ по отдельности — но его цель это клики, раздутые «кликбейт»-признаком (кричащий заголовок ловит клики без реальной пользы). Модель тянется за этим сигналом, роняет по-настоящему лучший документ и NDCG проседает. Pairwise и listwise учатся на честных попарных сравнениях по истинной релевантности и восстанавливают идеальный порядок. Нажми «Истинная релевантность» — и сразу видно, кто где промахнулся.
Метрики ранжирования
Раз важен порядок, метрики тоже позиционные — считаются на топ-k выдачи.
- Precision@k — доля релевантных среди первых k. Простая, но не различает порядок внутри топа и не учитывает степень релевантности.
- MRR (mean reciprocal rank) — обратный ранг первого релевантного документа, усреднённый по запросам: MRR = (1/Q) · Σ 1/ranki. Нашли нужное на 1-й позиции → 1.0, на 2-й → 0.5, на 5-й → 0.2. Идеальна там, где ответ по сути один (навигационный поиск, QA).
- NDCG (normalized discounted cumulative gain) — золотой стандарт для градуированной релевантности. Собирается в три шага. Сначала DCG складывает выигрыш каждого документа с дисконтом по позиции: DCG@k = Σi=1..k (2reli − 1) / log2(i+1) Чем ниже позиция, тем больше делитель, поэтому релевантное внизу почти не приносит пользы. Затем считают IDCG — DCG идеального порядка (сортировка по убыванию релевантности). И нормируют: NDCG@k = DCG@k / IDCG@k
Нормировка нужна, чтобы метрика лежала в [0, 1] и была сравнима между запросами: у одного запроса пять отличных документов, у другого — один, и без деления на идеал их DCG несопоставимы. NDCG = 1 означает идеальный порядок, деградация внизу списка почти не штрафуется — ровно как в реальном поиске, где до десятой позиции никто не доходит.
Фичи, двухэтапность и коварство кликов
Модель ранжирования работает не с сырым текстом, а с признаками «запрос-документ»: лексические совпадения (BM25, TF-IDF), семантическая близость эмбеддингов, свежесть, авторитетность источника, длина, историческая кликабельность. Именно поэтому LTR обычно стоит вторым этапом: сначала дешёвый retrieval (BM25 или векторный поиск) отбирает сотни кандидатов из миллионов, затем тяжёлая LTR-модель точно упорядочивает эту сотню. Та же двухэтапка retrieval → ranking лежит в основе рекомендательных систем и гибридного поиска с реранкингом — там роль точной модели играет cross-encoder, и его мы разбираем отдельно, здесь не дублируем.
Где брать обучающие метки? Асессорские оценки дороги, поэтому чаще учатся на кликах — и тут прячется главная ловушка. Клики несут смещение позиции (position bias): верхние документы кликают чаще просто потому, что они сверху, а не потому что релевантнее. Наивно приняв «клик = релевантность», модель выучит «показывай наверху то, что уже наверху» — самоподтверждающаяся петля. Лечат это моделями клика (examination model), inverse propensity weighting (взвешивание кликов на вероятность быть замеченным) и разведочными перестановками выдачи.
- «Чем LTR отличается от регрессии?» — регрессия минимизирует ошибку абсолютного значения по каждому объекту; LTR оптимизирует относительный порядок внутри запроса, и абсолютные скоры сами по себе не важны.
- «Что такое NDCG и зачем нормировка?» — DCG суммирует релевантность с дисконтом по позиции; нормировка на IDCG (идеальный порядок) загоняет метрику в [0,1] и делает её сравнимой между запросами с разным числом релевантных документов.
- «Pointwise vs pairwise vs listwise?» — pointwise предсказывает релевантность по одному документу и сортирует; pairwise учит порядок в паре (RankNet); listwise оптимизирует метрику всего списка (LambdaMART) и обычно даёт лучший NDCG.
- «Почему нельзя учить LTR на сырых кликах?» — position bias: верхнее кликают за позицию, модель закрепляет старый порядок; нужны IPW или модели клика.