文本分割的方法
Table of Contents
长文本分割是构建高效检索系统的重要步骤,好的分割方法需要兼顾语义完整性和块大小适中。我们要避免简单的固定长度切分导致语义丢失的问题:
1. 基于句子分割
方法
使用自然语言处理工具将文本分割成句子,然后再组合成适当大小的块。
实现示例
import nltk
from nltk.tokenize import sent_tokenize
# 下载 punkt 分词器(首次运行需要)
nltk.download('punkt')
def split_text_by_sentences(text, chunk_size=300):
sentences = sent_tokenize(text)
chunks = []
current_chunk = ""
for sentence in sentences:
# 如果当前块加上新句子的长度超过 chunk_size,则开始新块
if len(current_chunk) + len(sentence) > chunk_size:
chunks.append(current_chunk.strip())
current_chunk = sentence
else:
current_chunk += " " + sentence
# 添加最后一个块
if current_chunk:
chunks.append(current_chunk.strip())
return chunks
# 示例使用
text_chunks = split_text_by_sentences(pdf_text, chunk_size=300)
print(f"分割后的块数: {len(text_chunks)}")
print(text_chunks[:3]) # 打印前 3 个块
2. 基于段落分割
方法
如果文本格式包含段落信息(如 PDF 提取结果),可以优先按照段落分割,确保块的语义完整性。
实现示例
def split_text_by_paragraphs(text, chunk_size=300):
paragraphs = text.split("\n\n") # 假设段落以双换行分隔
chunks = []
current_chunk = ""
for paragraph in paragraphs:
if len(current_chunk) + len(paragraph) > chunk_size:
chunks.append(current_chunk.strip())
current_chunk = paragraph
else:
current_chunk += " " + paragraph
if current_chunk:
chunks.append(current_chunk.strip())
return chunks
# 示例使用
text_chunks = split_text_by_paragraphs(pdf_text, chunk_size=300)
print(f"分割后的块数: {len(text_chunks)}")
print(text_chunks[:3]) # 打印前 3 个块
3. 滑动窗口法
方法
使用滑动窗口技术创建有重叠的块,保证查询时的上下文信息完整性。
实现示例
def sliding_window_split(text, chunk_size=300, overlap=50):
chunks = []
for i in range(0, len(text), chunk_size - overlap):
chunk = text[i:i + chunk_size]
chunks.append(chunk.strip())
return chunks
# 示例使用
text_chunks = sliding_window_split(pdf_text, chunk_size=300, overlap=50)
print(f"分割后的块数: {len(text_chunks)}")
print(text_chunks[:3]) # 打印前 3 个块
4. 基于文本分层分割
方法
如果文本格式复杂(如技术文档、论文),可以结合标题、章节等结构信息,优先按结构分割。
示例
def split_text_by_structure(text, chunk_size=300):
# 假设标题以 "## " 开头
sections = text.split("## ")
chunks = []
for section in sections:
if len(section) > chunk_size:
chunks.extend(sliding_window_split(section, chunk_size=chunk_size, overlap=50))
else:
chunks.append(section.strip())
return chunks
# 示例使用
structured_text = "## Introduction\nThis is the intro.\n## Methodology\nThis is the method section."
text_chunks = split_text_by_structure(structured_text, chunk_size=100)
print(f"分割后的块数: {len(text_chunks)}")
print(text_chunks) # 打印分割结果
5. 结合 NLP 工具的智能分割
方法
使用 NLP 工具(如 spaCy)按语义分割文本,例如按句子或语义段落进行分割。
实现示例
import spacy
# 加载 spaCy 模型
nlp = spacy.load("en_core_web_sm")
def split_text_by_semantics(text, chunk_size=300):
doc = nlp(text)
chunks = []
current_chunk = ""
for sentence in doc.sents:
if len(current_chunk) + len(sentence.text) > chunk_size:
chunks.append(current_chunk.strip())
current_chunk = sentence.text
else:
current_chunk += " " + sentence.text
if current_chunk:
chunks.append(current_chunk.strip())
return chunks
# 示例使用
text_chunks = split_text_by_semantics(pdf_text, chunk_size=300)
print(f"分割后的块数: {len(text_chunks)}")
print(text_chunks[:3]) # 打印前 3 个块
比较与选择
方法 | 优点 | 缺点 |
---|---|---|
句子分割 | 简单直观,语义完整 | 对长句子可能不够灵活 |
段落分割 | 保留段落语义 | 段落过长时需进一步分割 |
滑动窗口法 | 保证上下文信息完整 | 存在重复信息,可能增加存储成本 |
文本分层分割 | 适合结构化文本 | 依赖文本中有明显结构标记 |
NLP 智能分割 | 结合语义分析,效果更智能 | 需要加载 NLP 模型,速度较慢 |
最佳实践
- 如果文本语义结构较好(如技术文档、论文),优先基于段落或结构分割。
- 如果需要精确检索上下文,滑动窗口法 是很好的选择。
- 对通用场景,结合 NLP 工具的智能分割 是最强大的方法。
建议根据具体的文本内容选择合适的分割方法,同时可以结合分割方法优化 RAG 系统的性能!
Comments |0|
Category: 似水流年