BM25是信息检索领域中一个重要的排序算法,它用来计算查询与文档之间的相关性。让我们通过一个图书馆的例子来理解:
想象你是一个图书馆管理员,有人来问你:“我想找关于太空探索和火星的书”。
传统TF-IDF方法: 就像你先数一数每本书中"太空探索"和"火星"这些词出现的次数,然后优先推荐这些词出现最多的书。但这有个问题:如果一本1000页的书和一本100页的书都提到"火星"10次,按理说短书中这个词更重要,但简单计数无法体现这点。
BM25的改进:
词频饱和度:BM25认为一个词出现次数多不等于无限重要。就像你吃饭,前几口很香,但吃到第20口时增加的满足感已经不明显了。同样,BM25对词频设定了上限,防止某些词重复很多次的文档不合理地获得超高分数。
文档长度归一化:BM25会考虑文档长度。如果两本书都提到"火星"5次,但一本是50页,另一本是500页,那么在短书中这个词显然更突出,BM25会给短书更高的相关性分数。
可调参数:BM25有两个重要参数k1和b,就像烹饪时可以调整火候和调料比例一样,这两个参数可以根据不同的信息检索系统特点进行调整。
实际应用中,BM25的计算公式会给每个查询词和文档对计算一个分数,然后把所有词的分数加起来得到最终排名。这就像图书管理员不仅看关键词出现的频率,还会考虑书的厚度、关键词的重要性等多方面因素,为读者推荐最相关的书籍。
BM25因其简单高效且效果良好,至今仍是许多搜索引擎的基础算法,包括Elasticsearch、Solr等流行的搜索平台。
LangChain框架中集成了BM25作为一种重要的检索算法,主要用于构建高效的向量存储和检索系统。下面详细解析LangChain中BM25的实现和使用方法:
LangChain中的BM25主要位于langchain.retrievers.bm25
模块中,它作为一种非向量化的检索器实现,可以在不需要嵌入模型的情况下进行文本相似度搜索。
from langchain.retrievers import BM25Retriever
from langchain.schema import Document
# 创建示例文档
documents = [
Document(page_content="LangChain是一个用于构建基于大语言模型应用的框架"),
Document(page_content="BM25是一种经典的信息检索算法"),
Document(page_content="向量数据库用于存储和检索嵌入向量"),
# 更多文档...
]
# 初始化BM25检索器
retriever = BM25Retriever.from_documents(documents)
retriever.k = 2 # 设置返回结果数量
# 执行检索
results = retriever.get_relevant_documents("信息检索算法")
LangChain中的BM25实现主要依赖于rank_bm25
库,它通过以下步骤工作:
文档预处理:
索引构建:
相关性计算:
LangChain的BM25Retriever允许你调整多个重要参数:
retriever = BM25Retriever.from_documents(
documents,
k=5, # 返回的文档数量
preprocess_func=None, # 自定义预处理函数
params={
"k1": 1.5, # 控制词频饱和度的参数
"b": 0.75, # 控制文档长度归一化的参数
}
)
LangChain允许将BM25与其他检索器组合使用,创建更强大的混合检索系统:
from langchain.retrievers import EnsembleRetriever
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import FAISS
# 创建向量存储检索器
embeddings = OpenAIEmbeddings()
vector_store = FAISS.from_documents(documents, embeddings)
vector_retriever = vector_store.as_retriever(search_kwargs={"k": 3})
# 创建BM25检索器
bm25_retriever = BM25Retriever.from_documents(documents, k=3)
# 组合两种检索器
ensemble_retriever = EnsembleRetriever(
retrievers=[bm25_retriever, vector_retriever],
weights=[0.5, 0.5]
)
优点:
缺点:
LangChain中的BM25检索器特别适合以下场景:
BM25在LangChain中既可以作为独立检索器使用,也可以作为更复杂RAG系统的组件,为开发者提供了灵活且高效的文本检索能力。