3. 医学文本预处理技术:从分词到实体边界识别
文本预处理是整个NLP管线的“地基”。处理新闻评论,通用分词器就够用。但碰到医生写的病历,用通用工具很容易翻车。我最早做医学文本处理时,踩过不少这方面的坑。
3.1 医学分词:领域专有工具才是正解
分词是中文处理的起点。通用工具(比如jieba、HanLP)对“肌酸激酶同工酶”这类长医学实体,几乎必错。它们会切成“肌酸/激酶/同工酶”甚至更碎。
我建议你优先考虑下面几个医学分词工具:
| 工具名称 | 特点 | 适合场景 |
|---|---|---|
| PySSP (Shenzhen) | 自带医学词典,支持多词性标注 | 中文电子病历、检验报告 |
| PKUSeg (医学版) | 北大开源,提供了医学领域预训练模型 | 药品说明书、医学论文摘要 |
| CCKS 评测词库 | 每年评测提供高质量医学词表 | 定制化项目,词典融合 |
| BERT + CRF (微调版) | 效果最好,但推理慢 | 对精度要求极高的场景 |
说白了,如果你只是做Demo,用jieba + 自定义医学词典也能顶一下。但要上线生产,我建议上PySSP或者微调一个BERT-CRF。我之前在一个药品不良反应项目里,用jieba切“盐酸肾上腺素注射液”,结果被切得七零八落,后处理代码写了快200行来补漏。换了PySSP之后,直接能正确分词,省了不少事。
# 使用 pkuseg 医学模型的示例
import pkuseg
seg = pkuseg.pkuseg(model_name='medicine')
text = '患者口服盐酸二甲双胍片后出现恶心症状'
seg_list = seg.cut(text)
print(seg_list)
# 输出: ['患者', '口服', '盐酸二甲双胍片', '后', '出现', '恶心', '症状']
3.2 词性标注:让模型知道名词和动词的区别
分完词,我们要给每个词打上词性标签。这步在药物实体关系抽取里尤其重要。
举个例子,“口服”是动词,“血压”是名词,“升高”是形容词/动词。模型如果不知道词性,很难判断“高血压”这个实体从哪开始。
我常用的词性标注方案:
- 北大数据集 (PKU POS):32个词性标签,对医学文本够用
- CTB (Chinese Treebank):更细粒度,但标注成本高
- 自定义医学词性标签:比如给“药品名”专门加个标签
pos_drug
这里有个坑要提醒你。中文医学文本里,“黄芪”在中医语境下是名词,但“黄芪片”这种组合,通用标注器可能标错。我在实际项目中,发现通用标注器会把“黄芪片”里的“片”标成量词 (q),从而导致后续实体边界判断出错。
嗯,所以我的习惯是:先用通用工具标一遍,再用医学专有词表做后修正。
# 使用 PySSP 进行词性标注
import pyssp
annotator = pyssp.PySSP()
text = '服用阿莫西林后出现皮疹'
result = annotator.pos_tag(text)
for token in result:
print(token.word, token.pos)
# 服用 v, 阿莫西林 n_drug, 后 p, 出现 v, 皮疹 n_symptom
n_drug、n_symptom 加进去,而不是让模型自己去猜。
3.3 句法分析:理清“谁修饰谁”
句法分析帮我们弄懂句子的结构。在药物关系抽取里,它特别适合处理长修饰关系。你想想看,“口服盐酸二甲双胍片患者的血糖水平显著降低”,这里面“血糖水平”是被“口服盐酸二甲双胍片”修饰的。句法依赖能把这种关系清晰的画出来。
常用方法有:
- 依存句法分析:画出一个词之间的“修饰树”。工具如 LTP、哈工大 LTP4
- 成分句法分析:生成短语结构树。工具如 Berkeley Parser
我更喜欢依存句法。因为它直接给出词对之间的“头-修饰”关系,这和我们抽实体关系时需要的“驱动词-实体”模式很接近。
为什么会这样?因为药物关系大多是一个动作(口服、注射、引起)连接两个实体(药品、症状)。依存句法能帮你快速定位动作词的修饰范围。
# 使用 LTP 进行依存句法分析(伪代码示例)
from ltp import LTP
ltp = LTP()
seg, hidden = ltp.seg(['口服盐酸二甲双胍片后血糖降低'])
dep = ltp.dep(hidden)
# 输出: 口服 -> 二甲双胍片 (dobj 关系)
# 降低 -> 血糖 (nsubj 关系)
3.4 实体边界识别:分词的“最后一公里”
实体边界识别,本质上是把分词后可能切错的医学实体再拼回来。很多医学实体由多个词复合而成,比如“慢性/阻塞性/肺疾病”。如果分词阶段没把它们合并成一个整体,后面做关系抽取就会出错。
我常用的方法有三类:
| 方法 | 原理 | 优点 | 局限 |
|---|---|---|---|
| 基于规则 | 用正则或词典匹配边界 | 快,零成本 | 覆盖率低,需要大量人工规则 |
| CRF (条件随机场) | 把边界识别当序列标注做 (BIO标注) | 效果稳定,适合医学文本 | 依赖人工特征工程 |
| 基于BERT | 利用预训练模型直接预测实体边界 | 效果最好,泛化强 | 需要标注数据,推理慢 |
我曾经在一个中文药物文本上测试过,结果发现边界不对。比如“盐酸肾上腺素注射液”,BERT+CRF直接给打成了“盐酸肾上腺/注射液”。后来我在标注数据里补充了几百条这种例子,重新训练后才修正过来。
3.5 本章流程总结:一个完整的预处理管线
下面这张图汇总了我平时搭建医学预处理管线的典型步骤。从原始文本输入,到经过分词、词性标注、句法分析、实体边界识别,最后输出结构化的、可供下游模型使用的数据。
在实际项目中,我推荐优先保障“分词”和“实体边界识别”这两个环节。词性标注和句法分析可以视情况降低要求——如果你的关系抽取模型是基于BERT微调的,那它内部其实已经隐含了句法信息,不一定需要显式的句法分析输出。