sparknlp.annotator.similarity.bm25#
Contains classes for the BM25 lexical document ranker.
Module Contents#
Classes#
Trains a BM25 (Okapi BM25) lexical ranker over a corpus of tokenized |
|
Fitted model produced by |
- class BM25Approach[source]#
Trains a BM25 (Okapi BM25) lexical ranker over a corpus of tokenized documents.
BM25 is a bag-of-words retrieval function that ranks documents against a query based on the query terms appearing in each document. Because a document’s score depends on corpus-level statistics (how many documents contain a term, and the average document length), BM25 is implemented as a two-phase Estimator/Model pair:
BM25Approach(this class) scans the full corpus once duringfit()and learns the document countN, the document frequencydf(t)of every term, the average document lengthavgdland the inverse document frequencyidf(t)of every term.BM25Modelreuses those statistics to score every document against a user-provided query.
The input is a column of
TOKENannotations, so BM25 is normally placed after aTokenizer(optionally followed by aNormalizerand/orStopWordsCleaner).Input Annotation types
Output Annotation type
TOKENBM25_RANKINGS- Parameters:
- k1
Term-frequency saturation parameter (typical range [1.0, 2.0]), by default 1.2
- b
Length-normalization parameter (range [0.0, 1.0]), by default 0.75
- minDocFreq
Drop terms that appear in fewer than this many documents, by default 1
- caseSensitive
Whether to treat tokens case-sensitively when computing statistics, by default False
Examples
>>> import sparknlp >>> from sparknlp.base import * >>> from sparknlp.annotator import * >>> from pyspark.ml import Pipeline >>> document_assembler = DocumentAssembler() \ ... .setInputCol("text") \ ... .setOutputCol("document") >>> tokenizer = Tokenizer() \ ... .setInputCols(["document"]) \ ... .setOutputCol("token") >>> stop_words_cleaner = StopWordsCleaner() \ ... .setInputCols(["token"]) \ ... .setOutputCol("clean_token") \ ... .setCaseSensitive(False) >>> bm25 = BM25Approach() \ ... .setInputCols(["clean_token"]) \ ... .setOutputCol("bm25_rankings") \ ... .setK1(1.2) \ ... .setB(0.75) \ ... .setMinDocFreq(1) \ ... .setCaseSensitive(False) >>> pipeline = Pipeline(stages=[ ... document_assembler, tokenizer, stop_words_cleaner, bm25]) >>> model = pipeline.fit(corpus) >>> model.stages[-1].setQuery("vitamin C health benefits fruits") >>> model.transform(corpus).selectExpr("explode(bm25_rankings) as r").show()
- setK1(value)[source]#
Sets the term-frequency saturation parameter k1, by default 1.2.
- Parameters:
- valuefloat
Term-frequency saturation parameter (typical range [1.0, 2.0])
- setB(value)[source]#
Sets the length-normalization parameter b, by default 0.75.
- Parameters:
- valuefloat
Length-normalization parameter (range [0.0, 1.0])
- class BM25Model(classname='com.johnsnowlabs.nlp.annotators.similarity.BM25Model', java_model=None)[source]#
Fitted model produced by
BM25Approach.It holds the corpus-level statistics (IDF map, average document length and document count) and scores every document in a dataset against a query using the Okapi BM25 ranking function. The query is provided at transform time, so the same fitted model can be reused for many different queries (“fit once, query many times”). Provide it either as a raw string with
setQuery(...)or — recommended when the corpus was analyzed by a non-trivial pipeline — as already-analyzed tokens withsetQueryTokens(...)(see the analyzer-symmetry warning below).For every input document the model emits a single
BM25_RANKINGSannotation whoseresultis the BM25 score and whosemetadatacontainsbm25_score,num_query_terms_matched,queryanddoc_len.Warning
Analyzer symmetry. BM25 only scores a query term when it matches a key in the learned IDF vocabulary, and those keys were produced by the pipeline placed in front of
BM25Approach(Tokenizer,Normalizer, a stemmer/lemmatizer, …). A raw-stringsetQueryis only split on non-word characters and lowercased; if your corpus pipeline transforms tokens (stemming, lemmatization, punctuation stripping, …), a raw query can silently fail to match. In that case run the query through the same pipeline (e.g. with aLightPipeline) and pass the resulting tokens tosetQueryTokens.Input Annotation types
Output Annotation type
TOKENBM25_RANKINGS- Parameters:
- query
The query to score every document against, as a raw string. The model splits it on non-word characters; prefer
queryTokensfor non-trivial pipelines (see the analyzer-symmetry warning above).- queryTokens
The query as a list of already-analyzed terms. When non-empty it overrides
query. Obtain these by running the query through the same pipeline used for the corpus, so query and documents match.- k1
Term-frequency saturation parameter (carried over from the approach)
- b
Length-normalization parameter (carried over from the approach)
- caseSensitive
Whether tokens are treated case-sensitively. Read-only: it is fixed when the corpus statistics are computed and must not be changed on a fitted model, so there is no
setCaseSensitivehere.
Examples
>>> from sparknlp.annotator import BM25Model >>> loaded = BM25Model.load("/tmp/bm25_corpus_model") >>> loaded.setQuery("neural networks deep learning")
- setQuery(value)[source]#
Sets the query that every document is scored against.
The same fitted model can be re-queried by calling
setQueryagain.- Parameters:
- valuestr
The query string
- setQueryTokens(value)[source]#
Sets the query as a list of already-analyzed terms.
When non-empty these override the raw
querystring. Obtain them by running the query through the same pipeline used for the corpus (for example with aLightPipeline) so that the query and the documents are analyzed identically.- Parameters:
- valueList[str]
Pre-analyzed query terms
- setK1(value)[source]#
Sets the term-frequency saturation parameter k1.
- Parameters:
- valuefloat
Term-frequency saturation parameter (typical range [1.0, 2.0])
- setB(value)[source]#
Sets the length-normalization parameter b.
- Parameters:
- valuefloat
Length-normalization parameter (range [0.0, 1.0])
- setCaseSensitive(value)[source]#
caseSensitiveis read-only on a fittedBM25Modeland cannot be set.It is fixed when the corpus statistics are computed by
BM25Approachand is baked into the IDF vocabulary keys. Changing it on a fitted model would desynchronize the query/document terms from the stored vocabulary and silently corrupt every score, so set it onBM25Approachbeforefit()instead.This method is defined only to override the setter that Spark NLP would otherwise generate automatically for every parameter; calling it always raises.
- Raises:
- AttributeError
Always, because
caseSensitiveis read-only on the model.