【NLP】利用 RAG 模分块技术提升文档处理效能

f0a23f4cb1ba45768387b1257022b780.webp

将大型文档划分为较小的部分是一项至关重要但又复杂的任务,它对检索增强生成 (RAG) 系统的性能有重大影响。这些系统旨在通过结合基于检索和基于生成的方法,提高输出的质量和相关性。有效的分块,即将文档拆分为可管理的片段的过程,对于优化 RAG 系统的检索和嵌入步骤至关重要。各种框架提供了几种分块方法,每种方法都有自己的优势和用例。在本文中,我介绍了一种新技术,它利用句子嵌入来识别文档中的主题变化,从而确保每个块都封装一个主题。这种方法增强了系统生成连贯且适合上下文的响应的能力,我们之前已经在主题建模的背景下探索过这一点。

了解检索增强生成 (RAG) 系统

检索增强生成 (RAG) 系统是一种复杂的机器学习模型,它将基于检索的技术与生成模型相结合。RAG 系统的主要目标是通过整合从大型数据集中检索到的信息来提高生成内容的质量和相关性。以下是 RAG 系统工作原理的细分:

  1. 检索阶段:系统首先根据输入查询检索相关文档或信息。此阶段依靠搜索算法和索引方法从大量数据中快速识别最相关的数据。
  2. 生成阶段:检索到相关文档后,将使用生成模型(通常是基于转换器的语言模型,如 GPT-4)来创建连贯且适合上下文的响应。该模型使用检索到的信息来确保生成的内容准确且信息丰富。

RAG 系统的混合特性使其特别适用于复杂或知识密集型任务,其中检索和生成的结合显著提高了整体性能。

文档拆分探索

在深入研究新分块技术的细节之前,了解文档拆分的标准方法至关重要。文档拆分是许多自然语言处理 (NLP) 任务的基础步骤,并且采用各种技术来确保以保留含义和上下文的方式划分文本。以下是一些常用方法,使用广泛采用的 Langchain 框架进行说明:

  1. 递归字符文本分割器:此方法通过基于字符递归地划分文本来分割文档。每个块的长度保持在指定长度以下,这对于具有自然段落或句子分隔的文档特别有用。此方法可确保块易于管理且易于处理,而不会丢失文档的固有结构。
  2. 标记分割器:此技术使用标记(可以是单词或子单词)来分割文档。在使用具有标记限制的语言模型时,它非常有用,因为它可以确保每个块都符合模型的限制。基于标记的分割通常用于 NLP 任务中,以在遵守模型限制的同时保持文本的完整性。
  3. 句子分割器:通过在句子边界处分割文档,此方法可保持文本的上下文完整性。句子通常代表完整的想法,因此这种方法非常适合需要连贯理解内容的任务。
  4. 正则表达式拆分器:此方法使用正则表达式来定义自定义拆分点。它提供了最高的灵活性,允许用户根据特定于其用例的模式拆分文档。例如,可以在每个特定关键字或标点符号实例处拆分文档。
  5. Markdown 拆分器:此方法专为 Markdown 文档量身定制,可根据标题、列表和代码块等 Markdown 特定元素拆分文本。它保留了 Markdown 文档的结构和格式,适合用于技术文档和内容管理。

高级分块方法

根据手头任务的具体要求,可以以各种方式应用分块。以下是满足不同需求的高级分块方法的概述:

  1. 按字符:此方法将文本分解为单个字符。它对于需要深入细致的文本分析的任务很有用,例如字符级语言模型或某些类型的文本预处理。
  2. 按字符 + SimplerLLM:此技术位于 SimplerLLM 库中,按字符对文本进行分块,同时保留句子结构。通过保持基于字符的块内句子的完整性,它可以提供更好、更有意义的片段。
  3. 按标记:将文本分割为标记(例如单词或子单词)是自然语言处理中的标准方法。基于标记的分块对于文本分类、语言建模和其他依赖标记化输入的 NLP 应用程序等任务至关重要。
  4. 按段落:按段落分块文本有助于维护文档的整体结构和流程。此方法非常适合需要更多上下文的任务,例如文档摘要或内容提取。
  5. 递归分块:这涉及反复将数据分解为较小的块,通常用于分层数据结构。递归分块对于需要多级分析的任务(例如主题建模或分层聚类)非常有用。
  6. 语义分块:对于需要理解数据上下文的任务来说,根据含义而不是结构元素对文本进行分组至关重要。语义分块利用句子嵌入等技术来确保每个块代表一个连贯的主题或想法。
  7. 代理分块:此方法侧重于根据所涉及的代理(例如人员或组织)识别和分组文本。它在信息提取和实体识别任务中很有用,在这些任务中,了解不同实体之间的角色和关系非常重要。

