RAG | 文本切分之按字符切分、按字符递归切分

当解析完文件,拿到纯文本的文件之后,接下来便是对文件内容进行分块,分块是为了更好地拆分语义单元,这样在后面可以更精确地进行语义检索。本文会介绍按字符切分按字符递归切分。在按字符递归切分中,会分别介绍纯文本的切分、代码的切分、MarkDown 文本的切分。在进行示例演示时,使用 LangChain 的 API。

一、按字符切分

在使用按字符切分时,需要指定分割符,另外需要指定块的大小以及块之间重叠的大小(允许重叠是为了尽可能地避免按照字符进行分割造成的语义损失)。整个流程如下:

首先按照指定的分割符进行切分,切分过之后,如果块的长度小于 chunk_size 的大小,则进行块之间的合并。在进行合并时,遵循下面的规则:

  1. 如果相邻块加在一起的长度小于或等于chunk_size,则进行合并;否则,不合并。

  2. 在进行合并时,如果块的大小小于或等于chunk_overlap,并且和前后两个相邻块合并后,两个合并后的块均不超过chunk_size,则两个合并后的块允许有重叠。

示例:

from langchain_text_splitters import CharacterTextSplitter         test_text = """这几天心里颇不宁静。今晚在院子里坐着乘凉,忽然想起日日走过的荷塘,在这满月的光里,总该另有一番样子吧。月亮渐渐地升高了,墙外马路上孩子们的欢笑,已经听不见了;妻在屋里拍着闰儿,迷迷糊糊地哼着眠歌。我悄悄地披了大衫,带上门出去。   沿着荷塘,是一条曲折的小煤屑路。这是一条幽僻的路;白天也少人走,夜晚更加寂寞。荷塘四面,长着许多树,蓊蓊郁郁的。路的一旁,是些杨柳,和一些不知道名字的树。没有月光的晚上,这路上阴森森的,有些怕人。今晚却很好,虽然月光也还是淡淡的。   路上只我一个人,背着手踱着。这一片天地好像是我的;我也像超出了平常的自己,到了另一个世界里。我爱热闹,也爱冷静;爱群居,也爱独处。像今晚上,一个人在这苍茫的月下,什么都可以想,什么都可以不想,便觉是个自由的人。白天里一定要做的事,一定要说的话,现在都可不理。这是独处的妙处,我且受用这无边的荷香月色好了。"""      text_splitter = CharacterTextSplitter(       separator="\n",       chunk_size = 300,       chunk_overlap = 200,       length_function = len,       is_separator_regex = False,   )   texts = text_splitter.create_documents([test_text])   for text in texts:       print(text)

在示例中,指定分割符为 \n,块的大小为 300,块之间重叠的大小为 200,输出结果如下:

page_content='这几天心里颇不宁静。今晚在院子里坐着乘凉,忽然想起日日走过的荷塘,在这满月的光里,总该另有一番样子吧。月亮渐渐地升高了,墙外马路上孩子们的欢笑,已经听不见了;妻在屋里拍着闰儿,迷迷糊糊地哼着眠歌。我悄悄地披了大衫,带上门出去。\n沿着荷塘,是一条曲折的小煤屑路。这是一条幽僻的路;白天也少人走,夜晚更加寂寞。荷塘四面,长着许多树,蓊蓊郁郁的。路的一旁,是些杨柳,和一些不知道名字的树。没有月光的晚上,这路上阴森森的,有些怕人。今晚却很好,虽然月光也还是淡淡的。'   page_content='沿着荷塘,是一条曲折的小煤屑路。这是一条幽僻的路;白天也少人走,夜晚更加寂寞。荷塘四面,长着许多树,蓊蓊郁郁的。路的一旁,是些杨柳,和一些不知道名字的树。没有月光的晚上,这路上阴森森的,有些怕人。今晚却很好,虽然月光也还是淡淡的。\n路上只我一个人,背着手踱着。这一片天地好像是我的;我也像超出了平常的自己,到了另一个世界里。我爱热闹,也爱冷静;爱群居,也爱独处。像今晚上,一个人在这苍茫的月下,什么都可以想,什么都可以不想,便觉是个自由的人。白天里一定要做的事,一定要说的话,现在都可不理。这是独处的妙处,我且受用这无边的荷香月色好了。'

二、按字符递归切分

纯文本的切分

上面的按字符切分只会按照指定的分割符切分一次,而按字符递归切分会指定一个分割符的列表,分割符列表为:"\n\n", "\n", " ", ""。在进行切分时,会遍历列表中的分割符进行按字符切分,直到满足块的大小要求。整个流程如下:

