Information Retrieval · Ranking

Score Normalization and Rank Fusion Across Retrievers

Why scores from different retrievers cannot be compared, how score distributions are normalized, and what reciprocal rank fusion gives up to avoid the problem.

Two retrievers return lists for the same query. One produces BM25 scores in a range around 4 to 30, the other produces cosine similarities in 0.6 to 0.95. Concatenating the lists to a fixed depth and taking the top results by raw score means the BM25 list wins whenever its top score happens to exceed 0.95, which is usually. The vector list is not wrong; it is measured in different units, and mixing units is the problem this cluster’s fusion methods exist to solve.

Scores are ordinal, not cardinal

The first thing to establish is that a retrieval score is not a measurement of relevance on any absolute scale. BM25 above is a sum of per-term weights with an unbounded ceiling and a magnitude that depends on query length, collection statistics, and the specific $k_1$ and $b$ in use. A cosine distance is bounded in $[-1,1]$ and, for normalized embeddings, has no particular meaning at the value 0.8 beyond “closer than 0.7”.

Within one retriever, comparisons are meaningful. Across retrievers, only the ordering carries information that both sides share. This is why fusion methods that throw away magnitudes tend to be more reliable than methods that calibrate them: the calibration step has to estimate a mapping from one arbitrary scale to another, and that mapping is query-dependent. A query with many rare terms produces a wide BM25 score range; a query with common terms produces a compressed one. A single global normalization curve cannot handle both.

The exception is when the score distributions are estimated per query rather than globally. That is what the normalization literature is about.

Three normalization families and what each assumes

Min-max normalization maps the retrieved set’s scores linearly into $[0,1]$:

$$\hat{s}(d) = \frac{s(d) - \min_{d’ \in R} s(d’)}{\max_{d’ \in R} s(d’) - \min_{d’ \in R} s(d’)}$$

It is cheap and scale-free per query, but it has two defects. It depends on the retrieved set rather than on the query, so changing the retrieval depth changes every document’s normalized score. And it is not stable: a single outlier score at the top compresses everything else near zero.

Z-score normalization centers and scales by the mean and standard deviation of the retrieved set. It preserves relative spacing better than min-max but still inherits the depth dependence, and it assumes the score distribution is roughly symmetric, which BM25 scores over a small retrieved set rarely are.

The third family fits a distribution to the scores of documents that match and maps through the fitted cumulative distribution, on the theory that the score distribution is a mixture of a relevance component and a noise component. This is the approach in the metasearch literature, where the score distributions from different engines are modeled separately and the normalized value is a probability of relevance rather than a rescaled score. It is more expensive and it requires enough retrieved documents to fit anything.

import math

def softmax_normalize(scores, temperature=1.0):
    """Map arbitrary scores to a distribution summing to 1."""
    if not scores:
        return []
    top = max(scores)
    exps = [math.exp((s - top) / temperature) for s in scores]
    total = sum(exps)
    return [e / total for e in exps]

Softmax has an appealing property that is easy to misread: the output sums to one, so it looks like a probability, and it is tempting to treat the normalized value as a confidence. It is not. The temperature is a free parameter, the distribution is over the retrieved set rather than over documents, and adding a document changes every other document’s normalized value. Used inside fusion, a softmax output is still only an ordering device, now with a dependency on set size.

Reciprocal rank fusion and the case for abandoning scores

Reciprocal rank fusion takes the opposite position: do not normalize, because normalization is where the errors come from. A document’s score is the sum over retrievers of $1/(k + \text{rank})$ where rank is 1-based and $k$ is a constant conventionally set to 60.

$$\text{RRF}(d) = \sum_{r \in R} \frac{1}{k + \text{rank}_r(d)}$$

The constants deserve scrutiny. With $k = 60$, the top-ranked document contributes $1/61 \approx 0.0164$, the second $1/62 \approx 0.0161$, and the hundredth $1/160 \approx 0.0063$. The gap between rank 1 and rank 2 in one list is tiny compared to the gap between rank 1 and rank 100. The effect is that agreement across lists dominates depth within a list: a document at rank 3 in both lists scores about $0.0317$ and beats a document at rank 1 in one list and unranked in the other, which scores $0.0164$.

That property is the reason RRF works without tuning and also the reason it is limited. It cannot express that one retriever is more trustworthy than another. Every list contributes equally, so a weak retriever that produces noise at rank 1 is as influential as a strong one.