新颖的分块技术:主题感知句子嵌入

我介绍的新分块技术旨在使用句子嵌入来识别文档中主题的变化。通过识别主题发生变化的点,该技术可确保每个块都封装一个连贯的主题。此方法利用先进的 NLP 技术来增强 RAG 系统的性能:

  1. 句子嵌入:句子嵌入将句子转换为高维向量,以捕捉其语义。通过分析这些向量,我们可以识别主题发生变化的点。
  2. 主题检测:该技术使用专为主题建模而设计的算法,检测主题的变化并确定拆分文档的最佳点。这确保每个块在主题上都是连贯的。
  3. 增强的检索和嵌入:通过确保每个块代表一个主题,RAG 系统中的检索和嵌入步骤变得更加高效。每个块的嵌入更有意义,从而实现更好的检索性能和更准确的响应。

这种技术已在主题建模中得到证实,但它同样适用于 RAG 系统。通过采用这种方法,RAG 系统可以在其生成的内容中实现更高的准确性和相关性,使其更有效地完成复杂且知识密集型的任务。

使用 LangChain 的高级文档拆分技术

在上一节中,我们探讨了各种文档拆分方法及其在检索增强生成 (RAG) 系统中的应用。现在,让我们深入研究使用 LangChain 框架实现这些技术的实际示例。此外,我们将介绍一种新颖的主题感知分块方法,该方法利用句子嵌入来识别文档中的主题转变。

LangChain 中的文档拆分示例

以下是 LangChain 中文档拆分方法的一些示例,以及详细的解释和代码片段来演示它们的用法:

  1. 递归字符文本分割器

递归字符文本分割器方法根据字符数将文本分成多个块,确保每个块的长度不超过指定长度。此方法对于在文档中保持自然的段落或句子分隔非常有用。

# 从 langchain 导入 RecursiveCharacterTextSplitter 类
from langchain.text_splitter import RecursiveCharacterTextSplitter # 示例长文档文本
text = "您的长文档文本在此处..." # 使用 1000 个字符的块大小和 50 个字符的重叠部分初始化 RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(chunk_size= 1000 , chunk_overlap= 50 ) # 将文本拆分为块
chunks = splitter.split_text(text) # 打印每个块
for chunk in chunks: print (chunk)

2. Token拆分器

Token Splitter 方法根据 token(例如单词或子单词)划分文本。在使用具有 token 限制的语言模型时,这种方法非常有用。

# 从 langchain 导入 TokenSplitter 类
from langchain.text_splitter import TokenSplitter # 示例长文档文本
text = "您的长文档文本在此处..." # 使用最大 token 限制 512 初始化 TokenSplitter
splitter = TokenSplitter(max_tokens= 512 ) # 将文本拆分为块
chunks = splitter.split_text(text) # 打印每个块
for chunk in chunks: print (chunk)

3.句子分割器

句子分割器方法在句子边界处分割文本,保留文本的上下文完整性。此方法非常适合需要连贯完整思想的任务。

# 从 langchain 导入 SentenceSplitter 类
from langchain.text_splitter import SentenceSplitter # 示例长文档文本
text = "您的长文档文本在此处..." # 初始化 SentenceSplitter,每个块的最大长度为 5 个句子
splitter = SentenceSplitter(max_length= 5 ) # 将文本拆分为块
chunks = splitter.split_text(text) # 打印每个块
for chunk in chunks: print (chunk)

4.正则表达式分割器

Regex Splitter 方法使用正则表达式来定义自定义分割点,为各种用例提供​​高度的灵活性。

# 从 langchain 导入 RegexSplitter 类
from langchain.text_splitter import RegexSplitter # 示例长文档文本
text = "您的长文档文本在此处..." # 使用模式初始化 RegexSplitter,在双换行符处拆分文本
splitter = RegexSplitter(pattern= r'\n\n+' ) # 将文本拆分为块
chunks = splitter.split_text(text) # 打印每个块
for chunk in chunks: print (chunk)

