ML Systems Lab Open interactive version →
Intermediate 30 min read NDCGMAPMRRrankingRecSys

Ranking Metrics

NDCG, MAP, MRR — search and recommendation quality

You type "Python tutorial for beginners" into a search box and get back ten results. Suppose the truly useful ones sit at positions 1, 3, and 7. A metric that just counts "3 of 10 are relevant" scores this 0.30 — and would give the *same* 0.30 if those three results were buried at positions 8, 9, and 10. But you know that is wrong: nobody reads past the first couple of results once they have their answer. Any metric that ignores *position* is nearly useless for search and recommendation.

So the whole family of ranking metrics is built on one idea: a relevant result near the top is worth far more than the same result near the bottom. They differ in how much detail they capture.


MRR — where is the first good one?

The simplest is Mean Reciprocal Rank. It cares about one thing: the position of the *first* relevant result. If it is at position 1 you score 1/1 = 1.0; at position 3, 1/3 = 0.33. Average that across all your queries and you have MRR. Flip it around and 1/MRR reads as the *effective rank* of the first relevant result: MRR = 0.60 means the first hit lands, on average, around rank 1.67; push MRR to 0.75 and that effective rank drops to about 1.33. It fits perfectly when the user has a single need and stops at the first good answer — a fact lookup, an FAQ, a "just take me to X" query. It is the wrong choice the moment users want *several* relevant results, because it ignores everything after the first hit.


MAP — did you find them all, and early?

Mean Average Precision rewards surfacing relevant results both early *and* completely. For one query, walk down the list, and each time you hit a relevant result note the precision so far; sum those, then divide by the total number of relevant results. For our example (relevant at 1, 3, 7, three relevant total): (1/3)(1/1 + 2/3 + 3/7) ≈ 0.70. Average across queries to get MAP. It only needs yes/no relevance labels, which makes it cheap to collect.


NDCG — the industry standard

Normalized Discounted Cumulative Gain adds the one thing MAP lacks: *grades* of relevance. A result can be perfect (grade 3), okay (grade 1), or useless (grade 0), not just relevant or not. NDCG folds in two moves: each result contributes (2^grade − 1), so a perfect hit counts far more than a so-so one; and each position is discounted by log₂(position + 1), so position 1 counts fully, position 3 about half, position 10 under a third. Divide by the score of the *ideal* ordering and you get a number from 0 to 1 that is comparable across queries. This is what commercial search and recommendation teams actually use, when they have graded human judgments and position matters.


Which one? Match the metric to what users do

There is no single best ranking metric — the right one mirrors real behavior. If users scan a vertical list and stop at the first hit, use MRR. If they expect to find all the relevant results and would be annoyed to see any buried, use MAP. If you have graded labels and care about exact ordering, use NDCG. And if every shown slot is equally prominent regardless of order — a grid of products, a row of ad slots — plain Precision@K is fine. Pick by what the interface makes people do, not by which formula looks most impressive.


Retrieval's own metrics: recall@K and hit-rate@K

Big systems rank in two stages — a cheap candidate generator pulls a few hundred items from millions, then an expensive ranker orders them. These stages need different metrics. For retrieval the question isn't "is the order perfect?" but "did we even *retrieve* the relevant items into the candidate set?" That's recall@K (of all relevant items, how many made it into the top K) and hit-rate@K (did at least one relevant item land in the top K). A ranker can't fix what retrieval never surfaced, so you measure recall@K on the generator and NDCG/MAP on the ranker — diagnosing the wrong stage is a classic mistake.


Relevance isn't the only goal

Pure relevance metrics miss things a real recommender must balance. Coverage — what fraction of the catalog ever gets shown (a system that only recommends the top 100 items starves the long tail). Diversity — are the top results varied, or ten near-duplicates? Novelty / serendipity — does it surface things the user wouldn't have found alone, not just the obvious? Freshness — new content shown before it goes stale. Creator fairness — is exposure spread across creators or concentrated? A model that maxes NDCG by always showing the same popular items can quietly wreck coverage and diversity, and the business notices even though the relevance metric looks great.


