理解unstructured的Chunking:如何将大型图书馆变成易管理的小书架
- 原文链接
- 什么是文档分块?
- 分块的基本步骤
- 1. 准备材料
- 2. 设置分块大小
- 3. 开始分块
- 4. 查看结果
- 特殊情况处理
- 基本策略(basic)和按标题分块策略(by_title)
- 如何恢复分块后的原始元素信息
- 总结
大家好!今天我们来聊一聊文档分块。这个概念乍一听可能有点复杂,但其实很简单,就像我们整理一个大型图书馆一样。让我们用整理图书馆的例子来了解文档分块的过程吧!
原文链接
https://docs.unstructured.io/open-source/core-functionality/chunking#basic-chunking-strategy
您说得对,我同意切蛋糕的例子可能不是最恰当的。让我们换一个更贴切的例子来解释文档分块。我会以整理一个大型图书馆的书籍为例,重新撰写这篇文章。
什么是文档分块?
想象一下,你是一个图书管理员,负责管理一个巨大的图书馆。这个图书馆里有成千上万本书,如果所有书都堆在一起,想找到某一本书会非常困难。这时候,我们会怎么做呢?对了,我们会把书按照主题分类,放在不同的书架上。文档分块就是这个意思 - 把一个很长的文档分成更小、更容易管理和理解的部分。
分块的基本步骤
1. 准备材料
就像整理图书馆需要书籍、书架和分类标签一样,分块也需要一些基本的"原料"。在代码中,这些原料就是文档的不同部分,比如标题、段落等。
elements = [Title("世界历史"),NarrativeText("这是一本关于世界历史的综合介绍。"),
]
2. 设置分块大小
我们需要决定每个书架能放多少本书。在文档分块中,我们用字符数来衡量:
max_characters = 500 # 每个"书架"最多能放500个字符
new_after_n_chars = 400 # 最好是每个"书架"放400个字符左右
3. 开始分块
现在,我们开始整理图书…哦不,是分块文档:
chunks = chunk_elements(elements, max_characters=500, new_after_n_chars=400)
4. 查看结果
就像整理好图书后,我们会检查每个书架是否合理,文档分块后我们也会检查每个块:
for chunk in chunks:print(chunk.text)print("-" * 20)
特殊情况处理
有时候,我们可能会遇到一些特殊情况,比如:
-
特大书籍: 有些书可能特别厚,一个普通书架放不下。这就像文档中特别长的段落,我们需要把它分成几部分。
-
成套书籍: 有些书是一整套的,我们希望它们放在一起。在文档中,某些部分(如表格)也需要保持完整。
-
相关书籍: 有时候我们会在相邻的书架上放一些相关的书,以便查阅。在文档分块中,我们称之为"重叠",让每块有一点点内容重复。
overlap = 20 # 每个"书架"有20个字符的重叠
基本策略(basic)和按标题分块策略(by_title)
两种文本分块策略:基本策略(basic)和按标题分块策略(by_title)。我来解析一下它们的主要特点:
-
基本策略(basic):
- 将连续的元素组合,以最大程度地填充每个块,同时遵守指定的最大字符数(硬上限)和新块起始字符数(软上限)。
- 单个超过硬上限的元素会被隔离,并使用文本分割拆分为多个块。
- 表格元素总是被隔离,不与其他元素组合。过大的表格也会被分割成多个TableChunk元素。
- 如果指定了重叠,它会应用于由分割过大元素形成的块之间,当overlap_all为True时也应用于其他块之间。
-
按标题分块策略(by_title):
包含基本策略的所有行为,并额外具有以下特点:- 保留章节边界,可选择性地保留页面边界。
- 检测章节标题:遇到Title元素时,会关闭前一个块并开始新块。
- 尊重页面边界:通过multipage_sections参数控制。默认为True,意味着页面中断不会开始新块。设为False会将不同页面上的元素分到不同块中。
- 合并小节:使用combine_text_under_n_chars参数来合并较小的节,以避免产生过小的块。默认值与max_characters相同,可以设置为0以禁用节的合并。
这两种策略的主要区别在于by_title策略更注重保留文档的结构,特别是章节和标题的完整性,而basic策略则更关注于均匀地填充每个块到指定的大小。
如何恢复分块后的原始元素信息
-
分块过程中的信息损失:
- 当多个文档元素被合并成一个块时,一些信息会自然丢失。
- 例如,无法确定文本的具体来源元素,以及某些元数据(如页码和坐标)可能无法解析为单一值。
-
访问原始元素:
- 可以通过
.metadata.orig_elements
字段访问组成块的原始元素。 - 示例代码展示了如何创建一个包含标题和正文的块,然后访问其原始元素。
- 可以通过
-
使用原始元素访问元数据:
- 原始元素保留了所有原始元数据。
- 可以用于访问那些无法可靠合并的元数据。
-
示例应用:
- 获取页码集合:通过遍历原始元素,可以获取所有相关的页码。
- 获取坐标信息:可以获取每个原始元素的坐标元数据。
- 获取图像路径:可以从具有图像路径的原始元素中提取图像路径。
这段代码的主要目的是展示如何在分块后仍然保留和访问原始文档元素的详细信息。这对于需要精确元数据(如页码、坐标、图像路径等)的应用场景非常有用,因为这些信息在分块过程中可能会丢失或变得不明确。
通过 .metadata.orig_elements
,用户可以在需要时轻松地回溯到原始文档结构和元数据,从而在保持文本分块效率的同时不损失重要的文档结构信息。
总结
通过这个整理图书馆的例子,我们了解了文档分块的基本概念。它就像把一个大图书馆变成许多有序的小书架,让每个人都能轻松找到想要的信息。同样,文档分块让我们能更容易地阅读和理解长文档。
下次当你看到一个很长的文章时,不妨想象它是一个大图书馆,然后试着把它分成小书架。这样不仅更容易理解,还能让阅读变得更有条理哦!
希望这篇文章能帮助你理解文档分块的概念。如果你有任何问题,欢迎在评论区留言。让我们一起学习,一起成长!