跳转到主要内容

文本分割器

[先决条件]

概述

文档分割通常是许多应用程序的关键预处理步骤。它涉及将大型文本分解为更小、更易于管理的块。此过程具有多个优点,例如确保一致地处理不同文档长度、克服模型的输入大小限制以及提高检索系统中使用的文本表示的质量。有几种分割文档的策略,每种策略都有其自身的优势。

主要概念

Conceptual Overview

文本分割器将文档分割成更小的块,以便在下游应用程序中使用。

为什么要分割文档?

分割文档有几个原因

  • 处理非均匀文档长度:真实世界的文档集合通常包含大小不一的文本。分割确保所有文档的处理一致。
  • 克服模型限制:许多嵌入模型和语言模型都有最大输入大小约束。分割使我们能够处理否则将超出这些限制的文档。
  • 提高表示质量:对于较长的文档,当它们尝试捕获太多信息时,嵌入或其他表示的质量可能会下降。分割可以产生更集中和准确的每个部分的表示。
  • 提高检索精度:在信息检索系统中,分割可以提高搜索结果的粒度,从而更精确地将查询与相关文档部分匹配。
  • 优化计算资源:处理较小的文本块可以更节省内存,并允许更好地并行处理任务。

现在,下一个问题是如何将文档分割成块!有几种策略,每种策略都有其自身的优势。

[进一步阅读]
  • 请参阅 Greg Kamradt 的 chunkviz,以可视化下面讨论的不同分割策略。

方法

基于长度

最直观的策略是根据文档的长度分割文档。这种简单而有效的方法确保每个块不超过指定的尺寸限制。基于长度分割的主要优点

  • 直接的实现
  • 一致的块大小
  • 易于适应不同的模型要求

基于长度的分割类型

  • 基于 Token:根据 token 的数量分割文本,这在使用语言模型时非常有用。
  • 基于字符:根据字符的数量分割文本,这在不同类型的文本中可能更一致。

使用 LangChain 的 CharacterTextSplitter 进行基于字符分割的示例实现

import { CharacterTextSplitter } from "@langchain/textsplitters";
const textSplitter = new CharacterTextSplitter({
chunkSize: 100,
chunkOverlap: 0,
});
const texts = await textSplitter.splitText(document);
[进一步阅读]

基于文本结构的分割

文本自然地组织成层次结构单元,例如段落、句子和单词。我们可以利用这种固有的结构来指导我们的分割策略,创建保持自然语言流程的分割,在分割内保持语义连贯性,并适应不同级别的文本粒度。LangChain 的 RecursiveCharacterTextSplitter 实现了这个概念

  • RecursiveCharacterTextSplitter 尝试保持较大的单元(例如,段落)完整。
  • 如果一个单元超过块大小,它会移动到下一个级别(例如,句子)。
  • 如有必要,此过程将继续向下到单词级别。

这是一个示例用法

import { RecursiveCharacterTextSplitter } from "@langchain/textsplitters";

const textSplitter = new RecursiveCharacterTextSplitter({
chunkSize: 100,
chunkOverlap: 0,
});
const texts = await textSplitter.splitText(document);
[进一步阅读]

基于文档结构的分割

某些文档具有固有的结构,例如 HTML、Markdown 或 JSON 文件。在这些情况下,根据文档的结构分割文档是有益的,因为它通常自然地将语义相关的文本分组在一起。基于结构分割的主要优点

  • 保留文档的逻辑组织
  • 在每个块内保持上下文
  • 对于检索或摘要等下游任务可能更有效

基于结构的分割示例

  • Markdown:基于标题分割(例如,#、##、###)
  • HTML:使用标签分割
  • JSON:按对象或数组元素分割
  • 代码:按函数、类或逻辑块分割
[进一步阅读]

基于语义意义的分割

与以前的方法不同,基于语义的分割实际上考虑了文本的内容。虽然其他方法使用文档或文本结构作为语义意义的代理,但此方法直接分析文本的语义。有几种实现此方法的方式,但从概念上讲,该方法是在文本意义发生重大变化时分割文本。例如,我们可以使用滑动窗口方法生成嵌入,并比较嵌入以找到显着差异

  • 从最初的几个句子开始并生成嵌入。
  • 移动到下一组句子并生成另一个嵌入(例如,使用滑动窗口方法)。
  • 比较嵌入以找到显着差异,这表明语义部分之间可能存在“断点”。

这项技术有助于创建语义上更连贯的块,从而可能提高检索或摘要等下游任务的质量。

[进一步阅读]
  • 请参阅 Greg Kamradt 的 notebook,其中展示了语义分割。

此页对您有帮助吗?


您也可以留下详细的反馈 在 GitHub 上.