Langchain使用介绍之 - 基于向量存储进行检索

Text Embedding Models

  如何将一段Document转换成向量存储到向量数据库中,首先需要了解Langchain提供了哪些将文本转换成向量的model,langchian提供了很多将自然语言转换成向量的的模型,如下图所示,除了下图列举的model,更多支持的model可参考官网信息。

   这里将以Langchain提供的SentenceTransformerEmbeddings和OpenAIEmbeddings为例子,通过实际代码来看看如何把一段自然语言转换成向量。SentenceTransformers 嵌入通过 HuggingFaceEmbeddings 集成进行调用,langchain还为那些更熟悉直接使用该包的用户添加了 SentenceTransformerEmbeddings 的别名,所以,本质上,SentenceTransformerEmbeddings和HuggingFaceEmbeddings是同一个内容,查看源代码也可以看到SentenceTransformerEmbeddings里面只是将HuggingFaceEmbeddings赋值给它而已,源代码如下图所示:

  所以,调用HuggingFaceEmbeddings和调用SentenceTransformerEmbeddings是一样的。下面的代码中调用HuggingFaceEmbeddings(),传入使用的model名称,这里使用的是"all-MinLM-L6-v2",通过调用embed_query(text)就能得到文本的向量数据。

import os
import openai
import numpy as np
from langchain.embeddings import HuggingFaceEmbeddings, SentenceTransformerEmbeddings
from langchain.embeddings import OpenAIEmbeddingsembeddings = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")
text = "hello"
query_result = embeddings.embed_query(text)
print(query_result)
print(type(query_result))
data = np.array(query_result)
print(data.shape)

    生成的向量信息如下图所示,结果信息是一个List,长度是384,可以看到通过一个长度是384个特征的值来表示上面的hello这个文字。

  接着,换成OPENAIEmbeddings再看看结果如何?

openaiEmbeddings = OpenAIEmbeddings(openai_api_key=os.environ.get("OPENAI_API_KEY"))
result = openaiEmbeddings.embed_query(text)
print(result)
print(type(result))
print(np.array(result).shape)

  生成的向量信息如下图所示,结果信息仍然是一个List,长度是1536,这个长度为1536个特征的值来表示上面的hello这个文字。

 Text Splitters

 当对一段很长的文档进行存储的时候,都需要对文档进行拆分,Langchain提供了多种对文本进行拆分的方式,具体如下图所示,以第一种为例子,以文档的\n为默认的分隔符,Split by tokens中的tiktoken is a fast BPE tokenizer created by OpenAI.

  为什么一定要把文档拆分成不同chunks呢?因为只有进行了合理拆分,在后续提问的时候,才能找出与问题最贴近的chunk进行回答。那如何保证拆分合理?即拆分出来的句子要保证语意尽量不丢失。这里有几个参数来控制,一个是spliter,对于txt文本类型,默认是换行符号,换行符代表了一个段落的结束,另外一个是chunk-size,在拆分的过程中会尽量保证拆分的chunk大小和设置的相近,另外,为了不丢失不同chunk间的连续性,还可以设置不同chunk间的重叠部分,即chunk_overlap.

下面这段代码就是对Document进行的拆分,模型按换行符进行拆分chunk.要实现Document的拆分,首先调用TextLoader加载文件,再调用CharacterTextSplitter进行拆分。

from langchain.text_splitter import CharacterTextSplitter
from langchain.document_loaders import TextLoader
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.chains import RetrievalQA
import numpy as np
from langchain.llms import OpenAIloader = TextLoader('basic/data/state_of_union.txt')
documents = loader.load()
text_spliter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_spliter.split_documents(documents)
print(texts)

   得到的内容如下图所示,可以看到page_content里面的内容都安装\n进行拆分。

  VectorStore

  拆分完成后,就可以调用Langchain提供的向量存储库进行存储,如下图所示,使用的是Chroma。Chroma是一种开源的向量数据库,旨在为开发人员和各种规模的组织提供构建基于大型语言模型(LLM)的应用所需的资源。 它为开发人员提供了可扩展和高效的解决方案,用于存储、搜索和提取多维向量。将拆分后的文本向量存储到vectorstore后,可以直接调用similarity_search_with_score(query=query)查询问题,通过计算向量的相似性得到问题的答案。

