BM25 Keyword Search

medium
Unit 16 · Inference II0/2 to milestone

Vector search misses exact keywords like product codes and names, so production RAG pairs it with BM25, the classic keyword-ranking function behind Elasticsearch and Lucene.

For a query qq and document DD:

score(D,q)=∑t∈qIDF(t)⋅f(t,D) (k1+1)f(t,D)+k1(1−b+b ∣D∣avgdl)\text{score}(D, q) = \sum_{t \in q} \text{IDF}(t) \cdot \frac{f(t, D)\,(k_1 + 1)}{f(t, D) + k_1\left(1 - b + b\,\frac{|D|}{\text{avgdl}}\right)} IDF(t)=ln⁡(N−nt+0.5nt+0.5+1)\text{IDF}(t) = \ln\left(\frac{N - n_t + 0.5}{n_t + 0.5} + 1\right)

where f(t,D)f(t, D) is how often term tt appears in DD, ∣D∣|D| is the document's length in tokens, avgdl is the average document length, NN is the number of documents and ntn_t is how many documents contain tt.

Implement bm25_scores(query, docs, k1=1.5, b=0.75) returning one score per document, in order.

Tokenising: lowercase, then split on whitespace. Count each distinct query term once, even if the query repeats it. Terms that appear in no document contribute nothing.

#rag#retrieval#search3 visible + 3 hidden tests
solution.py · Python 3.13
Loading editor…
Run your code to see results. ⌘↵ to run · ⌘⇧↵ to submit
BM25 Keyword Search · TechGradify