Weighting is the obvious extension: multiply each list’s contribution by a weight. The weights then have to be chosen, which reintroduces a tuning problem, though a smaller one than calibration because there is no scale to estimate.

What the depth cutoff costs

RRF needs ranks on both sides, and a document missing from a list contributes nothing rather than a penalty. The practical consequence is a bias toward documents both retrievers found, which is the intent, but also a sensitivity to retrieval depth. If each list is truncated at 100, the two lists can produce at most 200 distinct candidates; fusion cannot recover a document that neither retriever placed in its top 100.

Increasing depth raises recall but also raises the influence of the tail. Because the contribution at rank 100 is $1/160$, a hundred deep ranks contribute less than seven top-ranked documents, so the marginal value of doubling depth is small. This is why the constant is large: it flattens the contribution curve so that deep ranks matter enough to break ties but not enough to dominate.

The constant also controls robustness to a single bad retriever. With $k = 0$ the formula is $1/\text{rank}$, and a document at rank 1 in one list and absent everywhere else scores 1.0 while a document at rank 2 in five lists scores about 1.14, so the consensus barely wins. Larger $k$ pushes the balance toward consensus.

Choosing a fusion rule in practice

The decision follows from what is known about the retrievers.

If the retrievers are heterogeneous and calibration is unreliable, as with a lexical index and a dense index and no labelled data, rank fusion is the safe default. It requires no assumptions about score ranges and no per-query statistics.

If there is labelled data, the better approach is to learn the fusion. Treat each retriever’s score as a feature, along with its rank, and train a model to produce the final ordering. This subsumes both weighted RRF and weighted score sums, and the weights are estimated rather than assumed. The machinery for this is in Learning-to-Rank Objective Functions; the point here is that hand-tuned fusion is a special case of a learned model with a fixed functional form.

If one retriever is clearly primary and the other is a recall booster, a cascade is better than fusion. Retrieve broadly with the cheap retriever, rescore the top candidates with the expensive one, and never combine the two scores at all. Cascades sidestep normalization because only one score per document reaches the final ordering. The trade is that a document the cheap retriever missed cannot be rescued by the expensive one.

The degenerate cases that show up as bugs

A retriever returning no results contributes an empty list, and RRF handles this correctly by contributing nothing. But if a query is routed to a retriever that always returns its full index, a filter that matches everything, every document gets a rank from that list, and its $1/(k+\text{rank})$ contribution becomes a length-dependent tiebreaker over the whole corpus. Fusion with a permissive list is dominated by that list’s ordering rather than by agreement.

Duplicate ranks appear when a retriever assigns ties. Two documents at the same rank both contribute $1/(k+r)$ and are separated only by their other lists’ contributions. Implementations that assign distinct ranks by sorting on a secondary key produce different fusion output than implementations that share the rank, and neither is wrong, but mixing the two conventions across retrievers introduces an arbitrary advantage.

Finally, rank positions are 1-based in the standard formulation. An off-by-one in the constant makes the top rank $1/k$ instead of $1/(k+1)$, which is a small absolute change but shifts the effective consensus/depth balance slightly. It is the kind of discrepancy that shows up as a systematic difference between two implementations of the same published method rather than as a visible bug.

Combining fusion with normalization, and when not to

A hybrid that normalizes scores and then sums them is often worse than either pure approach, and the reason is that the two steps have incompatible assumptions. Normalization is per-query and set-dependent; a weighted sum of normalized scores behaves like a linear model over features whose scale changes between queries, so the effective weight of each retriever varies with the query.

What does work is normalizing and then fusing by rank anyway, or normalizing per retriever with a monotone transform that is fit once on a calibration set and applied unchanged at query time. The second is only sound when the score distribution is stable across queries, which for BM25 is false in general and for cosine similarity over a fixed embedding model is closer to true.

Where a fixed transform is defensible, it makes the resulting fused score interpretable enough to feed into a downstream layer, which is why calibrated scores matter for Score Calibration for Blended Ranking. Where it is not, rank fusion remains the honest option: it discards exactly the information that cannot be trusted.

References

  1. Reciprocal Rank Fusion Outperforms Condorcet and Individual Rank Learning Methods — Cormack, Clarke & Büttcher, SIGIR 2009
  2. Relevance Score Normalization for Metasearch — Montague & Aslam, CIKM 2001
  3. Introduction to Information Retrieval — Manning, Raghavan & Schütze, Cambridge University Press, 2008