【LangChain】ベクターストレージのFAISS

LangChain 学習ドキュメント


概要

Facebook AI 類似性検索 (Faiss) は、効率的な類似性検索と高密度ベクトル クラスタリングのためのライブラリです。これには、RAM に収まらない可能性のあるベクトル セットも含め、あらゆるサイズのベクトル セットを検索できるアルゴリズムが含まれています。評価とパラメータ調整のためのサポート コードも含まれています。

FAISS の詳細ドキュメント

この記事では、FAISS ベクトルデータベースに関する機能の使用方法を説明します。

前提条件

pip install faiss-gpu # For CUDA 7.5+ Supported GPU's.
# OR
pip install faiss-cpu # For CPU Installation

コンテンツ

それを使用したいので、キーをOpenAIEmbeddings取得する必要があります。OpenAI API

import os
import getpass

os.environ["OPENAI_API_KEY"] = getpass.getpass("OpenAI API Key:")

# Uncomment the following line if you need to initialize FAISS with no AVX2 optimization
# 如果您需要在没有 AVX2 优化的情况下初始化 FAISS,请取消以下注释
# os.environ['FAISS_NO_AVX2'] = '1'
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import FAISS
from langchain.document_loaders import TextLoader

関連する API リンク:

OpenAIEmbeddingsからlangchain.embeddings.openai

CharacterTextSplitterからlangchain.text_splitter

FAISSからlangchain.vectorstores

からのテキストローダーlangchain.document_loaders

from langchain.document_loaders import TextLoader

loader = TextLoader("../../../state_of_the_union.txt")
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
docs = text_splitter.split_documents(documents)

embeddings = OpenAIEmbeddings()

参考API:
TextLoader from langchain.document_loaders

db = FAISS.from_documents(docs, embeddings)

query = "What did the president say about Ketanji Brown Jackson"
docs = db.similarity_search(query)
print(docs[0].page_content)

結果:

今晚。我呼吁参议院: 通过《投票自由法案》。通过约翰·刘易斯投票权法案。当你这样做的时候,通过《披露法案》,这样美国人就可以知道谁在资助我们的选举。
今晚,我要向一位毕生为这个国家服务的人表示敬意:斯蒂芬·布雷耶法官——退伍军人、宪法学者、即将退休的美国最高法院法官。布雷耶法官,感谢您的服务。
总统最重要的宪法责任之一是提名某人在美国最高法院任职。
四天前,当我提名巡回上诉法院法官科坦吉·布朗·杰克逊时,我就这样做了。我们国家最顶尖的法律头脑之一,他将继承布雷耶大法官的卓越遗产。

スコア付き類似検索

具体的な方法はいくつかありますFAISSその 1 つは、similarity_search_with_scoreドキュメントだけでなく、ドキュメントまでのクエリの距離スコアも返すことができることです。返される距離スコアはL2距離です。したがって、スコアが低いほど良いことになります。

docs_and_scores = db.similarity_search_with_score(query)
docs_and_scores[0]

結果:

    (Document(page_content='Tonight. I call on the Senate to: Pass the Freedom to Vote Act. Pass the John Lewis Voting Rights Act. And while you’re at it, pass the Disclose Act so Americans can know who is funding our elections. \n\nTonight, I’d like to honor someone who has dedicated his life to serve this country: Justice Stephen Breyer—an Army veteran, Constitutional scholar, and retiring Justice of the United States Supreme Court. Justice Breyer, thank you for your service. \n\nOne of the most serious constitutional responsibilities a President has is nominating someone to serve on the United States Supreme Court. \n\nAnd I did that 4 days ago, when I nominated Circuit Court of Appeals Judge Ketanji Brown Jackson. One of our nation’s top legal minds, who will continue Justice Breyer’s legacy of excellence.', metadata={
    
    'source': '../../../state_of_the_union.txt'}),
     0.36913747)

similarity_search_by_vector 文字列の代わりにパラメータとして埋め込みベクトルを受け入れる、特定の埋め込みベクトルに類似したドキュメントを検索することもできます。

# embed 向量
embedding_vector = embeddings.embed_query(query)
# embed 向量作为入参:embedding_vector
docs_and_scores = db.similarity_search_by_vector(embedding_vector)

保存とロード

FAISS インデックスを保存およびロードすることもできます。これは便利なので、使用するたびに再作成する必要はありません。

db.save_local("faiss_index")
new_db = FAISS.load_local("faiss_index", embeddings)
docs = new_db.similarity_search(query)
docs[0]

結果:

    Document(page_content='Tonight. I call on the Senate to: Pass the Freedom to Vote Act. Pass the John Lewis Voting Rights Act. And while you’re at it, pass the Disclose Act so Americans can know who is funding our elections. \n\nTonight, I’d like to honor someone who has dedicated his life to serve this country: Justice Stephen Breyer—an Army veteran, Constitutional scholar, and retiring Justice of the United States Supreme Court. Justice Breyer, thank you for your service. \n\nOne of the most serious constitutional responsibilities a President has is nominating someone to serve on the United States Supreme Court. \n\nAnd I did that 4 days ago, when I nominated Circuit Court of Appeals Judge Ketanji Brown Jackson. One of our nation’s top legal minds, who will continue Justice Breyer’s legacy of excellence.', metadata={
    
    'source': '../../../state_of_the_union.txt'})

