【大模型从入门到精通22】开源库框架LangChain 深入探讨文本分割2


在这里插入图片描述

实际示例

简单文本字符串

示例文本字符串(字母表)

# 示例文本字符串(字母表)
alphabet_text = 'abcdefghijklmnopqrstuvwxyz'

# 使用两种分割器尝试分割 `alphabet_text`
recursive_character_text_splitter.split_text(alphabet_text)
character_text_splitter.split_text(alphabet_text, separator=' ')

内部工作原理

基于字符计数的文本分割器
# 定义一个类来根据字符数量分割文本。
class CharacterTextSplitter:
    def __init__(self, chunk_size, chunk_overlap=0):
        """
        初始化分割器,指定片段大小和重叠。

        参数:
        - chunk_size: 每个片段应包含的字符数。
        - chunk_overlap: 相邻片段间的字符重叠数。
        """
        self.chunk_size = chunk_size
        self.chunk_overlap = chunk_overlap

    def split_text(self, text):
        """
        根据初始化的片段大小和重叠来分割给定的文本。

        参数:
        - text: 要分割的文本字符串。

        返回:
        包含文本片段的列表。
        """
        chunks = []  # 初始化一个空列表来存储文本片段。
        start_index = 0  # 开始索引用于切片文本。

        # 循环分割文本直到达到文本末尾。
        while start_index < len(text):
            end_index = start_index + self.chunk_size  # 计算当前片段的结束索引。
            chunks.append(text[start_index:end_index])  # 切片文本并将其添加到列表中。
            # 更新下一个片段的开始索引,考虑到片段重叠。
            start_index = end_index - self.chunk_overlap
        return chunks  # 返回文本片段列表。

# 继承 `CharacterTextSplitter` 类以添加递归分割功能。
class RecursiveCharacterTextSplitter(CharacterTextSplitter):
    def split_text(self, text, max_depth=10, current_depth=0):
        """
        递归地分割文本成更小的片段,直到每个片段都在片段大小阈值以下或者达到了最大深度。

        参数:
        - text: 要分割的文本字符串。
        - max_depth: 防止无限递归的最大深度。
        - current_depth: 当前递归深度。

        返回:
        包含文本片段的列表。
        """
        # 基础条件:如果达到最大深度或文本长度在片段大小内,则返回文本作为一个单一片段。
        if current_depth == max_depth or len(text) <= self.chunk_size:
            return [text]
        else:
            # 将文本分为两半进行递归分割。
            mid_point = len(text) // 2
            first_half = text[:mid_point]
            second_half = text[mid_point:]
            # 递归分割每一半并将结果连接起来。
            return self.split_text(first_half, max_depth, current_depth + 1) + \
                   self.split_text(second_half, max_depth, current_depth + 1)

# 示例用法:
# 定义片段大小和重叠。
chunk_size = 26
chunk_overlap = 4

# 初始化 `Character Text Splitter` 分割器。
character_text_splitter = CharacterTextSplitter(chunk_size=chunk_size, chunk_overlap=chunk_overlap)

# 初始化 `Recursive Character Text Splitter` 分割器。
recursive_character_text_splitter = RecursiveCharacterTextSplitter(chunk_size=chunk_size)

# 定义一个要分割的样本文本字符串。
alphabet_text = 'abcdefghijklmnopqrstuvwxyz'

# 使用两种分割器分割样本文本,并存储结果。
recursive_chunks = recursive_character_text_splitter.split_text(alphabet_text)
simple_chunks = character_text_splitter.split_text(alphabet_text)

# 打印递归分割器的结果片段。
print("递归分割器片段:")
for chunk in recursive_chunks:
    print(chunk)

# 打印简单分割器的结果片段。
print("\n简单分割器片段:")
for chunk in simple_chunks:
    print(chunk)

这段代码展示了分割器如何处理基本的文本字符串,无论是否指定了分隔符。

高级分割技术

处理复杂文本

# 定义一个复杂的文本样本
complex_text = """当撰写文档时,作者会使用文档结构来组织内容...
句子以句号结尾,但也有空格。"""

# 应用递归分割,并定制片段大小和分隔符
recursive_character_text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=450,
    chunk_overlap=0, 
    separators=["\n\n", "\n", " ", ""]
)
recursive_character_text_splitter.split_text(complex_text)

这个例子说明了如何将复杂文本分割成有意义的片段,同时考虑文档本身的结构。

专业分割:基于词的分割和Markdown头部

基于词的分割

对于上下文窗口由大型语言模型定义的应用程序,按词计数分割可以使片段更接近模型的需求。

from langchain.text_splitter import TokenTextSplitter

# 初始化基于词的文本分割器
token_text_splitter = TokenTextSplitter(chunk_size=10, chunk_overlap=0)

# 按词分割文档页面
document_chunks_by_tokens = token_text_splitter.split_documents(pages)
Markdown头部文本分割

Markdown文档通常包含结构化的头部,这些头部可用于指导分割过程,保留文档的逻辑组织。

from langchain.text_splitter import MarkdownHeaderTextSplitter

# 定义Markdown文档中用于分割的头部
markdown_headers = [
    ("#", "一级标题"),
    ("##", "二级标题"),
]

# 初始化Markdown头部文本分割器
markdown_header_text_splitter = MarkdownHeaderTextSplitter(
    headers_to_split_on=markdown_headers
)

# 分割真实的Markdown文档,保留头部元数据
markdown_document_splits = markdown_header_text_splitter.split_text(markdown_document_content)

最佳实践与技巧

  • 语义连贯性:在分割文本时,优先考虑那些能保持内容语义完整性的策略。考虑文档的结构和文本的性质。
  • 重叠管理:妥善管理片段重叠,确保连续性而不重复信息。实验不同的重叠大小以找到最佳平衡。
  • 元数据保留:确保分割过程维护或增强了片段元数据,为每段文本提供有价值的上下文。
  • 16
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水木流年追梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值