## 技术背景介绍
Annoy(Approximate Nearest Neighbors Oh Yeah)是一个用于在空间中查找与给定查询点接近的点的C++库,并提供了Python绑定。它通过创建大型的只读文件数据结构,使多个进程可以共享相同的数据。虽然Annoy提供了一种高效的索引机制,支持快速近似最近邻搜索,但需要注意的是,一旦索引构建完成,就无法再添加新的嵌入。因此,如果需要动态增加新条目,可能需要考虑其他矢量数据库解决方案。
## 核心原理解析
Annoy通过使用多个树结构(随机投影树)来实现快速近似搜索。每棵树都根据空间中点的随机投影进行构建,这样可以快速地执行邻近查询。同时,它利用文件映射机制来实现进程间的数据共享。
## 代码实现演示
下面我们展示如何使用Annoy库结合langchain社区的工具来执行近似最近邻搜索。
### 安装依赖
在使用Annoy之前,需要安装相关库:
```bash
%pip install --upgrade --quiet annoy langchain-community
创建矢量存储从文本中
from langchain_community.vectorstores import Annoy
from langchain_huggingface import HuggingFaceEmbeddings
# 使用HuggingFace提供的嵌入功能
embeddings_func = HuggingFaceEmbeddings()
# 用文本数据创建矢量存储
texts = ["pizza is great", "I love salad", "my car", "a dog"]
vector_store = Annoy.from_texts(texts, embeddings_func)
# 执行相似性搜索
results = vector_store.similarity_search("food", k=3)
print(results)
创建矢量存储从文档中
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import CharacterTextSplitter
loader = TextLoader("path/to/state_of_the_union.txtn")
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)
print(docs[0].page_content[:100])
创建矢量存储通过现有嵌入
# 计算嵌入
embs = embeddings_func.embed_documents(texts)
data = list(zip(texts, embs))
vector_store_from_embeddings = Annoy.from_embeddings(data, embeddings_func)
# 执行相似性搜索
results_with_scores = vector_store_from_embeddings.similarity_search_with_score("food", k=3)
print(results_with_scores)
应用场景分析
Annoy适用于需要共享大型数据结构而又不频繁更新的场景,例如推荐系统中产品搜索,文档相似性匹配等。由于其高效的内存映射技术,可以在多进程环境下提供一致的查询性能。
实践建议
在使用Annoy时,建议在构建索引前对数据进行良好规划,并结合实际嵌入需求选择合适的参数(例如树的数量和选择的距离度量)。同时,确保在共享数据的环境中正确配置文件映射,以最大化内存使用效率。
如果遇到问题欢迎在评论区交流。
---END---