当前位置: 首页 > news >正文

AI代码开发宝库系列:FAISS向量数据库

FAISS向量数据库从入门到精通:让你的文本检索快如闪电!

大家好,我是你们的AI技术博主!今天我们来聊聊一个能让文本检索速度飞起来的神器——FAISS!如果你还在为海量文档检索慢而烦恼,那这篇文章绝对能让你眼前一亮!

基于FAISS构建法律文档向量数据库https://blog.csdn.net/chenchihwen/article/details/149835193?spm=1001.2101.3001.10796

什么是FAISS?为什么你需要它?

FAISS是Facebook AI团队开源的一个超高效的向量搜索引擎,专门用于快速相似性搜索和聚类密集向量。简单来说,它能帮你解决这样一个问题:

当你有成千上万个文档,用户问一个问题时,如何在毫秒级时间内找出最相关的几个文档?

传统关键词搜索已经不够用了!我们需要的是语义级别的理解,而这就需要用到Embedding技术和向量数据库。

核心概念:从文本到向量

想象一下,任何一段文本都可以变成一个多维空间中的点(向量),语义相近的文本在这个空间中距离很近,语义不同的文本距离较远。这就是Embedding的魅力!

# 示例:将文本转换为向量
completion = client.embeddings.create(model="text-embedding-v4",input="迪士尼乐园的门票一经售出,原则上不予退换",dimensions=1024,  # 1024维向量encoding_format="float"
)
vector = completion.data[0].embedding  # 这就是一个1024维的向量!

FAISS实战:三步搞定向量检索

废话不多说,直接上代码!让你3分钟掌握FAISS的核心用法:

第一步:准备数据和向量

import numpy as np
import faiss
​
# 准备你的文档数据
documents = [{"id": "doc1","text": "迪士尼乐园的门票一经售出,原则上不予退换。","metadata": {"category": "退票政策"}},{"id": "doc2","text": "购买“奇妙年卡”的用户,可以享受一年内多次入园的特权。","metadata": {"category": "会员权益"}}
]
​
# 为每个文档生成向量(这里简化处理)
vectors_list = []  # 存储向量
metadata_store = []  # 存储元数据
vector_ids = []  # 存储ID
​
for i, doc in enumerate(documents):# 实际应用中这里调用API生成向量vector = get_embedding(doc["text"])  # 假设这个函数能生成向量vectors_list.append(vector)metadata_store.append(doc)vector_ids.append(i)

第二步:构建FAISS索引

# 转换为NumPy数组
vectors_np = np.array(vectors_list).astype('float32')
vector_ids_np = np.array(vector_ids)
​
# 创建FAISS索引(关键步骤!)
dimension = 1024  # 向量维度
index_flat_l2 = faiss.IndexFlatL2(dimension)  # L2距离索引
index = faiss.IndexIDMap(index_flat_l2)  # 映射自定义ID
​
# 添加向量到索引中
index.add_with_ids(vectors_np, vector_ids_np)
print(f"FAISS索引创建成功,共包含 {index.ntotal} 个向量。")

第三步:执行相似性搜索

# 用户查询
query_text = "我想了解一下迪士尼门票的退款流程"
​
# 为查询生成向量
query_vector = np.array([get_embedding(query_text)]).astype('float32')
​
# 在FAISS中搜索最相似的3个向量
k = 3
distances, retrieved_ids = index.search(query_vector, k)
​
# 展示结果
for i in range(k):doc_id = retrieved_ids[0][i]if doc_id != -1:  # 检查是否找到匹配项retrieved_doc = metadata_store[doc_id]print(f"排名 {i+1} (距离: {distances[0][i]:.4f})")print(f"内容: {retrieved_doc['text']}")

实际应用:ChatPDF文档问答系统

来看一个更实际的例子——基于PDF文档的智能问答系统:

