【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.mzph.cn/diannao/43462.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

音频demo:使用开源项目lame来将MP3数据解码出PCM数据

1、README 前言 本demo是使用开源项目lame来将MP3数据解码成PCM数据。&#xff08;环境&#xff1a;x86_64 Ubuntu16.04 64位&#xff09; 注&#xff1a;在下面【参考文章】中的第1篇里面提到解码出现过异常情况&#xff08;hip: bitstream problem, resyncing skipping xxx…

显示渲染-OSG框架解析

1.背景介绍 1.1 OSG介绍 OSG的全称&#xff1a;OpenSceneGraph&#xff0c;它是一个开放源码&#xff0c;跨平台的图形开发包&#xff0c;它为诸如飞行器仿真&#xff0c;游戏&#xff0c;虚拟现实&#xff0c;科学计算可视化这样的高性能图形应用程序开发而设计。 它基于场…

Springboot随机端口配置

网上所有地方都告诉你的错误配置: server: port: ${random.int[6008,6009]} 这才是正确配置: server: port: ${random.int(6008,6009)} 如果能解决你的问题请记得点赞&#xff01;让更多人知道&#xff01;

DNS缓存详解

目录 一、缓存分类 1. 客户端缓存&#xff08;以浏览器缓存为列&#xff09; 2. 操作系统缓存 3.本地hosts文件静态映射 二、DNS查找优先顺序 1.浏览器查找顺序 2.cmd ping查找顺序&#xff08;非浏览器&#xff09; 一、缓存分类 在一台终端上&#xff0c;DNS缓存可以…

Android 12系统源码_设备设置(一)Settings介绍

前言 Settings 类是一个用于访问和管理设备设置的关键类&#xff0c;而作为系统开发人员&#xff0c;经常需要用这个类来做一些系统设备设置&#xff0c;而Settings里面存在着好几个处理不同领域的设备设置类&#xff0c;那么如何才能结合自己的业务场景正确选择使用这些设备设…

微信小程序开发跳转京东,淘宝小程序

没有淘宝小程序&#xff0c;所以只能提示他复制链接网页打开 跳转京东小程序 获取京东小程序 京东小程序appId&#xff1a;wx91d27dbf599dff74 或者点开京东小程序&#xff0c;查看详情即可获取到京东的appid 店铺页面路径 店铺首页&#xff1a;pages/shop/index/index?…

《无所不能的JavaScript · prototype 原型链》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; 近期刚转战 CSDN&#xff0c;会严格把控文章质量&#xff0c;绝不滥竽充数&#xff0c;欢迎多多交流。&am…

OpenWrt入门 (1) - 登录及ssh命令接入wifi

本文参考自: [OpenWrt 维基]在 OpenWrt 上启用 Wi-Fi 接入点 --- [OpenWrt Wiki] Enabling a Wi-Fi access point on OpenWrt 需要详细了解的小伙伴请看原文 基本概念 OpenWrt是适用于嵌入式设备的一个Linux发行版。 相对原厂固件而言&#xff0c;OpenWrt不是一个单一、静态…

企业如何从无序管理走向精益生产管理?

先来看看企业生产管理无序的弊端有哪些&#xff1f; 数据统计不及时&#xff1a;纸质生产工单&#xff0c;数据难统计&#xff0c;各业务环节问题难定位&#xff0c;影响车间生产效率。生产过程不透明&#xff1a;生产过程数据难监控&#xff0c;生产派工管理混乱&#xff0c;…

【前端】面试八股文——meta标签

【前端】面试八股文——meta标签 在HTML文档中&#xff0c;meta标签是一个关键但常被忽视的元素。它位于文档的<head>部分&#xff0c;用于提供关于HTML文档的元数据&#xff08;metadata&#xff09;。这些元数据不会直接显示在页面上&#xff0c;但对搜索引擎优化&…

web前端开发——标签一

