RRF на Python: объединить BM25 и векторное ранжирование

Реализуйте слияние двух ранжирований для гибридного поиска. Все данные передаются через стандартный ввод, внешняя модель и векторная база не нужны. В условии заданы формула RRF, правила равенства оценок и формат JSON-ответа — они важны для автоматической проверки.

Напишите решение и проверьте его на странице.

Продолжить практику: программа курса «LLMOps & Evaluation: из песочницы в продакшн».

Задача: Гибридный ретривер — RRF (Reciprocal Rank Fusion)

Цель. Объединить два независимых ранжирования документов (BM25 и векторная близость) методом RRF и выдать top-k.

Вход

Первая строка: три целых через пробел — N k K.

  • N — число документов (1..10^4)
  • k — сколько документов вернуть
  • K — константа RRF (> 0), по умолчанию в работах берут ~60

Далее N строк, каждая: doc_id bm25 vec

  • doc_id — строка без пробелов
  • bm25 — вещественный скор BM25 (чем больше — тем лучше)
  • vec — вещественный скор векторного ранжирования (cosine и т.п., чем больше — тем лучше)

Как считать

  1. Постройте два ранжирования (по убыванию score): rank_bm25 и rank_vec. При равных score используйте стабильную сортировку — более ранняя входная строка выигрывает.
  2. Для документа с позициями r_bm и r_vec (позиции начинаются с 1) вычислите
    RRF = 1/(K + r_bm) + 1/(K + r_vec)
  3. Отсортируйте документы по RRF по убыванию. При полном равенстве RRF — выше тот, у кого больше vec, затем больше bm25, затем более ранняя входная строка.
  4. Верните верхние min(k, N) документов.

Выход

Ровно одна минифицированная JSON-строка (без пробелов):

{"top":[{"id":"<doc_id>","score":<rrf>}, ...]}

Числа score округляйте до 6 знаков (математически) и печатайте без лишних нулей (напр., 0.166667, 0.5, 5, 0).

 

РешениеPython

Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.

Отправьте решение, чтобы увидеть результаты тестов.

Связанные задачи