from PyPDF2 import PdfReader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import FAISS
​
# 1. 读取PDF文件
pdf_reader = PdfReader('your_document.pdf')
text = ""
for page in pdf_reader.pages:text += page.extract_text()
​
# 2. 分割文本(因为向量模型通常有长度限制)
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000,chunk_overlap=200
)
chunks = text_splitter.split_text(text)
​
# 3. 创建向量数据库
embeddings = OpenAIEmbeddings()
knowledgeBase = FAISS.from_texts(chunks, embeddings)
​
# 4. 查询相似内容
query = "文档中关于退款的规定是什么?"
docs = knowledgeBase.similarity_search(query)
​
# 5. 结合大语言模型生成答案
# (这部分涉及LLM调用,此处省略详细代码)

实际应用:ChatPDF文档问答系统

来看一个更实际的例子——基于PDF文档的智能问答系统:

from PyPDF2 import PdfReader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import FAISS
from typing import List, Tupledef extract_text_with_page_numbers(pdf) -> Tuple[str, List[int]]:"""从PDF中提取文本并记录每行文本对应的页码参数:pdf: PDF文件对象返回:text: 提取的文本内容page_numbers: 每行文本对应的页码列表"""text = ""page_numbers = []for page_number, page in enumerate(pdf.pages, start=1):extracted_text = page.extract_text()if extracted_text:text += extracted_text# 记录每个文本块对应的页码page_numbers.extend([page_number] * len(extracted_text.split("\n")))else:print(f"警告: 第 {page_number} 页未找到文本内容。")return text, page_numbersdef process_text_with_splitter(text: str, page_numbers: List[int]) -> FAISS:"""处理文本并创建向量存储参数:text: 提取的文本内容page_numbers: 每行文本对应的页码列表返回:knowledgeBase: 基于FAISS的向量存储对象"""# 创建文本分割器,用于将长文本分割成小块text_splitter = RecursiveCharacterTextSplitter(separators=["\n\n", "\n", ".", " ", ""],chunk_size=1000,      # 每个文本块最大1000个字符chunk_overlap=200,    # 文本块之间重叠200个字符length_function=len,)# 分割文本chunks = text_splitter.split_text(text)print(f"文本被分割成 {len(chunks)} 个块。")# 创建嵌入模型embeddings = OpenAIEmbeddings()# 从文本块创建知识库knowledgeBase = FAISS.from_texts(chunks, embeddings)print("已从文本块创建知识库。")# 存储每个文本块对应的页码信息(重要:用于结果溯源)knowledgeBase.page_info = {chunk: page_numbers[i] for i, chunk in enumerate(chunks)}return knowledgeBase# 读取PDF文件
pdf_reader = PdfReader('./浦发上海浦东发展银行西安分行个金客户经理考核办法.pdf')
# 提取文本和页码信息
text, page_numbers = extract_text_with_page_numbers(pdf_reader)
print(f"提取的文本长度: {len(text)} 个字符。")# 处理文本并创建知识库
knowledgeBase = process_text_with_splitter(text, page_numbers)# 设置查询问题
query = "客户经理每年评聘申报时间是怎样的?"
if query:# 执行相似度搜索,找到与查询相关的文档docs = knowledgeBase.similarity_search(query)# 显示查询结果及来源页码print("查询结果:")unique_pages = set()for i, doc in enumerate(docs):print(f"\n--- 结果 {i+1} ---")print(f"内容: {doc.page_content}")# 显示来源页码source_page = knowledgeBase.page_info.get(doc.page_content.strip(), "未知")if source_page not in unique_pages:unique_pages.add(source_page)print(f"来源页码: {source_page}")

性能对比:快得惊人!

让我给你看看FAISS到底有多快:

  • 传统数据库全文检索:秒级响应

  • FAISS向量检索:毫秒级响应

  • 处理百万级向量:依然保持毫秒级响应

这性能提升,简直是从马车升级到了火箭!