按字符递归切分可以认为是把按字符切分的流程循环多次,其中块合并的逻辑和按字符切分是一致的。

示例:

from langchain_text_splitters import RecursiveCharacterTextSplitter         test_text = """这几天心里颇不宁静。今晚在院子里坐着乘凉,忽然想起日日走过的荷塘,在这满月的光里,总该另有一番样子吧。月亮渐渐地升高了,墙外马路上孩子们的欢笑,已经听不见了;妻在屋里拍着闰儿,迷迷糊糊地哼着眠歌。我悄悄地披了大衫,带上门出去。   沿着荷塘,是一条曲折的小煤屑路。这是一条幽僻的路;白天也少人走,夜晚更加寂寞。荷塘四面,长着许多树,蓊蓊郁郁的。路的一旁,是些杨柳,和一些不知道名字的树。没有月光的晚上,这路上阴森森的,有些怕人。今晚却很好,虽然月光也还是淡淡的。   路上只我一个人,背着手踱着。这一片天地好像是我的;我也像超出了平常的自己,到了另一个世界里。我爱热闹,也爱冷静;爱群居,也爱独处。像今晚上,一个人在这苍茫的月下,什么都可以想,什么都可以不想,便觉是个自由的人。白天里一定要做的事,一定要说的话,现在都可不理。这是独处的妙处,我且受用这无边的荷香月色好了。"""      text_splitter = RecursiveCharacterTextSplitter(       chunk_size=150,       chunk_overlap=100,       length_function=len,       is_separator_regex=False,   )   texts = text_splitter.create_documents([test_text])   for text in texts:       print(text)

在示例中,块的大小为 150,块之间重叠的大小为 100,输出结果如下:

page_content='这几天心里颇不宁静。今晚在院子里坐着乘凉,忽然想起日日走过的荷塘,在这满月的光里,总该另有一番样子吧。月亮渐渐地升高了,墙外马路上孩子们的欢笑,已经听不见了;妻在屋里拍着闰儿,迷迷糊糊地哼着眠歌。我悄悄地披了大衫,带上门出去。'   page_content='沿着荷塘,是一条曲折的小煤屑路。这是一条幽僻的路;白天也少人走,夜晚更加寂寞。荷塘四面,长着许多树,蓊蓊郁郁的。路的一旁,是些杨柳,和一些不知道名字的树。没有月光的晚上,这路上阴森森的,有些怕人。今晚却很好,虽然月光也还是淡淡的。'   page_content='路上只我一个人,背着手踱着。这一片天地好像是我的;我也像超出了平常的自己,到了另一个世界里。我爱热闹,也爱冷静;爱群居,也爱独处。像今晚上,一个人在这苍茫的月下,什么都可以想,什么都可以不想,便觉是个自由的人。白天里一定要做的事,一定要说的话,现在都可不理。这是独处的妙处,我且受用这无边的荷香月色'   page_content='闹,也爱冷静;爱群居,也爱独处。像今晚上,一个人在这苍茫的月下,什么都可以想,什么都可以不想,便觉是个自由的人。白天里一定要做的事,一定要说的话,现在都可不理。这是独处的妙处,我且受用这无边的荷香月色好了。'

代码的切分

代码切分的流程和按字符递归切分的流程是一样的,只不过每种语言的分割符列表是不一样的。下面以 Python 代码的切分来举例。Python 代码的分割符列表为 "\nclass ", "\ndef ", "\n\tdef ", "\n\n", "\n", " ", ""

示例:

from langchain_text_splitters import (       Language,       RecursiveCharacterTextSplitter,   )         python_code = """   class Dog:       def __init__(self, name, age):           self.name = name           self.age = age         def binary_search(arr, target):       left, right = 0, len(arr) - 1              while left <= right:           mid = left + (right - left) // 2           if arr[mid] == target:               return mid           elif arr[mid] < target:               left = mid + 1           else:               right = mid - 1              return -1   """      python_splitter = RecursiveCharacterTextSplitter.from_language(       language=Language.PYTHON, chunk_size=400, chunk_overlap=0   )   python_docs = python_splitter.create_documents([python_code])   for python_doc in python_docs:       print(python_doc)

在示例中,块的大小为 400,块之间重叠的大小为 0,输出结果如下:

