Co-authored-by: Soumil Rathi <soumilrathi@gmail.com> Co-authored-by: Saket Aryan <saketaryan2002@gmail.com> Co-authored-by: chaithanyak42 <chaithanya.kumar42a@gmail.com> Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
51 lines
1.4 KiB
Python
51 lines
1.4 KiB
Python
"""
|
|
BM25 lemmatization for consistent keyword matching.
|
|
|
|
Uses spaCy's lemmatizer for better handling of:
|
|
- Verb forms: attending/attends/attended -> attend
|
|
- Comparatives/superlatives: older/oldest -> old
|
|
- Plurals: memories -> memory
|
|
- Avoids over-stemming: organization != organize
|
|
|
|
Also includes original -ing forms alongside lemmas to handle cases
|
|
where spaCy's context-dependent lemmatization produces inconsistent
|
|
results (e.g., "meeting" as noun vs verb -> different lemmas).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def lemmatize_for_bm25(text: str) -> str:
|
|
"""Lemmatize text for BM25 matching.
|
|
|
|
Returns space-joined lemmas for full-text search. Falls back to
|
|
the original text if spaCy is unavailable.
|
|
"""
|
|
from mem0.utils.spacy_models import get_nlp_lemma
|
|
|
|
nlp = get_nlp_lemma()
|
|
if nlp is None:
|
|
return text
|
|
|
|
doc = nlp(text.lower())
|
|
tokens = []
|
|
|
|
for token in doc:
|
|
if token.is_punct or token.is_stop:
|
|
continue
|
|
|
|
lemma = token.lemma_
|
|
if lemma.isalnum():
|
|
tokens.append(lemma)
|
|
|
|
# Also add original if it ends in -ing and differs from lemma.
|
|
# This handles noun/verb ambiguity (meeting/meet, attending/attend).
|
|
if token.text.endswith("ing") and token.text != lemma and token.text.isalnum():
|
|
tokens.append(token.text)
|
|
|
|
return " ".join(tokens)
|