October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk5 min

Why Repeated “Python” Can Win Search—and How BM25F Weighs Fields

A raw-count search scorer can reward repeated terms without regard to field or document length. Learn how BM25F combines weighted, normalized field frequencies and how to build a compact pure-Python example.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A simple search scorer can rank a document higher just because it repeats “python.” BM25F can reduce that effect by combining field-aware term frequencies, document-length normalization, field weights and term-frequency saturation. It does not guarantee a better result: the fields, parameters and relevance goal still matter. The phrase “ranks #1” here describes an illustrative failure mode, not a verified result from a particular search engine or corpus.

Why repeating a query term can distort a ranking

Consider a basic scorer that adds a document’s occurrences of each query term:

As an Amazon Associate I earn from qualifying purchases.

score(doc, query) = sum(count(term, doc) for term in query)

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For a query containing one token, python, a document with three occurrences receives three points while a document with one occurrence receives one, if all else is equal. This example keeps the query to one token: some implementations deduplicate repeated query tokens, while others count each duplicate query token again. The example is about repeated occurrences in the document, not about counting the same query token multiple times.

Raw counts also ignore where a match appears and give longer documents more chances to accumulate occurrences. A title mention and a body mention count the same unless the scorer explicitly distinguishes those fields. This explains how repetition can create a misleading win; it does not establish that any particular search product returns a specific document first.

How BM25F changes the scoring

BM25F applies the BM25 approach to multiple document fields, often called streams. It first normalizes term frequency within each field, weights the fields, combines their contributions, and then applies a saturating term-frequency calculation. BM25-family scoring also uses inverse document frequency (IDF), which reflects how common a term is across the collection.

For field s, the length-normalization factor is B_s = (1 - b_s) + b_s × (field_length / average_field_length). The setting b_s controls how much that field’s length affects its normalized frequency. A field’s normalized term frequency is then combined with other fields using their weights before saturation. In practical terms, additional occurrences can still increase a score, but their contribution levels off rather than growing in a straight line.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Robertson and Zaragoza’s 2009 review describes BM25F as a field-aware extension of the BM25 framework and discusses collection-wide IDF. It also warns that a collection-wide IDF can produce degenerate cases if one stream is unusually verbose and contains most terms in most documents. See The Probabilistic Relevance Framework: BM25 and Beyond.

Raw counts and BM25F compared

Scoring question Naive raw-count scorer BM25F
Term frequency Adds occurrences according to the implementation’s counting rule. Combines field frequencies and saturates their contribution.
Document length Usually does not normalize for length; longer text can offer more chances for matches. Normalizes term frequency separately by field length and average field length.
Document structure Treats text as one pool unless fields are programmed separately. Can give fields such as title and body distinct weights.
IDF Often omitted from a simple count baseline. Includes an IDF component; the reviewed formulation discusses collection-level IDF and its caveat for unusually verbose fields.
Tuning May have few or no relevance-specific settings. Requires field weights and per-field normalization settings suited to the collection and task.

Implement a small BM25F scorer in pure Python

The example below uses only Python’s standard library. It tokenizes by lowercasing and splitting on whitespace, and scores the single query token python. The code computes field-specific average lengths, field-normalized frequencies, an IDF term and a saturation term, then sorts documents by score. The illustrative documents and resulting order are hypothetical; the code is provided to make the mechanics inspectable, not as a reported test result.

from math import log1p

# Hypothetical documents: fields must be parsed consistently.
docs = [
    {"id": "A", "title": "Python guide", "body": "python python python"},
    {"id": "B", "title": "Python", "body": "A guide to programming"},
]
fields = ("title", "body")
query = ["python"]  # one query token; document repetitions drive TF here

# Illustrative settings, not universal recommendations.
k = 1.5
weights = {"title": 3.0, "body": 1.0}
b = {"title": 0.75, "body": 0.75}

def tokens(text):
    return text.lower().split()

lengths = {
    field: [len(tokens(doc[field])) for doc in docs]
    for field in fields
}
avg_length = {
    field: sum(lengths[field]) / len(docs)
    for field in fields
}
df = {
    term: sum(
        any(term in tokens(doc[field]) for field in fields)
        for doc in docs
    )
    for term in query
}

scores = []
for i, doc in enumerate(docs):
    score = 0.0
    for term in query:
        combined_tf = 0.0
        for field in fields:
            field_tokens = tokens(doc[field])
            tf = field_tokens.count(term)
            avg = avg_length[field]
            norm = (1 - b[field]) + b[field] * (len(field_tokens) / avg)
            combined_tf += weights[field] * tf / norm
        idf = log1p((len(docs) - df[term] + 0.5) / (df[term] + 0.5))
        score += idf * (combined_tf * (k + 1)) / (combined_tf + k)
    scores.append((score, doc["id"]))

for score, doc_id in sorted(scores, reverse=True):
    print(doc_id, score)

The normalization and saturation terms follow the BM25F logic, while tokenization, parameter choices and this compact IDF expression are explicit implementation choices. The code is a teaching example, not a production search engine: it does not handle punctuation, stemming, stop words, phrase matching or a large index efficiently. For a project-specific title/text example, the BM25-Search documentation lists k=1.5, b=[0.75, 0.75] and w=[3.0, 1.0]; treat these as that project’s example values, not defaults for every corpus. See BM25-Search project documentation.

Choose fields and parameters for the collection

A title boost is an assumption that a title match is more informative for the search task than a body match. That can be sensible, but it is not universally correct. A collection with no reliable titles, inconsistently parsed fields or a task where body details dominate may need different fields or weights.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Keep field extraction and tokenization consistent between indexed documents and queries.
  • Choose field weights and per-field b values as tunable relevance settings, not facts about all search tasks.
  • Check whether one field is so verbose that it contains most terms for most documents; collection-level IDF can behave poorly in that situation.
  • Evaluate with relevance judgments or representative queries, rather than assuming that changing the formula alone improves results.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

How to tell whether the change helped

For a fair comparison, hold the corpus, query tokenization and candidate documents constant. Rank the same examples first with raw counts and then with BM25F. Inspect each BM25F score’s field frequencies, length-normalization factors, weights, IDF and saturation contribution. If repeated body occurrences dominate despite a more meaningful title match, adjust the model only when relevance judgments support that change; then evaluate across representative queries, not just one example.

BM25F changes how matches are scored; it does not understand context or guarantee that a repeated-term document will stop ranking first. The outcome depends on fields, tokenization, parameters, corpus statistics and what counts as relevant.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.