今天我来针对web前端开发讲解标签一 Html标签_标题&段落&换行 注释标签&#xff1a;Ctrl/ Ctrl/ &#xff0c;用户可能会获取到注释标签 注释的原则: •和代码逻辑一致 •尽量使用中文 •正能量 标题标签&#xff1a;<h1></h1> h1-h6 标题标签有6…

C++线程锁std::mutex

基本用法 “mutex”是“mutual exclusion”的缩写&#xff0c;意思是互斥锁。互斥锁用于多线程编程中&#xff0c;以确保同一时间只有一个线程能够访问某一共享资源&#xff0c;从而避免数据竞争和不一致性。 std::mutex是最基本的互斥锁&#xff0c;用于保护共享数据。它有两…

Vue3框架搭建2:axios+typescript封装

仓库地址&#xff1a;https://github.com/buguniao5213/LuArch&#xff08;分支代码未上传&#xff0c;完整一系列后传一波&#xff0c;中途有需求可以再传&#xff09; 1、安装axios npm install axios2、创建文件 先创建一个文件夹&#xff1a; ├── src/ │ ├── …

51单片机-第二节-数码管

一、数码管介绍&#xff1a; 1.什么是数码管&#xff1f; 多个LED组合成8字显示器。 2.一位数码管的引脚&#xff08;只有一个8&#xff09;&#xff1a; 数码管的引脚为1-10&#xff0c;其中公共极为3,8&#xff0c;其余八位分别对应一个二极管&#xff0c;如下图&#xff…

Vue2 基础十Vuex

代码下载 Vuex 概述 组件之间共享数据的方式&#xff1a; 父组件向子组件传值&#xff0c;是以属性的形式绑定值到子组件&#xff08;v-bind&#xff09;&#xff0c;然后子组件用属性props接收。子组件向父组件传值&#xff0c;子组件用 $emit() 自定义事件&#xff0c;父组…

JavaScript--local storage存储的数组不可扩展的问题

数组扩展 问题解析解决办法总结进一步扩展原因 问题 下列代码中的points是从本地存储中获取到的数据&#xff0c;我想存储到一个Map并且新增元素的时候报错 let obj this.objectsManager._objects.get(obstacle.uuid);let points obj.track_points;this.dyObstacleTP.set(ob…

【大模型】大模型相关技术研究—微调

为什么要对大模型进行微调 1.成本效益&#xff1a; o 大模型的参数量非常大&#xff0c;训练成本非常高&#xff0c;每家公司都去从头训练一个自己的大模型&#xff0c;这个事情的性价比非常低。 2.Prompt Engineering 的局限性&#xff1a; o Prompt Engineering 是一种相…

视图库对接系列(GA-T 1400)十二、视图库对接系列(本级)人员数据推送

背景 人体和非机动车和机动车类似的,只是请求的参数不一样而已。人员数据推送 接入人员数据推送相对比较简单,我们只需要实现对应的接口就ok了。 具体如图: 有增删改查接口,目前的话 因为我们是做平台,我们只需要实现添加接口就可以了。 接口实现 service 层 /**** …

软件工程面向对象 超市管理系统 需求分析 系统设计 课程设计报告

1、引言 系统简述 超市管理系统的功能主要有前台管理和后台管理两个大块。其使用对象 有超市管理人员和超市销售人员两类。超市管理系统主要为了实现商品输 入、 输出管理数据的自动化&#xff0c; 提高商品统计信息的实时性&#xff0c; 减轻人工劳动强 度从而节省人力成本。实…

Perl 语言开发(九):深入探索Perl语言的文件处理

目录 1. 文件打开与关闭 1.1 打开文件 1.2 关闭文件 2. 读取文件内容 2.1 逐行读取 2.2 一次性读取整个文件 3. 写入文件内容 3.1 覆盖写入 3.2 追加写入 4. 文件测试操作 4.1 文件测试运算符 5. 文件路径操作 5.1 文件路径处理模块 5.2 获取文件路径信息 6. 文…