C/C++教程

混合搜索:用LanceDB实现语义和关键词结合的搜索技术(应用于实际项目)

本文主要是介绍混合搜索:用LanceDB实现语义和关键词结合的搜索技术(应用于实际项目),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

大型语言模型(LLMs)检索增强生成(RAG)领域 占主导地位,高效的可扩展搜索机制是关键。虽然向量搜索已经变得流行,特别是在语义搜索 中,但在应用于大规模实际场景时,这些方法仍面临挑战。

这篇文章深入探讨了混合搜索,一种结合关键字搜索和向量搜索的搜索方法,利用LanceDB作为核心数据库,以提供精准且符合用户期望的搜索体验。

什么是混合搜索?

混合搜索技术结合了基于关键词的传统搜索与先进的技术,包括自然语言处理(NLP)语义搜索机器学习,提供更准确和相关的结果。为何要局限于一种方法,而不能利用多种方法的长处呢?通过结合这些技术,混合搜索技术可以理解查询的上下文和含义,超越简单的关键词匹配,提供符合用户意图的信息。

这对实际应用有什么影响?在工作中,企业搜索引擎使用混合搜索技术,可以让员工快速在庞大的知识库中找到特定信息。电子商务平台也受益于混合搜索,即使顾客不确定商品的确切名称,也能帮助他们找到合适的产品。传统的网络搜索引擎也在采用这种方法,提高他们提供给用户的搜索结果的准确性和相关性。

混合搜索功能是怎么工作的?

混合搜索通过结合传统的基于关键词的搜索(使用稀疏向量)和现代的基于密集向量的语义搜索来运行,从而提供更加细腻且准确的检索体验。那么它是如何做到这一点的呢?让我们来拆解一下。

图片来源:混合搜索是如何工作的?

基于关键词的搜索(稀疏向量技术)
  • 在传统的搜索引擎中,基于关键词的搜索利用稀疏向量,每个维度对应一个独特词汇,这些词汇来自庞大的词汇表。这种方法通过如词频-逆文档频率(TF-IDF)和倒排索引这类技术,能够高效匹配查询关键词与文档。它在提供快速精准的术语匹配方面表现出色,但在相关文档未包含确切关键词时可能效果不佳。
语义搜索技术(密集向量表示)
  • 语义搜索则利用高级技术生成密集向量,如词嵌入(例如Word2vec、GloVe)或上下文嵌入(例如BERT、GPT)。这些密集向量捕捉了单词和短语的语义含义及上下文,使搜索系统能够理解并匹配查询背后的潜在意图,即使查询中没有使用确切的关键词,搜索系统也能理解用户的真实意图。
将稀疏向量和稠密向量结合起来
  • 在混合搜索系统中,会同时生成并存储稀疏和密集向量到各自的索引中。当提交查询时,系统会处理查询以生成这两种类型的向量,从而可以在两个索引中执行搜索。首先从稀疏(关键字匹配)和密集(语义匹配)索引中挑选候选文档。
检索和排名
  • 下一步是对检索到的文档进行重新排序,结合稀疏向量和稠密向量的相关性得分。机器学习模型通常通过考虑查询的上下文、用户行为和文档的整体相关性等因素来微调排序过程,确保最相关的文档出现在最前面。
比较关键字搜索、语义搜索和混合搜索
  • 每种搜索方法——关键词搜索法、语义搜索法和混合搜索法——都有其独特的优势和应用场景。关键词搜索法速度快,适用于精确匹配;而语义搜索法在理解和解释上下文及含义方面更为出色。因此,混合搜索法通过结合这两种方法的优势,提高了准确性和相关度,适用于企业搜索、数字图书馆和电子商务等场景。

在现代应用中,最终混合搜索通常是最佳选择,因为它能够利用关键词和语义搜索的各自优点,为用户提供最相关和最精确的结果。

为什么选择混合搜索?

  • 增强的相关性和精确度:结合了关键词搜索的精确匹配和语义搜索的上下文理解,检索出既准确又语义相关的结果。
  • 更好的查询处理:能够处理简单关键词查询和复杂自然语言查询,提升准确性和用户体验。
  • 全面的结果:确保不会遗漏任何相关文档,涵盖精确关键词匹配和语义相关的内容。
  • 适应性:动态调整关键词匹配和语义相关性的权重,利用机器学习模型不断优化。
  • 优化的性能:通过关键词搜索过滤结果并使用语义搜索进行微调,平衡计算负载,实现可扩展性。
  • 应用的多功能性:适用于企业搜索、电子商务、数字图书馆等多种场景,满足各种复杂查询需求,提升用户满意度。
混合搜索示例(示例包括但不限于...)

现在我们已经讨论了为什么要考虑使用混合搜索,现在我们来看看在不同平台上的混合搜索实例。每个平台都有其独特的特性和能力,来提高搜索的准确性和相关性。

Couchbase
  • Couchbase 是一个 NoSQL 云数据库平台,团队可以将强大的搜索功能集成到应用程序中。它涵盖向量、全文、地理位置、范围和谓词搜索技术,所有这些都在单一的 SQL 查询和索引中完成——提供简单性和更低延迟。更多详情请参阅此处 here。
Elasticsearch(一个开源的分布式搜索引擎)
  • Elasticsearch 是一个功能强大的开源搜索引擎,支持基于关键词和语义的搜索。它与多种插件和工具(如 Kibana 的可视化和机器学习功能)集成,以提高搜索的相关性。您可以在这篇 博客文章 中了解更多关于 Elasticsearch 的混合搜索能力。