实战技巧和注意事项

1. 向量维度选择

# 不同模型有不同的维度
dimensions = 1024  # text-embedding-v4
dimensions = 1536  # OpenAI ada-002
dimensions = 768   # BERT-base

2. 索引类型选择

# 精确搜索(适合小数据集)
index = faiss.IndexFlatL2(dimension)
​
# 近似搜索(适合大数据集,更快但稍有精度损失)
index = faiss.IndexIVFFlat(quantizer, dimension, nlist)

3. 元数据管理

# 向量和元数据的对应关系是关键
metadata_store = []  # 用列表索引与向量ID对应
# 或者用字典存储
metadata_dict = {doc_id: doc_metadata}

应用场景大盘点

  1. 智能客服系统:快速匹配用户问题与知识库中的答案

  2. 文档问答系统:像ChatPDF一样实现PDF智能问答

  3. 推荐系统:根据用户兴趣向量推荐相关内容

  4. 代码搜索:在代码库中快速找到相关函数或模块

  5. 法律咨询:快速检索相关法条(正如CSDN博客中提到的法律文档案例)

总结

FAISS真的是一个改变游戏规则的工具!它让原本复杂的向量检索变得简单高效。掌握了FAISS,你就拥有了构建各种AI应用的利器!

记住这几个关键点:

  • 文本 → 向量 → FAISS索引 → 快速检索

  • 向量维度要匹配你的Embedding模型

  • 元数据管理是连接向量和原始信息的桥梁

  • 根据数据规模选择合适的索引类型

赶紧动手试试吧!相信我,一旦你体验过FAISS的速度,就再也回不去了!

如果你觉得这篇文章对你有帮助,别忘了点赞收藏关注哦!后续还会带来更多AI实战干货,让我们一起在AI的世界里乘风破浪!

http://www.dtcms.com/a/523501.html

相关文章:

  • 前端埋点学习
  • Spring AI与DeepSeek实战:打造企业级知识库+系统API调用
  • 秦皇岛市建设局网站关于装配式专家做运动特卖的网站
  • j2ee 建设简单网站设计婚纱网站
  • C++类和对象(中):const 成员函数与取地址运算符重载
  • 数据结构 散列表—— 冲突解决方法
  • 箭头函数和普通函数有什么区别
  • Spring Boot 缓存知识体系大纲
  • 破局政务数字化核心难题:金仓数据库以国产化方案引领电子证照系统升级之路
  • XML:从基础到 Schema 约束的全方位解析
  • 技术引领场景革新|合合信息PRCV论坛聚焦多模态文本智能前沿实践
  • 海南网站建设网络货运平台有哪些
  • 系统架构设计师备考第53天——业务逻辑层设计
  • 科技创新与数字化制造转型在“十五五”规划中的意义
  • 网站开发最新技术wordpress4.7.4密码
  • HarmonyOS方舟编译器与运行时优化
  • HarmonyOS AI能力集成与端侧推理实战
  • 自己做公众号和小说网站推广济南网站建设艮安
  • 阿里云国际站GPU:阿里云GPU的应用场景有哪些?
  • 【工具】Scrcpy|安卓投屏电脑的开源工具Scrcpy的安装及看电视注意事项
  • penCV轻松入门_面向python(第七章 图像平滑处理)
  • html5移动网站开发流程各类设计型网站
  • 使用C#代码在Excel中创建数据透视表
  • 反爬克星还是效率神器?Browser-Use+cpolar重构Web自动化逻辑
  • 《KingbaseES数据库:首个多院区异构多活容灾架构,浙人医创新开新篇》
  • MySQL 的 MyISAM 与 InnoDB 存储引擎的核心区别
  • 【Qt开发】容器类控件(一)-> QGroupBox
  • 生活电器:重构家居体验的产业变革与发展探索
  • 怎么在百度建立自己的网站58同城西安网站建设
  • Modbus笔记