Как формировать кандидатов для ранжирования
Что проверяют
Знаете ли вы, как устроено многоступенчатое ранжирование в рекомендациях и поиске, и понимаете ли разницу целей этапов: генерация кандидатов отвечает за полноту, ранжирование за точность. Следом спрашивают, как оценить именно этап отбора и сколько кандидатов отдавать ранжировщику.
Как отвечать
Из миллионов объектов за десятки миллисекунд нужно выбрать сотни или тысячи, которые потом отсортирует тяжёлая модель. Кандидатов берут из нескольких источников сразу:
- векторный поиск: двухбашенная модель или item2item-эмбеддинги, приближённый поиск ближайших соседей через HNSW или FAISS;
- коллаборативная фильтрация: ALS, совместные просмотры и покупки, «с этим товаром берут»;
- история пользователя: недавно просмотренное, повторные покупки расходников, брошенная корзина;
- популярное: тренды по сегменту, региону и категории, это же спасает при холодном старте;
- контентные и бизнес-источники: похожие по атрибутам, новинки, товары под акцию. В поиске сюда добавляется текстовый отбор по BM25.
Затем объединение с квотами на источник, дедупликация и жёсткие фильтры: нет в наличии, уже куплено, запрещено к показу. Источник кандидата и его скор полезно передавать ранжировщику как признаки.
Отбор оценивают отдельно: recall@K, то есть доля объектов, с которыми пользователь потом реально провзаимодействовал, попавших в множество кандидатов, плюс покрытие каталога и задержка. Если нужного объекта нет среди кандидатов, никакой ранжировщик его не поднимет.
Где спотыкаются
Смотрят только на итоговый NDCG. Когда он падает, непонятно, виноват отбор или ранжирование, а потолок качества задаёт именно recall кандидатов.
Обучают ранжировщик на случайных негативах, а на проде подают ему трудных кандидатов из генератора. Распределения не совпадают, и офлайн-метрики не переносятся; негативы надо брать из тех же источников, что работают в проде.
Строят всё на популярности и получают петлю: показываем популярное, оно набирает клики и становится ещё популярнее, а длинный хвост каталога не попадает в выдачу никогда.