5. Markdown 分割器

Markdown Splitter 方法是针对 markdown 文档量身定制的,根据 markdown 特定元素(如标题、列表和代码块)拆分文本。

# 从 langchain 导入 MarkdownSplitter 类
from langchain.text_splitter import MarkdownSplitter # 长 markdown 文档示例文本
text = "您的长 markdown 文档在此处..." # 初始化 MarkdownSplitter
splitter = MarkdownSplitter() # 将文本拆分为块
chunks = splitter.split_text(text) # 打印每个块
for chunk in chunks: print (chunk)

引入一种新颖的主题感知分块方法

将大型文档分割成连贯的主题部分是数字内容分析中的一项重大挑战。如上所述,传统方法通常难以准确检测细微的主题变化。我们的新方法利用句子嵌入来增强分割过程,提供更精确、更有意义的区块。

核心挑战

大型文档(例如学术论文、长篇报告和详细文章)通常包含多个主题。传统的分割技术(从简单的基于规则的方法到高级机器学习算法)都难以识别主题转换的精确点。这些方法通常会错过细微的转换或错误地识别它们,从而导致部分内容支离破碎或重叠。

利用句子嵌入

我们的方法采用 Sentence-BERT (SBERT) 为单个句子生成嵌入。这些嵌入是封装句子语义内容的密集向量表示。

  1. 生成嵌入

SBERT 用于为文档中的每个句子生成嵌入。这些嵌入可以捕捉句子的语义,使我们能够衡量它们的相似性。

from sentence_transformers import SentenceTransformer# 例句
sentences = [ "句子 1..." , "句子 2..." , ...] # 初始化 SBERT 模型
model = SentenceTransformer( 'paraphrase-MiniLM-L6-v2' ) # 为每个句子生成嵌入 
embeddings = model.encode(sentences)

2. 计算相似度

句子之间的相似度使用余弦相似度或其他距离测量方法(如曼哈顿距离或欧几里得距离)来衡量。这有助于识别连续句子之间的连贯性。

from sklearn.metrics.pairwise import cosine_similarity# 计算嵌入之间的余弦相似度
similarity_matrix = cosine_similarity(embeddings)

3.差距得分和平滑

为了检测主题转换,我们定义了一个参数n来指定要比较的句子数量。该算法根据余弦相似度计算差距分数。

import numpy as np # 定义参数 nn = 2 # 计算差距分数
gap_scores = [] 
for i in  range ( len (embeddings) - n): similarity = cosine_similarity(embeddings[i:i+n], embeddings[i+n:i+ 2 *n]) gap_scores.append(np.mean(similarity))

为了解决差距分数中的噪音问题,我们采用了平滑算法。窗口大小k决定了平滑的程度。 

# 定义窗口大小 k
k = 3 # 平滑差距分数
smoothed_gap_scores = np.convolve(gap_scores, np.ones(k)/k, mode= 'valid' )

4.边界检测

分析平滑后的差距分数以识别局部最小值,这表明潜在的主题转换。c使用阈值来确定重要边界。

# 检测局部最小值
local_minima = (np.diff(np.sign(np.diff(smoothed_gap_scores))) > 0 ).nonzero()[ 0 ] + 1 # 设置阈值 c
c = 1.5 # 识别显著边界
significance_boundaries = [i for i in local_minima if smoothed_gap_scores[i] < np.mean(smoothed_gap_scores) - c * np.std(smoothed_gap_scores)]

5.聚类片段

对于较长的文档,类似的主题可能会重复出现。为了解决这个问题,该算法将具有类似内容的片段聚类,从而减少冗余并确保每个主题都有唯一的表示。

from sklearn.cluster import KMeans# 将文本段转换为嵌入
segment_embeddings = [np.mean(embeddings[start:end], axis= 0 ) for start, end in  zip (significant_boundaries[:- 1 ], significance_boundaries[ 1 :])] # 应用聚类
kmeans = KMeans(n_clusters= 5 ) 
clusters = kmeans.fit_predict(segment_embeddings)

未来发展方向

