dorianbrown/rank_bm25
dorianbrown/rank_bm25 has 1,417 GitHub stars and 115 forks. GitHot measured 0 stars in 24 hours. Last checked 2026-11-08 05:39 UTC. Last push 2026-05-02.
A Collection of BM25 Algorithms in Python
Measured star growth
- in 24h
- 0
- in 7 days
- Collecting history
- in 15 days
- Collecting history
- in 1 month
- Collecting history
Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.
README.md
OriginalRank-BM25: A two line search engine
A collection of algorithms for querying a set of documents and returning the ones most relevant to the query. The most common use case for these algorithms is, as you might have guessed, to create search engines.
So far the algorithms that have been implemented are:
- Okapi BM25
- BM25L
- BM25+
- BM25-Adpt
- BM25T
These algorithms were taken from this paper, which gives a nice overview of each method, and also benchmarks them against each other. A nice inclusion is that they compare different kinds of preprocessing like stemming vs no-stemming, stopword removal or not, etc. Great read if you're new to the topic.
For those looking to use this in large scale production environments, I'd recommend you take a look at something like retriv, which is a much more performant python retrieval package. See #27
Installation
The easiest way to install this package is through pip, using
pip install rank_bm25
If you want to be sure you're getting the newest version, you can install it directly from github with
pip install git+ssh://[email protected]/dorianbrown/rank_bm25.git
Usage
For this example we'll be using the BM25Okapi algorithm, but the others are used in pretty much the same way.
Initalizing
First thing to do is create an instance of the BM25 class, which reads in a corpus of text and does some indexing on it:
from rank_bm25 import BM25Okapi
corpus = [
"Hello there good man!",
"It is quite windy in London",
"How is the weather today?"
]
tokenized_corpus = [doc.split(" ") for doc in corpus]
bm25 = BM25Okapi(tokenized_corpus)
# <rank_bm25.BM25Okapi at 0x1047881d0>
Note that this package doesn't do any text preprocessing. If you want to do things like lowercasing, stopword removal, stemming, etc, you need to do it yourself.
The only requirements is that the class receives a list of lists of strings, which are the document tokens.
Ranking of documents
Now that we've created our document indexes, we can give it queries and see which documents are the most relevant:
query = "windy London"
tokenized_query = query.split(" ")
doc_scores = bm25.get_scores(tokenized_query)
# array([0. , 0.93729472, 0. ])
Good to note that we also need to tokenize our query, and apply the same preprocessing steps we did to the documents in order to have an apples-to-apples comparison
Instead of getting the document scores, you can also just retrieve the best documents with
bm25.get_top_n(tokenized_query, corpus, n=1)
# ['It is quite windy in London']
And that's pretty much it!
Explore related projects
codecrafters-io/build-your-own-x
Master programming by recreating your favorite technologies from scratch.
560,861 starspublic-apis/public-apis
A collective list of free APIs
497,105 starsmorluto/rea
Reverse engineer anything with agents, from app behavior down to native binaries.
441,758 starsopenclaw/openclaw
The AI that really does things. Any OS. Any Platform. The lobster way. 🦞
394,164 stars