常见的几种分块策略,每种策略都有适用场景和优缺点
关于医疗文档或长文本的分块策略(chunking strategies),在自然语言处理(特别是在处理医疗数据、问答系统、多轮对话等任务中)中,是非常关键的一步。分块策略决定了文本被切分成多少块、每块包含多少上下文信息,这会直接影响模型的表现。
以下是常见的几种 分块策略,每种策略都有适用场景和优缺点:
🧱 1. 固定窗口滑动(Fixed-size Sliding Window)
描述:
将文本按固定长度(比如 512 个 token)滑动切分,中间允许有重叠(如 50%)。
参数:
chunk_size
: 每块的最大长度stride
: 每次滑动的步长(stride < chunk_size 会产生重叠)
举例:
假设文本为 0~1000 tokens,chunk_size=100,stride=50:
chunk1: tokens 0~99
chunk2: tokens 50~149
chunk3: tokens 100~199
...
优点:
- 保留上下文连续性
- 适用于多模态任务或长文档摘要任务
缺点:
- 重叠增加了计算成本
- 可能出现重复回答或重复信息提取
📘 2. 按段落分块(Paragraph-based Chunking)
描述:
根据文本原始的段落、换行或标题结构进行切分,每段或每几段构成一个块。
场景:
- 医疗病历、科研报告、FAQ 等文档往往本身有结构,适合此方式。
优点:
- 保留自然语义结构,效果通常比固定窗口更自然
- 避免句子被截断
缺点:
- 块的长度可能不均匀(过短或过长)
- 某些段落可能信息密度低
🧩 3. 按句子分块(Sentence-based Chunking)
描述:
先用句子分割器(如 nltk.sent_tokenize
),再按一定数量组合成块。
示例:
假设每 3 句为一个块:
chunk1: sentence1 + sentence2 + sentence3
chunk2: sentence4 + sentence5 + sentence6
...
优点:
- 保证语义连贯
- 更适合问答任务或摘要任务
缺点:
- 句子长短不一,token 数量不好控制
- 可能需要动态裁剪
🧠 4. 基于语义边界的智能分块(Semantic-aware Chunking)
描述:
借助分句模型(如 spaCy、CoreNLP)或 embedding 计算,检测语义边界(如话题变化、主语变化)后分块。
方法:
- 对句子生成 embedding
- 相邻句子之间计算余弦相似度
- 相似度低时认为话题有变化,作为切分点
优点:
- 准确找到信息“转折点”
- 更适合用于知识检索、文档问答(RAG)
缺点:
- 实现复杂,计算开销大
⛓️ 5. 关键词驱动分块(Keyword-guided Chunking)
描述:
设定关键术语(如“诊断”、“用药”、“病史”),在这些关键词处切分文本。
应用场景:
- 医疗文本中存在固定模式,如“主诉”、“现病史”、“诊断意见”…
优点:
- 易于提取结构化信息
- 分块语义明确
缺点:
- 依赖规则或关键词库
- 对非标准格式的文本不适用
🧬 6. Token-aware Chunking(基于 tokenizer 分块)
描述:
结合模型 tokenizer(如 Tiktoken
或 transformers
tokenizer)进行 token-level 控制:
- 精确控制 token 数量不超过模型上限(如 512 或 4096)
- 避免半个单词被切掉
工具:
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
tokens = tokenizer(text)["input_ids"]
优点:
- 兼容所有模型
- 不会因字符切分而出错
✅ 实践推荐(针对医疗文档):
任务类型 | 推荐策略 |
---|---|
医疗实体识别 | 按句子或段落分块 |
医疗问答 / 摘要 | 滑动窗口 + 句子结构优化 |
检索增强生成 RAG | 按语义边界/关键词分块 |
医疗知识图谱构建 | 按段落或关键词提取为节点信息 |