该方法提出了一种复杂的文档分割方法,将传统原理与尖端的句子嵌入相结合。未来的研究可以探索以下领域以进一步增强该方法:

  • 自动参数优化:利用机器学习技术动态调整参数。
  • 广泛的数据集试验:在多样化、大型数据集上测试该方法以验证其有效性。
  • 实时分割:探索动态文档的实时应用。
  • 模型改进:集成更新的变压器模型以增强性能。
  • 多语言分割:使用多语言 SBERT 将该方法应用于不同的语言。
  • 分层分割:调查多个层次的分割以进行详细的文档分析。
  • 用户界面开发:创建交互式工具,以便更轻松地调整分割结果。
  • 与NLP任务的集成:将算法与其他自然语言处理任务相结合。

结论

我们的方法为大型文档中的精确主题建模提供了一种强大而有效的解决方案。通过利用 SBERT 和先进的平滑和聚类技术,这种方法比传统的文档分割方法有了显著的改进。这项创新提高了 RAG 系统的性能,使它们能够为复杂且知识密集型的任务生成更相关、更连贯的内容。

 


http://www.ppmy.cn/news/1474636.html

相关文章

【区块链+跨境服务】基于区块链的离岸贸易综合服务平台 | FISCO BCOS应用案例

离岸贸易是一种新型的国际贸易模式&#xff0c;指在一个国家或地区的境内&#xff0c;通过一定的方式&#xff0c;将两个或多个国家或地区 之间的贸易活动&#xff0c;从货物流、资金流和信息流三个方面分离开来&#xff0c;实现货物不经过境内&#xff0c;直接从一个国家或地区…

qt 的表格控件有什么

在Qt中&#xff0c;表格控件主要用于显示和编辑表格数据。以下是Qt中常用的表格控件及其相关信息的详细归纳&#xff1a; QTableWidget 介绍&#xff1a;QTableWidget是Qt框架下的一个表格控件&#xff0c;它是基于QTableView的封装&#xff0c;并提供了更方便的方式来操作和呈…

uboot学习:(二)uboot命令

目录 uboot命令 常见命令 内存操作命令 网络操作命令 EMMC/SD卡操作命令: FAT格式文件系统操作命令: EXT格式文件系统操作命令 NAND操作命令 BOOT操作命令 其他命令 uboot命令 在烧录uboot到板子中后&#xff0c;开机三秒后才会进入系统&#xff0c;在这三秒按enter…

【机器学习】特征选择:精炼数据,提升模型效能

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 特征选择&#xff1a;精炼数据&#xff0c;提升模型效能引言为何进行特征选择&a…

【LeetCode】633. 平方数之和

1. 题目 2. 分析 典型双指针的题了&#xff0c;不知道为啥LeetCode会把这题放到二分类别下&#xff1f; 需要知道math.ceil()是向上取整&#xff1b; 3. 代码 class Solution:def judgeSquareSum(self, c: int) -> bool:upper math.ceil(sqrt(c))print(upper)left, ri…

微信小程序之使用上拉加载实现图片懒加载

在微信小程序中&#xff0c;有2个事件&#xff0c;相信大家都很熟悉 下拉重新加载 上拉加载更多 事件是这么个事件&#xff0c;至于事件触发后干嘛&#xff0c;那就看代码了 首先要在对应得地方xxxxpage.json打开这个 "onReachBottomDistance": 100至于这个值100还是…

SpringSecurity 三更草堂学习笔记

0.简介 Spring Security是Spring家族中的一个安全管理框架。相比与另外一个安全框架Shiro&#xff0c;它提供了更丰富的功能&#xff0c;社区资源也比Shiro丰富。 一般来说中大型的项目都是使用SpringSecurity来做安全框架。小项目有Shiro的比较多&#xff0c;因为相比与Spring…

合并pdf的方法,如何合并pdf文件到一个pdf,简单方法

在现代办公和学习中&#xff0c;pdf格式的文件因其跨平台兼容性和安全性得到了广泛应用。然而&#xff0c;有时我们需要将多个pdf文件合并成一个&#xff0c;以便于管理和分享。本文将详细介绍几种合并pdf的方法&#xff0c;帮助读者轻松完成pdf文件的合并工作。 方法一、使用p…

urlib Python爬虫

