paint-brush
矢量数据库 - Python 中矢量搜索和 Langchain 包的基础知识经过@shyamganesh
18,207 讀數
18,207 讀數

矢量数据库 - Python 中矢量搜索和 Langchain 包的基础知识

经过 Shyam Ganesh S7m2023/09/30
Read on Terminal Reader

太長; 讀書

在本文中,我将带您了解向量数据库、向量搜索和 Python 中用于存储和查询相似向量的 Langchain 包的基础知识。为了开始我们的学习之旅,我们将从一个名为“嵌入”的关键概念开始。嵌入是一种以机器可理解的格式向机器表示数据的方法。
featured image - 矢量数据库 - Python 中矢量搜索和 Langchain 包的基础知识
Shyam Ganesh S HackerNoon profile picture

在这篇博文中,我将指导您了解向量数据库、向量搜索和 Python 中的 Langchain 包的基础知识,该包有助于存储和检索可比向量。


为了开始我们的旅程,我们将从一个称为“嵌入”的关键概念开始。

什么是嵌入?

在本文中,我们将探讨嵌入的概念——机器学习的一个基本方面,它使我们能够以机器可以轻松理解的格式表示文本数据。


本质上,嵌入充当文本的向量表示,将复杂的单词、句子和段落网络转换为机器可以处理的数字格式。


一个紧迫的问题出现了:人类能否破译这些嵌入?答案是不。嵌入本质上是封装文本信息的数字序列。


因此,理解和使用嵌入向量对于人类来说可能是一项艰巨的任务,而机器可以轻松处理它。


存在多种从文本生成嵌入的技术。著名的方法包括 TF-IDF、Word2Vec、Glove 和 BERT 等。在当代机器学习领域,句子嵌入比词嵌入更受欢迎。


这些代表文本本质的句子嵌入可以从预先训练的句子转换器模型(如“all-MiniLM-L6-V2”和“all-mpnet-base-v2”)中获得。


这些模型为给定文本生成固定尺寸的嵌入,通常为 384 或 768 尺寸。


现在我们已经探索了嵌入的基础知识及其生成的各种技术,让我们将注意力转移到将这些高维嵌入向量存储在向量存储中的挑战上。

矢量商店

矢量数据存储是一种专门的数据库,旨在存储不同数据类型的高维嵌入表示,包括音频、视频、图像、文本等。


其核心功能之一是能够在商店内有效搜索与给定查询向量非常相似的向量。



向量存储简化了存储嵌入和在这些向量之间进行相似性搜索的过程,从而简化了高维数据表示的管理和检索。


在向量嵌入领域,相似性搜索涉及量化两个或多个嵌入之间的邻近性或相关性。通常,这是通过使用各种距离度量计算相似性来完成的。一些常用且广泛认可的距离度量包括欧几里德距离、曼哈顿距离和余弦距离等。这些指标帮助我们衡量向量之间的相似度或不相似度,从而促进数据中有效的相似性搜索。


例如,当确定图表上两点之间的相似性或接近度时,通常采用欧几里得距离。该距离可以使用以下公式计算:


欧氏距离 = [(x2 - x1)^2 + (y2 - y1)^2]^0.5



二维中 2 点之间的距离


这里,(x1,y1)表示图形上第一个点的坐标,(x2,y2)表示图形上第二个点的坐标。此计算的结果提供了两点之间的空间分离的度量,表明它们在图中的位置方面的相似性或不相似性。


类似地,在相似性搜索中,嵌入被描述在高维空间内,每个记录充当一个数据点。


下面的代码行演示了如何检索给定输入数据的前 5 个相似嵌入:

 distance, n = vector_store.search(input_embedding, k=5)


该代码将返回与输入数据非常相似的前 5 个嵌入的列表,使其成为推荐系统、内容检索等各种应用程序的宝贵工具。


vector_store.search() 函数输出包含前 k 个相似嵌入以及它们各自与 input_embedding 的距离。参数“k”是一个可配置值,用于确定在相似性搜索中检索的最接近嵌入的数量。您可以设置“k”来控制搜索操作返回的结果数量。


现在我们已经对向量存储有了基本的了解,让我们继续深入研究 LangChain 包和 FAISS。这些工具将进一步增强我们处理高维嵌入和执行有效相似性搜索的能力。

Python 中的 LangChain

简而言之,LangChain 是一个旨在构建利用大型语言模型(LLM)功能的应用程序的框架。更详细的信息和资源,可以参考LangChain官方文档。


python中的LangChain


相反,FAISS 代表“Facebook AI 相似性搜索”,它是一个 Python 库,它为开发人员提供了一种快速有效的搜索相似嵌入的方法,这与传统的基于哈希的方法不同。


该库由 Facebook AI 团队开发,为高维空间中的相似性搜索任务提供强大的功能。


FAISS 是一个开源库,可以托管在您自己的服务器上。


