

0 / 2 embers
0 / 3000 xp
click for more info
Complete a lesson to start your streak
click for more info
Still calibrating
click for more info
Not enough gems
Cost: 6 gems
1: BM25
incomplete
2: Term Frequency Saturation
incomplete
3: Document Length Normalization
incomplete
4: BM25 Search
incomplete
This lesson's interactive features are locked, please to keep using them
The final BM25 improvement is document length normalization: preventing longer documents from getting an unfair advantage over shorter, more focused ones. Longer documents contain more words, which can artificially boost their scores:
Query: "bear"
Document B has higher term frequencies just because it's longer, not because it's more relevant!
BM25 adjusts term frequency based on document length:
# Length normalization factor
length_norm = 1 - b + b * (doc_length / avg_doc_length)
# Apply to term frequency
tf_component = (tf * (k1 + 1)) / (tf + k1 * length_norm)
Let's break it down.
doc_length / avg_doc_lengthThis ratio tells us how this document's length compares to the average document length in the dataset:
| Ratio | Meaning | Effect |
|---|---|---|
| = 1.0 | Average length | No change |
| > 1.0 | Longer than average | Penalized |
| < 1.0 | Shorter than average | Boosted |
b (Normalization Strength)b is a tunable parameter that controls how much document length affects the score.
b = 0, length normalization is always 1.b = 1, full normalization is applied.The key idea:
length_norm and are penalized (lower scores).length_norm and are boosted (higher scores).A common b value is 0.75, which tends to work well in most scenarios.
Implement the BM25 document length normalization formula in our InvertedIndex class. Use a b value of 0.75 and a k1 value of 1.5.
BM25_B = 0.75
bm25_tf_parser.add_argument(
"b", type=float, nargs="?", default=BM25_B, help="Tunable BM25 b parameter"
)
Run and submit the CLI tests.