The elephant: position bias in click labels

If your relevance labels come from *clicks*, they're contaminated. The item at position 1 gets more clicks because it was shown first, not because it's more relevant — so training or evaluating on raw clicks teaches the model to reproduce the old ranking's position effects rather than true relevance, a self-reinforcing loop. The fixes are their own field: inverse-propensity weighting to down-weight clicks that only happened due to position, interleaving (blend two rankers' results and see which gets clicked, which cancels position bias), and counterfactual evaluation — estimating how a *different* ranking policy would have performed, using data logged under the old policy, without actually deploying the new one to find out. Never treat click data as clean relevance.


Offline-online gaps: it isn't always position bias

Position bias in click labels is not the only reason a healthy offline score can miss what users feel. The offline test set itself can be stale — judgments and even the candidate catalog were captured at some past date, so a model can keep matching outdated ground truth while the real catalog and real user intent have moved on. And offline metrics are almost always computed per item — one score per query, per result list — while the actual user experience unfolds per session, across several searches or scroll loads in a row; a ranking that scores fine query-by-query can still feel repetitive or exhausting once you look at the whole session. When an offline number and online sentiment disagree, check the freshness of your judgments and whether you're measuring the right unit (item vs. session) before assuming the metric itself is wrong.


Metric@K: K is a product decision

NDCG@1, @3, @10, @50 answer *different* questions, and K should match how the interface is actually used. NDCG@1 is for "I feel lucky" single-answer surfaces; NDCG@10 for a first page of ten; NDCG@50 for a scroll-heavy feed or a candidate pool feeding a downstream reranker. Set K to the viewport and session behaviour, not to a default — reporting NDCG@10 for a mobile screen that shows three results is measuring the wrong thing.


Ties and unjudged documents

Two practical hazards. Ties (items with equal score) make the metric depend on arbitrary tiebreak order — resolve them deterministically or you'll see phantom metric swings. And unjudged ≠ irrelevant: with millions of documents, only a pooled subset gets human labels, so a genuinely relevant document nobody judged is scored 0 by default, penalising a new system that surfaces it. This pooling bias is why a better retriever can look worse offline; judge the novel results before trusting the comparison.


You can't optimise these metrics directly

A final subtlety interviewers probe: NDCG, MAP, and MRR are based on *sorting*, which is not differentiable, so you can't gradient-descend on them directly. Ranking models therefore optimise a surrogate loss — pairwise (learn "A should rank above B," as in RankNet/LambdaRank) or listwise (score the whole list, as in ListNet) — that correlates with the target metric while being differentiable. LambdaMART's trick is to weight those pairwise gradients by their NDCG impact, getting a ranking-aware signal without needing NDCG to be differentiable.

Key points

Takeaway

All ranking metrics embed a model of user attention — MRR says users stop after the first hit, MAP says they care about every relevant item equally, NDCG says attention decays with position and highly relevant results matter more — so choosing the metric is choosing which user behaviour you believe, not which formula is standard.

Recap

Check your understanding

Q1. A search engine retrieves 3 relevant documents at ranks 1, 3, 5, out of 5 total relevant documents. Compute Average Precision (AP).

Q2. Your recommendation system shows NDCG@10 = 0.85 offline, but users complain the results feel irrelevant. Which two of the following could plausibly explain the gap? Select two.

Q3. A search system has MRR = 0.60. A manager wants 0.75. What does that mean concretely, and what would you change?

Q4. You have graded relevance labels (0-3) and want to compare two rankers. Should you use MAP or NDCG?

Q5. A new retrieval model surfaces documents the old system never showed, and offline NDCG comes out lower than the old model. What is the likely explanation before you conclude the new model is worse?

Q6. An interviewer asks: "Why can't you train a ranking model by directly minimising 1 − NDCG with gradient descent?"

Try it interactively

ML Systems Lab is a free interview-prep platform for ML engineers — work through the full interactive module, quizzes, and drills.

Open ML Systems Lab →