语义文档分割器的使用与背景
在前面文章中使用的文档分割器都是使用 特定字符 对文本进行拆分,这种拆分模式虽然考虑了文档中的上下文切断的问题,但是并没有考虑句子之间的语义相似性。如果有一篇长文本,需要将其分割成语义相关的块,以便更好地理解和处理,这个时候可以使用 LangChain 中的 语义相似性分割器 (SemanticChunker) 来实现这个任务。
语义相似性分割器目前仍处于实验性,这个类目前位于 langchain_experimental
包中(这个包中的类与方法未来极大概率会发生变更,需要谨慎使用),安装命令:
pip install -Uqq langchain_experimental
SemanticChunker
在使用上和其他的文档分割器存在一些差异,并且该类并没有继承 TextSplitter
,实例化参数含义如下:
- embeddings:文本嵌入模型,在该分类器底层使用向量的余弦相似度来识别语句之间的相似性。
- buffer_size:文本缓冲区大小,默认为
1
,即在计算相似性时,该文本会叠加前后各1
条文本,如果不够则不叠加(例如第1
条和最后1
条)。 - add_start_index:是否添加起点索引,默认为
False
。 - breakpoint_threshold_type:断点阈值类型,默认为
percentile
即百分位。 - breakpoint_threshold_amount:断点阈值金额/得分。
- number_of_chunks:分割后的文档块个数,默认为
None
。 - sentence_split_regex:句子切割正则,默认为
(?<=[.?!])\s+
,即以英文的点、问号、感叹号切割语句,不同的文档需要传递不同的切割正则表达式。
资料推荐 - 💡大模型中转API推荐
- ✨中转使用教程
- ✨模型优惠查询
例如想要将科幻短篇.txt
按照语义切割成 10 个文档,可以使用如下代码示例:
import dotenv
from langchain_community.document_loaders import UnstructuredFileLoader
from langchain_experimental.text_splitter import SemanticChunker
from langchain_openai import OpenAIEmbeddingsdotenv.load_dotenv()# 1.构建加载器和文本分割器
loader = UnstructuredFileLoader("./科幻短篇.txt")
text_splitter = SemanticChunker(embeddings=OpenAIEmbeddings(model="text-embedding-3-small"),sentence_split_regex=r"(?<=[。?!])",number_of_chunks=10,
)# 2.加载文本与分割
documents = loader.load()
chunks = text_splitter.split_documents(documents)for chunk in chunks:print(f"块大小: {len(chunk.page_content)}, 元数据: {chunk.metadata}")
输出内容:
块大小: 201, 元数据: {'source': './科幻短篇.txt'}
块大小: 25, 元数据: {'source': './科幻短篇.txt'}
块大小: 31, 元数据: {'source': './科幻短篇.txt'}
块大小: 46, 元数据: {'source': './科幻短篇.txt'}
块大小: 203, 元数据: {'source': './科幻短篇.txt'}
块大小: 19, 元数据: {'source': './科幻短篇.txt'}
块大小: 91, 元数据: {'source': './科幻短篇.txt'}
块大小: 466, 元数据: {'source': './科幻短篇.txt'}
块大小: 116, 元数据: {'source': './科幻短篇.txt'}
块大小: 0, 元数据: {'source': './科幻短篇.txt'}
SemanticChunker
的原理其实非常简单,核心思想是将文档拆分成独立的每一句,接下来根据传递的缓冲大小前后拼接字符串,然后计算拼接后的新字符串的文本嵌入/向量,然后计算这些文本的相似度,并根据传入的分块数和断点类型计算得到一个阈值,最后将相似度超过某个阈值的合并到一起,从而实现相似度分割。
目前在 SemanticChunker
底层检测相似度阈值的方法有 4 种:
-
百分位数 (默认)
-
标准差
-
四分位数
-
梯度
在LangChain
中,除了SemanticChunker
这种基于 Embedding 的语义分割器,还提供了 3 种基于自然语言处理的语义分割器: -
NLTKTextSplitter
NLTK(The Natural Language Toolkit)是一套用 Python 编程语言编写的用于英语符号和统计自然语言处理(NLP)的库和程序。 -
SpacyTextSplitter
spaCy 是一个用于高级自然语言处理的开源软件库,使用 Python 和 Cython 编程语言编写。 -
SentenceTransformersTokenTextSplitter
用于句子转换器模型的文本拆分器。默认行为是将文本拆分为适合您想要使用的句子转换模型的标记窗口的块。
资料推荐
- 💡大模型中转API推荐
- ✨中转使用教程
- ✨模型优惠查询