文本如何做分块

在RAG中,最重要的就是把内容进行分块,向量化,存到向量数据库里面。RAG检索结果的准确度主要还是要看内容分块是否合理。

本章我们主要介绍下文本切块(chunking)的几种方式。

方式 1:固定长度切


 做法:每 N 个字符/词一刀切。

 优点:无脑快,代码 3 行搞定。

 缺点:容易把句子拦腰斩断,“北京大学”切成“北京+大学”,语义全断,自然处理效果就不会很好。

方式2:滑动窗口切(overlap)
 

做法:每 N 个词后回退 M 个词再切,像卷尺量两次。按照一个窗口一样往前滑动。

优点:减少断句,提高召回率。

缺点:块数翻倍,存储和检索成本大大滴高。目前我在工作中没咋用这种形式。

方式 3:按句子切(句号、换行)

做法:按 。!?\n 等能够明确的区分段落,完整句子的标识进行分割。

优点:语义完整,适合短问答。

缺点:句子太长或太短都不好;超长句子仍需二次切。主要还是向量化算法要求的token有限。

普通 BGE(bge-base/large-zh-v1.5 等)默认最多 512 token
新一代 BGE-M3 最长支持 8192 token
BGE 家族现在有两代产品:

  1. 第一代的 bge-base-zh-v1.5、bge-large-zh-v1.5 等,基于 BERT 类架构,训练时就固定了 512 token 的输入窗口。我们工作中用的就是bge-large-zh-v1.5这个版本。

  2. 2024 年发布的 BGE-M3

### 文本分块方法概述 文本分块是指将较长的文本划分为较小的部分,以便更好地处理和分析。当前主流的文本分块方法主要包括基于规则的文本分块、内容感知分块、结构感知分块以及基于语义嵌入的分块。 #### 基于规则的文本分块 这种方法通过设定固定的字符数或token数目来切割文本,通常会指定`chunk_size`(每一块的最大长度)和`chunk_overlap`(相邻块间的重叠部分),以保持上下文连贯性[^1]。对于不需要复杂自然语言理解的任务来说,这种方式简单有效且资源消耗少。 ```python from langchain.text_splitter import CharacterTextSplitter splitter = CharacterTextSplitter(separator="\n", chunk_size=100, chunk_overlap=20) chunks = splitter.split_text(long_document_string) ``` 此代码展示了如何利用LangChain框架下的`CharacterTextSplitter`类来进行简单的基于字符计数的文本分割操作[^2]。 #### 内容感知分块 不同于机械地依据预设尺寸裁剪材料,此类技术着眼于识别并尊重文章内部逻辑边界——比如句子结束处或是段落转换之际作为断点位置。这往往借助专门设计的语言处理软件包完成,像NLTK或者spaCy这样的开源项目提供了强大的支持功能用于发现合适的分裂点。 #### 结构感知分块 当面对具备清晰层次架构的数据源时,如HTML网页或Markdown文件,则可采取更为精细的办法对其进行剖析。这类算法能够识别人工编写的标记信息,并据此指导怎样合理分配各个组成部分到独立片段之中。 #### 递归分块 这是一种特别适合处理超大型文档的技术路径。它先依照初步准则把整体分解成若干子集;随后检查所得单元是否满足预定条件;倘若未达标便继续细分直至达到理想状态为止。 #### 基于语义Embedding分块 该方案试图超越表面形式上的相似度考量而深入探讨意义层面的一致性问题。通过构建向量空间表示法捕捉词语间潜在关联模式之后,再运用聚类或其他机器学习手段找出最佳匹配组合形成最终结果集合[^3]。 ### 实现示例 下面是一个使用Python编程语言配合LangChain库执行不同类型文本划分的具体实例: ```python import spacy from langchain.text_splitter import RecursiveCharacterTextSplitter # 加载SpaCy模型准备更高级别的文本处理工作 nlp_model = spacy.load('en_core_web_sm') def custom_chunker(text): doc = nlp_model(text) # 定制化函数可以根据实际需求调整参数配置 splitter = RecursiveCharacterTextSplitter( separators=["\n\n", "\n", " ", ""], chunk_size=500, chunk_overlap=50 ) chunks = [] for sent in list(doc.sents): sub_chunks = splitter.split_text(sent.text_with_ws) chunks.extend(sub_chunks) return chunks long_text = """这里是一篇很长的文章...""" result = custom_chunker(long_text) print(result[:5]) # 打印前五个分片查看效果 ``` 上述脚本首先加载了一个英语版本的小型SpaCy NLP管道,接着定义了名为`custom_chunker()`的新函数负责接收待加工字符串输入并通过调用内置API获得经过标注后的对象表达式。最后采用循环迭代遍历每一个句子节点并将它们传递给自定义创建的对象进行进一步细化处理得到目标输出列表。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值