Precision@k and NDCG@k
Background
Ranking metrics judge an ordered list of results, not a single prediction. Precision@k is the fraction of the top- results that are relevant. NDCG@k (Normalised Discounted Cumulative Gain) additionally rewards placing more relevant items higher, discounting gains logarithmically by rank and normalising against the ideal ordering. They are the workhorse metrics of search and recommendation evaluation.
Problem statement
Implement precision_at_k(relevances, k) and ndcg_at_k(relevances, k), where relevances lists the relevance scores in the model's ranked order (higher = more relevant; relevance means "relevant"):
where is the DCG of the relevances sorted in descending order.
Input
relevances—list[float]: relevance scores in ranked order.k—int: the cutoff rank.
Output
precision_at_kreturns afloatin .ndcg_at_kreturns afloatin ( = ideal ordering).
Examples
Example 1
Input: relevances = [3, 2, 3, 0, 1, 2], k = 3
Output: precision_at_k = 1.0, ndcg_at_k = 0.9778
Explanation: all of the top 3 are relevant (P@3 = 1.0). DCG@3 = ; dividing by the ideal DCG (relevances sorted descending) gives NDCG@3 = 0.9778.
Constraints
- Rank positions start at 1; the discount for position is .
- Precision@k counts relevance as relevant and always divides by .
- NDCG normalises by IDCG@k (ideal ordering); return if IDCG@k is .
- Tests compare with
atol=1e-4.
Notes
- The log discount encodes "higher ranks matter more": moving a relevant item from rank 1 to rank 10 sharply reduces its contribution.
- NDCG lies in and is comparable across queries thanks to the per-query ideal-DCG normalisation, unlike raw DCG.
This problem ships 4 hidden tests. They run in your browser via Pyodide — no backend, no submission queue. Press ▶ Run tests to execute.
- •Precision@3 = 1.0 (all top-3 relevant)
- •Precision@k counts relevance > 0 and divides by k
- •NDCG of the ideal ordering is 1.0
- •NDCG@3 matches the discounted-gain definition