Data Conection
一些基于大型语言模型的应用经常需要用到模型数据集中没有的数据。针对这一需求,LangChain提供了一系列的工具可以让你从各种数据源中加载新的数据,转换数据,存储数据以及访问数据。
LangChain提供了以下几个工具:
- 文档加载器:从多种不同的数据源加载文档
- 文档转换器:拆分文档、丢弃冗余文档等
- 文本embedding模型:将非结构化文本转化为浮点数的列表
- 向量存储站:存储和搜索embedding数据
- 检索器:查询向量数据
数据连接流程
流程图如下:
image.png
加载器
数据加载器(文档加载器):如图所示:一个PDF实际上就是对应一个数据源,然后经过文档加载器(这里使用的是对应的PDF加载器),当你吧PDF文档放到PDF加载器之后,它就会得到一系列我们称之为documents的东西。默认情况下PDF加载器会把PDF的每一页对应到一个document。如图所示,看到一共有6个document,也就意味这原始的PDF有6页。
针对不同的数据源,LangChain会给我们提供很多不同的加载器。
image.png
结构化、非结构化数据以及URL加载器
- 结构化数据支持,比如:csv等
- 非结构化数据支持,比如:纯文本、幻灯片(PPT)、html、pdf、图片。
- URL可以理解为网址
具体可参考:
https://python.langchain.com/docs/integrations/document_loaders
案例1(CSV)
什么是CSV文件?
CSV文件是一种使用逗号作为分隔符的定界文本文件。文件的每一行是一条数据记录。每个记录由一个或多个字段组成,字段之间使用逗号分隔。
如图所示:
- 代码
# 加载CSVloader,CSV的加载器
from langchain.document_loaders.csv_loader import CSVLoader
# 指定CSV文件的路径
loader = CSVLoader(file_path='C:UserszhiwangDownloadsdata.csv')
data = loader.load()
print(data)
len(data)
data[0].page_content
如图:
文档转换器
为什么我们需要文档转换呢?因为有的时候你可能原始的document无法满足你的需求。一个最简单的例子就是:使用的时候可能希望将长文拆分为较小的块,以避免大型语言模型对于提示词文本长度的限制。
LangChain有许多内置的文档转换器,可以轻松的拆分、合并、过滤文档。
文本分割器
既然要拆分文档,就需要使用到LangChain提供的一个非常重要的工具类文本分割器,它分割的准则是会根据文本的这个语义,将其语义有关联的文本放在同一个分割段中
文本分割器工作方式
- 将文本拆分为小的、语义有意义的块(通常是句子)
- 开始将这些小块组合成较大的块,直到达到一定的体量
- 一旦达到该大小,将该块作为独立的文本片段,然后开始创建一个新文本块。为了各块之间的连贯性,一般两个文本块之间会有重叠部分。
如图所示:
文本词嵌入(Word Embedding)
image.png
- 词嵌入是词语的一种数值化表示方式,一般情况下会将一个词映射到一个高维的向量中(词向量vector)
- 例子:
image.png
- 不再考虑单词或者句子,对象变成了高维向量->数字化表达
- 接近的语义 = 接近的高维距离
- 把文本变成高维向量:嵌入模型
- openAI
- Cohere
- Hugging Face
向量存储站
向量存储站是LangChain为我们封装的一个专门用来解决需求的一个工具,它可以和不同的向量数据库进行交互,能够为问哦们非常方便的解决词向量的一个存储和查询或者说是检索的一个需求。
image.png
当有了词向量之后,我们便可以对这些词向量做语义检索。去找一下有什么相近的词语或者问题。检索完之后我们可以选择把这些词向量给扔掉,但是如果下次继续使用,还需要再次生成一遍词向量,从加载文档开始。虽然这个过程简单速度也不慢,但是实则是没有必要的,这个时候如果能将使用的词向量做一个存储等到再次使用的时候直接获取就行了。这个时候就需要一个向量存储站
的东西了。也可称之为向量数据库。实际上也就是一个数据库,但是它存储的是我们的词向量。
检索器
在LangChain中检索器指的就是一类接口 ,这个接口的作用就是根据你输入的非结构化的查询语句返回一系列的Document对象。
相比向量存储而言,检索器的定义更加宽泛。
- 向量存储可以看作是一种具备存储功能的检索器实现
- 检索器不一定需要具备存储向量的功能
image.png
代码演示
代码语言:javascript复制## 数据加载器Document Loader
PDF
# PDF加载器
%pip install pypdf
# 初始化了一个PDF加载器
from langchain.document_loaders import PyPDFLoader
loader = PyPDFLoader("a.pdf")
documents = loader.load()
documents
### 对于PDF加载器来说,一个document对应的就是PDF的一页
# PDF文件长度
len(documents)
documents[1]
## 文本分割器
通用型的文本分割器
# 文本分割器
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(
# 设置一个非常小的文字块大小
chunk_size = 100,
chunk_overlap = 20,
length_function = len,
)
pages = loader.load_and_split(text_splitter=text_splitter)
len(pages)
pages[94]
## 文本的词嵌入 Word Embedding
# 首先先加载环境变量
%load_ext dotenv
%dotenv
# 初始化LangChain为我们封装好的 embedding
from langchain.embeddings import OpenAIEmbeddings
embedding_model = OpenAIEmbeddings()
# 在OpenAI的模块工作的时候 它需要有一个依赖是TikTok token这样一个依赖
# 这个依赖是为了把我们的文本分片之后,才能更好的去做词嵌入
%pip install tiktoken
# 调用嵌入模型的embed document这样一个函数 我们这里选择的是第4页
# 第4个document里面的内容 把它放到一个列表里面
embeddings = embedding_model.embed_documents([pages[4].page_content])
# len(embeddings[0]) 维度
len(embeddings), len(embeddings[0])
embeddings[0]
## 向量存储
Chromadb是一个本地的向量存储解决方案
%pip install chromadb
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
# 这个db对象就是我们直接操作的数据库本身
db = Chroma.from_documents(pages, OpenAIEmbeddings())
## 相似度检索
query = "霍金"
docs = db.similarity_search(query)
len(docs)
docs[0]
## 检索器
我们可以看一下Chroma的源代码
文件如图所示:
image.png
image.png
image.png
image.png
源码
langchain-loader.ipynb
至此,本次入门的教程到此结束了,感谢你的阅读。希望对你的学习有所帮助