要使用Python进行爬虫&#xff0c;可以使用Python自带的urllib库。 urllib是Python内置的HTTP请求库&#xff0c;用于发送HTTP请求、处理响应和处理URL编码等任务。它提供了很多方法和函数&#xff0c;可以方便地进行网络数据的获取和处理&#xff0c;因此在Python爬虫中被广泛…

极速目标检测:算法加速的策略与实践

标题&#xff1a;极速目标检测&#xff1a;算法加速的策略与实践 目标检测算法在计算机视觉任务中扮演着重要角色&#xff0c;但其计算成本往往较高。优化目标检测算法的速度&#xff0c;不仅可以提升效率&#xff0c;还能使算法适用于实时系统。本文将深入探讨如何优化目标检…

JS进阶-解析赋值

学习目标&#xff1a; 掌握解析赋值 学习内容&#xff1a; 解构赋值数组解构对象解构筛选数组filter方法&#xff08;重点&#xff09; 解构赋值&#xff1a; 解构赋值是一种快速为变量赋值的简洁语法&#xff0c;本质上仍然是为变量赋值。 分为&#xff1a; 数组解构对象解…

Android 性能优化之启动优化

文章目录 Android 性能优化之启动优化启动状态冷启动温启动热启动 耗时检测检测手段TraceView使用方式缺点 Systrace环境配置使用方式TraceView和Systrace比较 AOP统计耗时环境配置使用 优化白屏优化异步加载优化环境配置使用 延迟加载优化AppStartup 源码下载 Android 性能优化…

Apache Web安全分析与增强

Apache HTTP Server 概述 Apache HTTP Server(通常简称为Apache)是一个开源的Web服务器软件,由Apache软件基金会开发和维护。它是全球使用最广泛的Web服务器之一,支持多种操作系统,包括Unix、Linux、Windows和Mac OS X。以下是Apache Web服务器的详细概述,包括其功能特点…

阿里巴巴矢量图标库使用

阿里巴巴矢量图标库官网 添加图标到购物车 悬浮到图标上面会有个购物车icon,点击一下就可以添加购物车了 添加图标到项目 添加完购物车后,右上角会有当前在购物车的数量,点击右上角购物车icon,在新弹窗内点击添加至项目,选择添加到哪个项目(没有项目就创建一个),点击完成,…

PostgreSQL的使用

PostgreSQL的使用 1.首先&#xff0c;使用docker进行安装pgvector数据库&#xff0c;具体的安装步骤可以查看我之前发的博文。 2.docker exec -it pgvector /bin/bash 进入docker容器内部&#xff0c;操作数据库&#xff0c;上述命令是以交互式命令进入了容器的内部&#xf…

View->裁剪框View的绘制,手势处理

XML文件 <?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android…

100 个网络基础知识普及,看完成半个网络高手!

1&#xff09;什么是链接&#xff1f; 链接是指两个设备之间的连接。它包括用于一个设备能够与另一个设备通信的电缆类型和协议。 2&#xff09;OSI 参考模型的层次是什么&#xff1f; 有 7 个 OSI 层&#xff1a;物理层&#xff0c;数据链路层&#xff0c;网络层&#xff0…

lua 脚本语言 : 基础到高级语法

❃博主首页 &#xff1a; 「码到三十五」 &#xff0c;同名公众号 :「码到三十五」&#xff0c;wx号 : 「liwu0213」 ☠博主专栏 &#xff1a; <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关> ♝博主的话 &#xff1a…

ARM功耗管理之唤醒源与组合唤醒源

安全之安全(security)博客目录导读 思考&#xff1a;什么是睡眠锁&#xff1f;什么是唤醒源&#xff1f;什么是组合唤醒源&#xff1f; DynamIQ系统下的唤醒源 Redistributor中包含了一个GICR_WAKER寄存器&#xff0c;用于记录connected PE的状态是onLine还是offline. 如果让P…

jitsi 使用JWT验证用户身份

前言 Jitsi Meet是一个很棒的会议系统,但是默认他运行所有人创建会议,这样在某种程度上,我们会觉得他不安全,下面我们就来介绍下使用JWT来验证用户身份 方案 卸载旧的lua依赖性sudo apt-get purge lua5.1 liblua5.1-0 liblua5.1-dev luarocks添加ubuntu的依赖源,有则不需…