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

news2024/11/26 17:38:56

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 OpenAIEmbeddings

embeddings = 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 OpenAI

loader = 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.coloradmin.cn/o/976887.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java和js实现MD5加密

java import java.security.MessageDigest;public class Demo2 {public static void main(String[] args) {Demo2 demo2 new Demo2();String encry demo2.md5("admin");System.out.println("加密后:" encry);}/*** md5加密*/private static…

正则性能提升之-Matcher.appendReplacementappendTail使用(别再无脑用字符串替换啦)

首先是用法: appendReplacement是java中替换相应字符串的一个方法 appendReplacement(StringBuffer sb,String replacement) 将当前匹配子串替换为指定字符串,并且将替换后的子串以及其之前到上次匹配子串之后的字符串段添加到一个 StringBuffer 对象里…

oracle将一个用户的表复制到另一个用户

注:scott用户和scott用户下的源表(EMP)本身就有,无需另行创建。 GRANT SELECT ON SCOTT.emp TO BI_ODSCREATE TABLE ODS_EMP AS SELECT * FROM SCOTT.emphttp://www.bxcqd.com/news/77615.html

Java多线程基础(创建、使用,状态)——Java第九讲

前言 这一讲开始我们将进入java高级部分,包括多线程编程、数据结构、并发编程、设计模式等。本讲先介绍多线程,多线程编程是Java编程中的一个重要部分。它允许程序同时执行多个任务,这有助于提高程序的效率和性能。在Java中,可以通过实现Runnable接口或继承Thread类来创建线…

android studio安卓模拟器高德SDK定位网络连接异常

背景 使用了高德SDK创建了一个 project, 下面是运行界面: 点击 "开始定位"按钮, 结果并没有返回定位信息, 而是报错了: 根据错误提示打开这个网址: https://lbs.amap.com/api/android-location-sdk/guide/utilities/errorcode, 并且找到错误码 4 的信息, 显示的是网…

zabbix -- 新建主机

目录 一、新建主机 二、新建监控项 IP主机192.168.136.55zabbix控制端/服务端192.168.136.56zabbix被控端/客户端 一、新建主机 主机参数 名称、群组(每台主机必须属于某个主机组内)、ip、端口 创建完成,如果你的ZBX为灰色,代…

SOLIDWORKS倒角是什么?

在现代工程设计中,倒角是一项常见而重要的工艺。它不仅可以提升产品的外观美观度,还能改善产品的强度和耐用性。SOLIDWORKS作为一款广泛应用于3D建模和设计的软件,提供了强大的倒角功能,使工程师能够轻松地在设计过程中添加和编辑…

基于SSM的线上旅行信息管理系统

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用Vue技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…

Python 中下划线详解(_、_xx、xx_、__xx、__xx__)

文章目录 1 概述2 演示2.1 _:不重要的变量2.2 _xx:声明私有,仅内部调用2.3 xx_:区分关键字2.4 __xx:声明私有,仅当前类中可用2.5 __xx__:内置函数 1 概述 2 演示 2.1 _:不重要的变…

兼容性测试基本原则是什么

兼容性测试是计算机软件测试过程中的一项重要活动,旨在验证软件在不同平台、操作系统、网络环境、硬件设备或软件版本之间的正确运行和兼容性。那么,兼容性测试的基本原则是什么?下面,就来看看具体介绍吧! 兼容性测试的基本原则:…

zookeeper/HA集群配置

1.zookeep配置 1.1 安装4台虚拟机 (1)按照如下设置准备四台虚拟机,其中三台作为zookeeper,配置每台机器相应的IP,hostname,下载vim,ntpdate配置定时器定时更新时间,psmisc&#xff…

11.3.1-使用Pythton抓取股票基金数据

文章目录 1. 哪些方式获取股票数据1.1. yifinance1.2. JoinQuant聚宽1.3. tushare1.4. 自己动手,丰衣足食 2. 使用python抓取数据2.1. 查看请求报文2.2. 解析返回报文2.3. 数据存储2.4. 开始python代码编写2.4.1. 构造时间区间2.4.2. requests调用2.4.3. 数据存储 2…

让API开发更高效——Apipost

作为一款专为API开发设计的工具,Apipost凭借其强大的功能和高效的特点,正逐渐受到越来越多开发者的欢迎。本文将向您详细介绍Apipost的独特优势以及如何让您的API开发更加高效。 Apipost适用于所有与API开发相关的从业者,包括但不限于前端工…

Nor flash 页写地址与数据大小的限制

厂商提供的flash手册如下 如果页写指令的地址不是256的整数倍,并且写入的数据量超过了当前地址所在页的边界,则超过的那些数据会重新写入当前页的首地址(即256的整数倍地址),所以,在进行页写的时候&#x…

Unity Shader着色器知识

学习3D开发技术的时候无可避免的要接触到Shader,那么Shader是个什么概念呢?其实对于开发同事来说还是比较难理解的,一般来说Shader是服务于图形渲染的一类技术,开发人员可以通过其shader语言来自定义显卡渲染页面的算法&#xff0…

Django学习

1、启动项目 python manage.py runserversettings.py

微信小程序新建页面文件

1、在app.json->pages中新增页面的存放路径 list文件夹之前是直接右键加上去,后面删掉了,利用上述操作新增,只出现了两个文件。暂时还不清楚需要怎样才能正式生成4个文件

【STM32】锁存器

问题背景 在学习FSMC控制外部NOR存储器时,看到在NOR复用接口模式下,AD信号[15:0]是复用的。也就是说,若不使用锁存器:当NADV为低时,ADx(x0…15)上出现地址信号Ax,当NADV变高时,ADx上出现数据信号Dx。若使用…

基于深度学习网络的火灾检测算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ................................................................................ load F…

【广州华锐互动】智慧园区3D数据可视化系统有什么作用?

随着科技的不断发展,智慧园区3D数据可视化系统已经成为了现代园区管理的重要组成部分。它通过将大量的数据进行整合、分析和展示,为企业提供了一个直观、高效的数据管理平台,帮助企业实现精细化管理,提高运营效率,降低…