在我们对LangChain和FAISS的探索中,我们现在的目标是在LangChain框架内实现FAISS。以下是 LangChain 与 FAISS 集成的一些关键 API,我们将在本文中重点介绍这些 API:


  1. add_documents() :此函数允许我们将其他文档合并到向量存储中。


  2. add_embeddings() :它可以向向量存储添加更多嵌入。


  3. from_documents() :此 API 根据提供的文档返回 VectorStore。


  4. from_embeddings() :该函数提供从给定嵌入生成的 FAISS 索引。


  5. load_local() :使用它从磁盘加载 FAISS 索引。


  6. save_local() :它允许您将 FAISS 索引保存到磁盘。


  7. 相似度_search() :此函数检索与给定查询最相似的文档。


  8. 相似度_search_by_vector() :它检索与给定嵌入最相似的文档。


这些 API 构成了将 LangChain 的功能与 FAISS 相结合的基础,使您能够使用嵌入并在应用程序中执行高效的相似性搜索。


元过滤是一种有价值的技术,用于细化 LangChain FAISS 中的搜索查询结果。元过滤通常有两种类型:预过滤和后过滤。在我们的框架中,我们特别支持搜索查询的后过滤。


需要注意的是,搜索结果元过滤的概念是 FAISS 的 LangChain 版本中提供的功能,并且在 FAISS 的原始实现中并不存在。这种后过滤功能提高了搜索结果的精确度和相关性,为用户提供更加量身定制的结果。


了解了 LangChain FAISS API 的知识后,让我们深入了解 LangChain FAISS 的 Python 实现。此实现将使您能够在 LangChain 框架内使用嵌入、执行相似性搜索并应用后过滤技术来微调您的搜索结果。


请随意探索和利用这些功能来创建利用大型语言模型和 FAISS 高级相似性搜索功能的应用程序。

浪链FAISS Python Demo

数据集

在本教学指南中,我们选择斯坦福数据集作为基础数据集,并添加了一些列来展示 LangChain FAISS 中元过滤的工作。


我们将从安装和导入所需的包开始

!pip install langchain[all] !pip3 install Langchain[FAISS] !pip install faiss-cpu # WARNING: langchain 0.0.74 does not provide the extra 'faiss'
 from langchain import FAISS import pandas as pd import numpy as np import os import time import pickle


现在,我们将导入数据集:

 passage_data = pd.read_csv("/Users/shyam/Python_Programs/Text Similarity Codes/Standford_Edited.csv") passage_data.drop(columns=["Unnamed: 0"],axis=1, inplace=True) passage_data 

数据集概述


有了数据集,我们需要初始化一个嵌入函数以将文本数据转换为向量。我们使用“sentence-transformers/all-MiniLM-L6-V2”,它生成 384 维的嵌入,

 from langchain.embeddings import SentenceTransformerEmbeddings embedding_function = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")


我们将设置元数据信息。在元数据中,我们为每个嵌入(内容)添加了文档 ID 和文档语言,

 start=time.time() metadatas = [] for index, row in passage_data.iterrows(): doc_meta = { "id": row['Id'], "language": row['Language'] } metadatas.append(doc_meta)


就是这样......我们现在将构建我们的 FAISS 索引,

 faiss = FAISS.from_texts(passage_data['Content'].tolist(), embedding_function, metadatas) print("Time Taken --> ", time.time()-start)


现在,我们将尝试将 FAISS 索引保存到磁盘并将其加载回来:

 faiss.save_local("/Users/shyam/Python_Programs/LangChain_FAISS", "Standford") loaded_faiss = faiss.load_local("/Users/shyam/Python_Programs/LangChain_FAISS",embedding_function, "Standford")


我们已经完成了 FAISS 索引的构建、存储和加载。现在是推理时间。我们将尝试搜索一些查询并测试 FAISS 索引。


首先,我们将获得与“无神论”相关的前五个相似文档。

 start=time.time() loaded_faiss.similarity_search_with_score("What is atheism?",5) 

“无神论”的输出


嗯,结果是令人信服的。但我们仍然会探索更多……


这次,我们将尝试使用一些元过滤的不同语言查询。我们将询问俄语查询,指出过滤条件应为 {lang: 'ru_RU'}。

 #Что такое атеизм? - Russian loaded_faiss.similarity_search_with_score("Что такое атеизм?",5, {"language":"ru_RU"}, 10)


在这里,我们提到从向量存储中取出十个最相似的文档,然后应用过滤条件来获取查询的前五个文档。

过滤后查询的输出


结束本文后,我相信您已经对向量存储和向量搜索有了深入的理解。我们还提供了LangChain FAISS的演示来说明其功能。


我强烈鼓励您探索其他矢量存储,例如 ChromaDb、Qdrant、Milvus 等。


每个矢量商店都有其独特的优点和缺点,因此请根据您的用例的具体要求进行选择。


祝您有一个愉快而富有成果的学习之旅!