Problems
Loading...
1 / 1

Implement BM25 Ranking Score

NLPLinear AlgebraData Processing
Hard

Implement the BM25 ranking score to rank a list of documents for a tokenized query. Return a score per document (higher = more relevant).

IDF Formula:

idf(t)=log(Ndf(t)+0.5df(t)+0.5+1)\text{idf}(t) = \log\left(\frac{N - \text{df}(t) + 0.5}{\text{df}(t) + 0.5} + 1\right)

BM25 Score:

score(D,Q)=tQidf(t)tf(t,D)(k1+1)tf(t,D)+k1(1b+bDavgdl)\text{score}(D, Q) = \sum_{t \in Q} \text{idf}(t) \cdot \frac{\text{tf}(t, D) \cdot (k_1 + 1)}{\text{tf}(t, D) + k_1 \left(1 - b + b \cdot \frac{|D|}{\text{avgdl}}\right)}

Where: N = #docs, df(t) = #docs containing t, |D| = doc length, avgdl = average doc length

Function Arguments

  • query_tokens: list[str] - List of query terms to search for
  • docs: list[list[str]] - List of documents, each document is a list of tokens
  • k1: float = 1.2 - Term frequency saturation parameter
  • b: float = 0.75 - Length normalization parameter
Loading visualization...

Examples

Input: query=["machine","learning"], docs=[["introduction","to","machine","learning"], ["deep","learning","basics"], ["cooking","pasta","guide"]]

Output: [1.34111, 0.49005, 0.00000]

scores[0] ≥ scores[1] ≫ scores[2] (doc 0 has both terms, doc 1 has one term, doc 2 has none)

Input: query=["data"], docs=[["data","science"], ["big","data","analytics"], ["cooking","recipes"]]

Output: [0.49918, 0.42082, 0.00000]

Hint 1

Use Counter to count term frequencies in each document and document frequencies across the corpus. Use set() to get unique terms per document.

Hint 2

Use np.array() for document lengths and np.mean() for average length. Use dict.fromkeys() to deduplicate query terms while preserving order.

Hint 3

Use math.log() for IDF calculation and np.zeros() to initialize the score array. Use .get() method on Counter objects for safe term frequency lookups.

Requirements

  • Use the formula above with the provided parameters
  • Return np.ndarray of shape (len(docs),) (dtype float)
  • If a query term never appears in the corpus, its idf can be 0
  • Handle empty corpus by returning an empty array

Constraints

  • Corpus size ≤ 10,000 docs; each doc length ≤ 2,000 tokens
  • Vectorized where reasonable; avoid heavy nested loops
  • Libraries: NumPy + standard library only
Try Similar Problems