embeddings = OpenAIEmbeddings()
docSearch = Chroma.from_documents(texts, embeddings)
query = "what did the president say about Putin?"
result = docSearch.similarity_search_with_score(query=query)
print(len(result))
print(result[0])

   这里通过相似度得到问题的答案,结果如下图所示,默认是给4个答案,相似度越高,放得越靠前,查看result[0]的值,可以看到相似度得分才0.33分,这里用的是余弦定理计算相识度。

  在自然语言处理(NLP)和信息检索等领域,余弦相似度常常用于计算文本或向量之间的相似度。余弦相似度是一种用于衡量两个向量之间的夹角的指标,通常用于比较它们的方向和相对位置。分数与相似度之间的关系是这样的:余弦相似度范围: 余弦相似度的取值范围在-1到1之间。具体来说,余弦相似度为1表示两个向量的方向完全相同,夹角为0度,它们非常相似。余弦相似度为-1表示两个向量的方向完全相反,夹角为180度,它们非常不相似。余弦相似度为0表示两个向量之间没有明显的相似性或关系。

   RetrievalQA Chain

  除了直接调用向量存储库的方法计算相似度外,还可以调用Langchain封装的RetrievalQA chain。

qa_chain = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type="stuff", retriever=docSearch.as_retriever())
rs = qa_chain.run(query)
print(rs)

   得到的结果如下图所示,可以看到通过大模型查询问题,得到的内容准确率更高一些。

   上面的例子中使用的VectorDB是Chroma,实际Langchain支持和多种VectorDB进行集成,如下图所示,更多VectorDB可查看官网信息。

  

   另外,上面用到的RetriveQA chain中有一个字段是chain type,上面用的stuff类型,表示将所有内容组合成一个文档,除此之外,还支持

  • Map Reduce

将所有块与问题一起传递给语言模型,获取回复,使用另一个语言模型调用将所有单独的回复总结成最终答案,它可以在任意数量的文档上运行。可以并行处理单个问题,同时也需要更多的调用。它将所有文档视为独立的

  • Refine

用于循环许多文档,际上是迭代的,建立在先前文档的答案之上,非常适合前后因果信息并随时间逐步构建答案,依赖于先前调用的结果。它通常需要更长的时间,并且基本上需要与Map Reduce一样多的调用

  • Map Re-rank

对每个文档进行单个语言模型调用,要求它返回一个分数,选择最高分,这依赖于语言模型知道分数应该是什么,需要告诉它,如果它与文档相关,则应该是高分,并在那里精细调整说明,可以批量处理它们相对较快,但是更加昂贵

总结

  将一份Document或者多份document进行向量化,然后存储到vectorstoredb中,在基于存储的向量上进行提问,也就是基于Document中的上下文进行提问,总体过程分为三部分,如下图所示。

  以上就是对“基于存储的文本向量,进行问题检索”的实现过程的详细介绍。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/99253.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2023年动力电池回收行业研究报告

