Как использовать поисковый запрос и историю пользователя для формирования выдачи в холодном старте
Что проверяют
Понимаете ли вы, что в поиске холодный старт мягче, чем в ленте рекомендаций: запрос уже сообщает намерение, и опираться нужно на него, а не строить персонализацию из пустоты. Следом обычно спрашивают, в какой момент и с каким весом подключать историю.
Как отвечать
Разложите выдачу на отбор кандидатов и ранжирование и покажите, откуда берутся сигналы, пока истории нет:
- запрос: лексический поиск BM25 плюс семантический по эмбеддингам, двухбашенная модель запрос-документ. На кандидатах работает ранжер с признаками релевантности, популярности, CTR и конверсии в разрезе запроса;
- сессия: клики и просмотры за последние минуты это уже история. Их подают ранжеру как контекст, используют сессионные модели вроде GRU4Rec и SASRec или item-to-item похожесть на то, что человек открыл;
- контекст без логина: регион, устройство, источник перехода, время суток дают групповые предпочтения;
- смешивание: вес персональных признаков растёт с числом взаимодействий, например через байесовское сглаживание к среднему по сегменту, так что два клика не переворачивают всю выдачу;
- исследование: немного трафика отдают бандитам (Thompson sampling), чтобы новые товары и новые пользователи вообще получали сигнал.
Холодные объекты закрывают контентными признаками: текст, категория, цена, эмбеддинг описания, небольшой буст свежести.
Проверять стоит отдельно на сегменте новых пользователей: офлайн NDCG и recall@k на их сессиях, затем A/B с метрикой по этому сегменту, потому что общий прирост легко спрячет провал на новичках.
Где спотыкаются
Предлагают коллаборативную фильтрацию. Без взаимодействий матричному разложению не на чем учиться, это как раз то, что ломается на холодном старте.
Показывают топ популярного и игнорируют запрос. Популярность годится как признак, но не как замена релевантности.
Учат ранжер на логах, не поправив позиционный сдвиг. Модель выучит, что кликают по первым строкам, и закрепит старую выдачу.