Thomas Piacentini
← Atelier

Exercice Python

Reciprocal rank fusion

Texte original · anglais12 min

Reciprocal rank fusion (RRF) merges ranked lists from different retrievers into one list. It uses only the rank of each document, not the raw score. A BM25 score and a cosine similarity have different scales, but their ranks are comparable. Hybrid search uses RRF to merge keyword and vector results.

Task

Write two functions.

  1. rrf_scores(rankings, k=60, weights=None) returns the fused score of each document.
  2. fuse(rankings, k=60, weights=None) returns the documents sorted by fused score.

Each ranking is a list of document ids, best first. The first document of a list has rank 1. The fused score of document d is

\mathrm{RRF}(d) = \sum_{i} \frac{w_i}{k + \mathrm{rank}_i(d)}

The sum runs over the lists that contain d. A list that does not contain d adds nothing. When weights is None, every w_i is 1.

If weights is not None and its length is not the number of lists, raise ValueError.

Tie rule: fuse sorts from the highest score to the lowest. When two documents have the same score, the lower doc id comes first.

Input and output

Name Type Shape Meaning
rankings list of lists of int L lists each list holds distinct doc ids, best first
k int scalar the RRF constant, default 60
weights list of float or None L values the weight of each list
  • rrf_scores returns a dict that maps each doc id in any list to its fused score as a float.
  • fuse returns a list of (doc_id, score) tuples, best first. It holds every document of rrf_scores.

Constraints

  • 0 <= L <= 10 and each list has at most 1000 ids. A list can be empty.
  • Doc ids are non negative ints. An id occurs at most once in one list.
  • k >= 1 and each weight is positive.
  • Do not change the input lists.
  • Use Python and numpy only.

Examples

python
bm25 = [3, 1, 4]
dense = [1, 5, 3]
fuse([bm25, dense])
text
[(1, 0.03252247488101534), (3, 0.032266458495966696), (5, 0.016129032258064516), (4, 0.015873015873015872)]

Document 1 has ranks 2 and 1, so its score is 1/62 + 1/61. Document 3 has ranks 1 and 3, so its score is 1/61 + 1/63. Document 1 comes first.

python
fuse([bm25, dense], weights=[2.0, 1.0])
text
[(3, 0.04865990111891751), (1, 0.048651507139079855), (4, 0.031746031746031744), (5, 0.016129032258064516)]
Code et livrables 12
Ce que vous en retenez

Enregistré dans votre carnet sur cet appareil.

Sources et limites

Les repères de lecture sont déclaratifs. Les résultats de tests sont enregistrés séparément ; ils valent pour les cas exécutés.

AI Engineering from Scratch · 3f9715c · MIT

Télécharger ce fichier ↓