page_content='class Dog:\n    def __init__(self, name, age):\n        self.name = name\n        self.age = age'   page_content='def binary_search(arr, target):\n    left, right = 0, len(arr) - 1\n    \n    while left <= right:\n        mid = left + (right - left) // 2\n        if arr[mid] == target:\n            return mid\n        elif arr[mid] < target:\n            left = mid + 1\n        else:\n            right = mid - 1\n    \n    return -1'

Markdown 的切分

Markdown 切分的流程和按字符递归切分的流程是一样的,只不过 Markdown 的分割列表为 "\n#{1,6} ", "```\n", "\n\\*\\*\\*+\n", "\n---+\n", "\n___+\n", "\n\n", "\n", " ", ""

示例:

from langchain_text_splitters import RecursiveCharacterTextSplitter         markdown_text = """   ## 灵活的 Markdown 语言   + 在一篇笔记中处理文本、图片、表格和待办事项列表   + 通过灵活的标签轻松整理笔记和项目   + 根据不同场景需求,使用简单的 Markdown 符号便捷添加格式         ## 轻松整理   + 帮助您记笔记、制定周计划、写书,甚至建立个人维基的强大工具   + 快如原生应用,无论在线或离线状态下都能与您天马行空的想象力同步   + 想与全世界分享您的绝妙想法?可自由分享笔记或将其导出为多种格式         ## 赏心悦目   + 曾荣获苹果设计大奖   + 界面简约而无冗杂,助您全身心沉浸其中   + 多款精美主题提供了完美舒适的工作空间         ## 安全私密   + 您的笔记仅存储于本地或 iCloud,我们无法读取任何信息   + 选择加密笔记,为拒绝窥视提供加强防线   """      md_splitter = RecursiveCharacterTextSplitter.from_language(       language=Language.MARKDOWN, chunk_size=200, chunk_overlap=0   )   md_docs = md_splitter.create_documents([markdown_text])   for md_doc in md_docs:       print(md_doc)

在示例中,块的大小为 200,块之间重叠的大小为 0,输出结果如下:

page_content='## 灵活的 Markdown 语言\n+ 在一篇笔记中处理文本、图片、表格和待办事项列表\n+ 通过灵活的标签轻松整理笔记和项目\n+ 根据不同场景需求,使用简单的 Markdown 符号便捷添加格式'   page_content='## 轻松整理\n+ 帮助您记笔记、制定周计划、写书,甚至建立个人维基的强大工具\n+ 快如原生应用,无论在线或离线状态下都能与您天马行空的想象力同步\n+ 想与全世界分享您的绝妙想法?可自由分享笔记或将其导出为多种格式\n\n\n## 赏心悦目\n+ 曾荣获苹果设计大奖\n+ 界面简约而无冗杂,助您全身心沉浸其中\n+ 多款精美主题提供了完美舒适的工作空间'   page_content='## 安全私密\n+ 您的笔记仅存储于本地或 iCloud,我们无法读取任何信息\n+ 选择加密笔记,为拒绝窥视提供加强防线'

在实际的应用过程中,针对不同类型的文本应该选择不同的切分策略。而且,文本的切分和业务场景也是密切相关的,在制定策略的过程中,也要紧密结合业务场景,才能做到准确的切分。


最后

AI大模型作为人工智能领域的重要技术突破,正成为推动各行各业创新和转型的关键力量。抓住AI大模型的风口,掌握AI大模型的知识和技能将变得越来越重要。

学习AI大模型是一个系统的过程,需要从基础开始,逐步深入到更高级的技术。

这里给大家精心整理了一份全面的AI大模型学习资源,包括:AI大模型全套学习路线图(从入门到实战)、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频,免费分享!

在这里插入图片描述

一、大模型全套的学习路线

L1级别:AI大模型时代的华丽登场
L2级别:AI大模型API应用开发工程
L3级别:大模型应用架构进阶实践
L4级别:大模型微调与私有化部署

在这里插入图片描述

达到L4级别也就意味着你具备了在大多数技术岗位上胜任的能力,想要达到顶尖水平,可能还需要更多的专业技能和实战经验。

二、640套AI大模型报告合集

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

在这里插入图片描述

三、大模型经典PDF书籍

随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

在这里插入图片描述

四、AI大模型商业化落地方案

在这里插入图片描述

作为普通人在大模型时代,需要不断提升自己的技术和认知水平,同时还需要具备责任感和伦理意识,为人工智能的健康发展贡献力量。

有需要全套的AI大模型学习资源的小伙伴,可以微信扫描下方CSDN官方认证二维码,免费领取【保证100%免费

在这里插入图片描述

如有侵权,请联系删除。

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值