結合

FAISS2 つのベクター ストアをマージすることもできます

db1 = FAISS.from_texts(["foo"], embeddings)
db2 = FAISS.from_texts(["bar"], embeddings)
# 打印第一个FAISS
db1.docstore._dict

結果:

    {
    
    '068c473b-d420-487a-806b-fb0ccea7f711': Document(page_content='foo', metadata={
    
    })}
# 打印第二个FAISS
db2.docstore._dict

結果:

    {
    
    '807e0c63-13f6-4070-9774-5c6f0fbb9866': Document(page_content='bar', metadata={
    
    })}
# 合并
db1.merge_from(db2)
# 打印
db1.docstore._dict

結果:

    {
    
    '068c473b-d420-487a-806b-fb0ccea7f711': Document(page_content='foo', metadata={
    
    }),
     '807e0c63-13f6-4070-9774-5c6f0fbb9866': Document(page_content='bar', metadata={
    
    })}

フィルタリングによる類似検索

FAISS vectorstoreFAISS 自体はフィルタリングをサポートしておらず、手動で行う必要があるため、フィルタリングもサポートできます。

これは、まず複数の結果を取得してからそれらをフィルタリングすることによってk行われます。メタデータに基づいてドキュメントをフィルタリングできます。

また、検索メソッドを呼び出すときにパラメータを設定して、fetch_kフィルタリングする前にフェッチするドキュメントの数を設定することもできます。以下に小さな例を示します。

from langchain.schema import Document
# 先构造文档数据,方便后面的测试
list_of_documents = [
    Document(page_content="foo", metadata=dict(page=1)),
    Document(page_content="bar", metadata=dict(page=1)),
    Document(page_content="foo", metadata=dict(page=2)),
    Document(page_content="barbar", metadata=dict(page=2)),
    Document(page_content="foo", metadata=dict(page=3)),
    Document(page_content="bar burr", metadata=dict(page=3)),
    Document(page_content="foo", metadata=dict(page=4)),
    Document(page_content="bar bruh", metadata=dict(page=4)),
]
# 构建向量存储
db = FAISS.from_documents(list_of_documents, embeddings)
# 简单搜索下,方便后面的对比
results_with_scores = db.similarity_search_with_score("foo")
# 打印
for doc, score in results_with_scores:
    print(f"Content: {
      
      doc.page_content}, Metadata: {
      
      doc.metadata}, Score: {
      
      score}")

関連 API: langchain.schema のドキュメント

    Content: foo, Metadata: {
    
    'page': 1}, Score: 5.159960813797904e-15
    Content: foo, Metadata: {
    
    'page': 2}, Score: 5.159960813797904e-15
    Content: foo, Metadata: {
    
    'page': 3}, Score: 5.159960813797904e-15
    Content: foo, Metadata: {
    
    'page': 4}, Score: 5.159960813797904e-15

ここで同じクエリ呼び出しを行いますが、フィルタリングのみを行いますpage = 1

# 开始使用过滤:filter指定过滤元数据page:1的数据
results_with_scores = db.similarity_search_with_score("foo", filter=dict(page=1))
for doc, score in results_with_scores:
    print(f"Content: {
      
      doc.page_content}, Metadata: {
      
      doc.metadata}, Score: {
      
      score}")

結果:

    Content: foo, Metadata: {
    
    'page': 1}, Score: 5.159960813797904e-15
    Content: bar, Metadata: {
    
    'page': 1}, Score: 0.3131446838378906

と同じことができますmax_marginal_relevance_search

# max_marginal_relevance_search
results = db.max_marginal_relevance_search("foo", filter=dict(page=1))
for doc in results:
    print(f"Content: {
      
      doc.page_content}, Metadata: {
      
      doc.metadata}")

結果:

# 相比上面,少了Score
    Content: foo, Metadata: {
    
    'page': 1}
    Content: bar, Metadata: {
    
    'page': 1}

呼び出し時のパラメータのsimilarity_search設定例を以下に示します。通常は>> が必要ですfetch_k
fetch_k参数k 参数

これは、fetch_k 参数フィルタリング前にフェッチされるドキュメントの数であるためです。fetch_k小さい数値に設定すると、フィルタリングするのに十分なドキュメントが得られない可能性があります。

# k设置过滤后得到的文档数、fetch_k设置过滤前的文档数
results = db.similarity_search("foo", filter=dict(page=1), k=1, fetch_k=4)
for doc in results:
    print(f"Content: {
      
      doc.page_content}, Metadata: {
      
      doc.metadata}")

結果:

    Content: foo, Metadata: {
    
    'page': 1}

要約する

この記事では主にFAISSの使い方について説明します。
基本的な考え方:

  1. 文書の読み込み、分割
  2. embed を使用してベクトル ストレージを構築します。db = FAISS.from_documents(docs, embeddings)
  3. これに基づいて、相关性搜索など搜索过滤が可能になります。

参照アドレス:

https://python.langchain.com/docs/integrations/vectorstores/faiss

おすすめ

転載: blog.csdn.net/u013066244/article/details/132014791