第一章 行业概况 1.1 定义 动力电池,通常指用于驱动电动车辆(包括电动汽车、电动自行车、电动滑板车等)的电池。这类电池需要具备高能量密度(以便在较小的空间和重量下提供更多的能量)、高功率密度(以便在…

高并发(水平扩展,垂直扩展)

高并发(水平扩展,垂直扩展) 一、什么是高并发 高并发(High Concurrency) 是互联网分布式系统架构设计中必须考虑的因素之一,它通常是指, 通过设计保证系统能够同时并行处理很多请求。 高并发相关常用的一些指标有 响…

Linux(基础IO)

Linux(基础IO) 前言C语言文件IO什么叫当前路径stdin/stdout/stderr 系统文件IOopenclosewriteread 文件描述符文件描述符的分配规则 重定向输出重定向原理追加重定向原理输入重定向原理dup2添加重定向功能到minishell 缓冲区模拟实现一个缓冲区 理解文件…

MySQL告警“Connection attributes of length 570 were truncated“

mysql的错误日志中看到如下报错"[Warning] Connection attributes of length 571 were truncated"。比如: 2023-09-01T08:37:49.87392408:00 9149015 [Warning] [MY-010288] [Server] Connection attributes of length 570 were truncated (76 bytes los…

el-table动态生成多级表头的表格(js + ts)

展示形式&#xff1a; 详细代码&#xff1a; &#xff08;js&#xff09; <template><div><el-table :data"tableData" style"width: 100%"><el-table-column label"题目信息" align"center"><el-table-…

⽹络与HTTP 笔试题精讲1

OSI七层与TCP/IP 这个就是OSI参考模型,⽽实际我们现在的互联⽹世界是就是这个理论模型的落地叫做TCP/IP协议 TCP的三次握⼿与四次挥⼿ 客户端想要发送数据给服务端,在发送实际的数据之前,需要先在两端之间建⽴连接,数据发完以后也需要将该连接关闭。建⽴连接的过程就是我们…

Java中网络的基本介绍。网络通信,网络,ip地址,域名,端口,网络通信协议,TCP/IP传输过程,网络通信协议模型,TCP协议,UDP协议

- 网络通信 概念&#xff1a;网络通信是指通过计算机网络进行信息传输的过程&#xff0c;包括数据传输、语音通话、视频会议等。在网络通信中&#xff0c;数据被分成一系列的数据包&#xff0c;并通过网络传输到目的地。在数据传输过程中&#xff0c;需要确保数据的完整性、准…

使用scp在两个linux系统之间传输文件

使用scp在两个linux系统之间传输文件 问题背景拷贝文件首先我们要从源设备&#xff08;本文中是矩池云自己的服务器&#xff09;传输文件至目标设备&#xff08;本文中是A100设备&#xff09;传输一个文件传输一个文件夹 从目标设备&#xff08;本文中是A100设备&#xff09;下…

Redis List类型命令 - Set类型命令 - SortedSet类型命令

目录 List类型 什么是双向链表呢&#xff1f; List类型的特征&#xff1a; List的常用命令 LPUSH和RPUSH的区别&#xff1a; LPOP和RPOP的区别&#xff1a; LPUSH和RPUSH的使用 LPOP和RPOP的使用 LRANGE key star end&#xff1a;返回一段距离范围内所有的元素 BLPOP…

【实践篇】Redis缓存和数据库一致性问题

Redis缓存和数据库一致性问题 文章目录 Redis缓存和数据库一致性问题0. 前言参考资料 1. 缓存和数据库的数据不一致是如何发生的&#xff1f;1. 删除数据的情况&#xff1a;2. 修改数据的情况&#xff1a; 0. 前言 确保缓存和数据库之间的数据一致性是一项挑战&#xff0c;这需…

2023年05月 C/C++(五级)真题解析#中国电子学会#全国青少年软件编程等级考试

C/C++编程(1~8级)全部真题・点这里 第1题:问题求解 给定一个正整数N,求最小的M满足比N大且M与N的二进制表示中有相同数目的1。 举个例子,假如给定N为78,二进制表示为1001110,包含4个1,那么最小的比N大的并且二进制表示中只包含4个1的数是83,其二进制是1010011,因此83…

长短期记忆网络(LSTM)

概念 三个门&#xff1a;遗忘门、输入门、输出门 候选记忆单元 记忆单元 隐状态 ot 控制是否让输出&#xff0c;是否要进行重置。 总结 代码实现 import torch from torch import nn from d2l import torch as d2lbatch_size,num_steps 32,35 train_iter,vocab d2l.load_…