Algolia(一个搜索引擎技术公司)
  • Algolia 是一个搜索即服务 (SaaS) 平台,提供实时搜索和发现功能,结合关键词搜索。它结合了基于关键词的搜索和诸如拼写纠错、同义词扩展和个性化搜索等功能,这些都是语义搜索的方面。更多关于 Algolia 的 AI 搜索功能的信息,请参阅此处 here。
Amazon Kendra

亚马逊 Kendra 是一款全文搜索服务,帮助您轻松查找和访问存储在不同来源中的信息。

  • Amazon Kendra 是一个由机器学习驱动的智能搜索引擎。它拥有自然语言理解功能,结合关键词搜索和语义搜索,提供更相关的结果体验。您可以在这里了解更多关于 Amazon Kendra 的信息。
实施

您的混合搜索应用程序的项目结构: 为了搭建您的混合搜索应用程序,您可以参考以下布局:

    HybridSearch/  
    │  
    ├── data/  
    │   └── BEIR/ (请将您的数据集放在这里)  
    │  
    ├── db/  
    │   └── (LanceDB数据库文件)  
    │  
    ├── scripts/  
    │   ├── setup.py (配置环境)  
    │   ├── load_data.py (加载并预处理数据集)  
    │   ├── hybrid_search.py (实现混合搜索功能)  
    │   └── rerankers.py (自定义重排序器和过滤器脚本)  
    │  
    └── README.md (项目概览和说明)

设置 LanceDB 环境: 要开始实现混合搜索,您需要设置您的环境。LanceDB 是一个很好的工具,它提供了开箱即用的全文搜索功能(使用 Tantivy)和重新排序能力,非常适合用于这种场景。以下是开始的方法:
这里是如何开始的步骤:

    import os  
    import lancedb  
    from lancedb.embeddings import get_registry  
    from datasets import load_dataset  

    os.environ["OPENAI_API_KEY"] = "sk-......."  # 请填入你的 OpenAI API 密钥  
    embeddings = get_registry().get("openai").create()

创建一个用于加载BEIR数据的LanceDB表: 下一步是创建一个LanceDB表并加载BEIR数据集。此示例展示了如何创建一个包含额外的元数据的表,以便进行更灵活且更“混合型”的搜索。

    queries = load_dataset("BeIR/scidocs", "queries")["queries"].to_pandas()  
    full_docs = load_dataset('BeIR/scidocs', 'corpus')["corpus"].to_pandas().dropna(subset="text")  

    docs = full_docs.head(64)  
    docs["num_words"] = docs["text"].apply(lambda x: len(x.split()))  # 计算文本长度  
    class Documents(LanceModel):  
        vector: Vector(embeddings.ndims()) = embeddings.VectorField()  
        text: str = embeddings.SourceField()  
        title: str  
        num_words: int  
    data = docs.apply(lambda row: {"title": row["title"], "text": row["text"], "num_words": row["num_words"]}, axis=1).values.tolist()  
    db = lancedb.connect("./db")  
    table = db.create_table("documents", schema=Documents)  
    table.add(data)  # 自动导入并向量化文档  
    table.create_fts_index("text")  # 创建全文索引

混合搜索的实践:融合与重排序: 现在你已经设置好表格了,你可以通过应用融合或重排序技术来进行混合搜索。

from lancedb.rerankers import LinearCombinationReranker  

reranker = LinearCombinationReranker(weight=0.3)  
results = table.search("Confuse the AI with random terms", query_type="hybrid").rerank(reranker=reranker).limit(5).to_pandas()

该代码使用混合查询类型搜索表并重新排序结果,以获取与混淆AI的随机术语最相关的前五个条目。

自定义搜索:过滤器和自定义重排器: 您可以通过应用过滤器和创建自定义重排器来进一步定制混合型搜索。

    from typing import List, Union  
    import pandas as pd  
    import pyarrow as pa  

    class 修改线性重排序器(线性组合重排序器):  
        def __init__(self, 过滤器: Union[str, List[str]], **kwargs):  
            super().__init__(**kwargs)  
            过滤器 = 过滤器 if isinstance(过滤器, list) else [过滤器]  
            self.过滤器 = 过滤器  

        def 混合重排序(self, query: str, vector_results: pa.Table, fts_results: pa.Table) -> pa.Table:  
            合并结果 = super().rerank_hybrid(query, vector_results, fts_results)  
            df = 合并结果.to_pandas()  
            for 过滤器 in self.过滤器:  
                df = df.query("(not text.str.contains(@过滤器)) & (num_words > 150)")  
            return pa.Table.from_pandas(df)  

    modified_reranker = 修改线性重排序器(过滤器=["dual-band"])  
    table.search("用随机术语混淆AI", query_type="hybrid").rerank(reranker=modified_reranker).limit(5).to_pandas()

这段代码将实现一个自定义的过滤条件,其中只有单词数量超过150的结果会被保留。您还可以通过继承内置的Reranked类并添加一些自定义逻辑来自定义合并机制。

结论部分

混合搜索 使用 LanceDB 提供了一种平衡的搜索方法,结合了基于关键词方法的精准度和语义搜索的情境感知能力。这种双重方法使它成为现代大规模应用的理想选择,特别是在这些应用中,相关性和精准度至关重要。结构化的实现提供了一个可扩展且适应性强的解决方案,非常适合各种搜索驱动的应用。

学习愉快!

这篇关于混合搜索:用LanceDB实现语义和关键词结合的搜索技术(应用于实际项目)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!