第2章 医学文本数据源分析
做药物实体关系抽取,第一步就是找对数据。数据选错了,模型再牛也白搭。我个人习惯先把常见的医学文本数据源摸透——PubMed摘要、临床记录、药品说明书、FDA标签、还有医学文献。每个源都有自己的脾气。
一句话总结:PubMed摘要适合预训练和远监督;临床记录语料珍贵但获取门槛高;说明书和FDA标签结构化好,适合做评测集;医学文献是高质量标注数据的来源。
2.1 五种数据源对比
| 数据源 | 特点 | 典型大小 | 标注可用性 | 获取难度 |
|---|---|---|---|---|
| PubMed摘要 | 短文本、领域广、更新快 | 3500万+ | 远监督噪声大 | ⭐ 简单(API/BioBERT) |
| 临床记录 | 长文本、缩写多、隐私受限 | 百万级(院内) | 需标注 | ⭐⭐⭐⭐ 极高(MIMIC-III需申请) |
| 药品说明书 | 结构化半结构化、条款明确 | 数万种 | 可自动标注 | ⭐⭐ 中等(DailyMed/SPL) |
| FDA标签 | 监管级、包含不良反应 | 约10万份 | 结构化字段 | ⭐⭐ 中等(OpenFDA) |
| 医学文献全文 | 长上下文、方法结果详细 | 数百万篇 | 需人工标注 | ⭐⭐⭐ 较高(PMC OA) |
2.2 各数据源深入解读
2.2.1 PubMed摘要
你想想看,PubMed里3500万条摘要,随便拉出来就能做关系抽取的远监督。但注意——摘要很短,平均200-300词,实体共现不一定代表真实关系。我在项目中遇到过用PubMed远监督做Drug-Drug Interaction抽取,结果噪声率超过40%。避坑指南:我后来加了规则过滤和置信度阈值,才把F1从0.55提到0.68。
获取方式很简单:用Biopython的Entrez模块或官网API。举个代码片段:
from Bio import Entrez
Entrez.email = "your@email.com"
handle = Entrez.esearch(db="pubmed", term="drug interaction", retmax=100)
record = Entrez.read(handle)
id_list = record["IdList"]
# 然后用 efetch 拿摘要XML
2.2.2 临床记录
临床记录是真正的"黄金数据"——里面有真实的患者-药物-不良反应关系。但获取门槛很高。最常用的是MIMIC-III/IV,你需要通过CITI数据保护培训,签署协议才能下载。
这类文本的特点:大量缩写("QD"表示每日一次)、拼写错误、半结构化(SOAP格式)。我曾经处理一份记录,里面"metformin 500mg"和"Metformin 500 mg"同时出现——同一种药两个拼法。所以预处理阶段要归一化。
⚠️ 隐私红线:千万别在公开数据集里出现患者ID、日期、地名。所有临床记录必须去标识化后再用于模型训练。
2.2.3 药品说明书 & FDA标签
这两个可以放一起说。说明书通常来自DailyMed(SPL格式),FDA标签来自OpenFDA。它们高度结构化:有"适应症"、"不良反应"、"药物相互作用"等明确章节。模型很容易在这些章节里做关系抽取——因为上下文已经帮你把关系类型暗示好了。
比如药品说明书里"药物相互作用"一节,几乎每句话都是一个DDI关系对。获取方式:
# OpenFDA 示例:获取某种药物的标签 JSON
GET https://api.fda.gov/drug/label.json?search=active_ingredient:metformin&limit=1
# 返回中包含 drug_interactions 字段
2.2.4 医学文献全文
PMC(PubMed Central)提供开放获取全文,格式是XML,包含段落、表格。这是做精细关系抽取的好材料——比如从"方法"部分抽实体,从"结果"部分抽关系。但全文很长,需要滑窗或分段。我建议先做段落级别的预筛选,只保留包含两个候选实体的段落,再跑模型,否则计算量太大。
2.3 数据源选择策略
为什么要对比这些?因为实际项目里没那么多钱买全部数据。我列个选择流程:
- 起步阶段:用PubMed摘要 + 远监督构建种子集,快速验证模型可行性。
- 提升阶段:加入说明书和FDA标签,用结构化信息做数据增强或作为评测集。
- 精细阶段:申请临床记录(如MIMIC),或者自己标注少量医学文献全文,提升领域内准确率。
💡 一个小经验:我做过一个药物-副作用抽取项目,先用PubMed摘要跑了远监督,结果召回高但精度极低。后来我拿了1000篇说明书里"不良反应"章节的句子做种子,效果直接翻倍。所以说明书数据往往被低估了。
2.4 数据获取实务
上面讲了理论,下面直接上命令。我个人常用的几个获取渠道:
📦 获取清单
- PubMed摘要:
pip install biopython+ Entrez API,或直接用BioBERT预处理好的压缩包 - MIMIC临床记录: 去physionet.org申请,需要签名(一般2周内获批),然后下载CSV/JSON
- 药品说明书(SPL): DailyMed官网直接下载全部SPL包(约2GB)
- FDA标签: OpenFDA API免费,限制10次/秒,批量建议用数据导出dump
- PMC全文: FTP访问 ftp.ncbi.nlm.nih.gov/pub/pmc/ ,XML包按年打包
嗯,这里要提醒:别在未批准的情况下爬PubMed全量,会被封IP。用官方API或者用别人已经整理好的数据集更稳妥。我记得有一次图省事直接爬,结果第二天IP黑了,后来老老实实走API。
2.5 避坑汇总
- 数据泄露: 临床记录里经常出现患者名字缩写,记得用NLM的deid工具清洗
- 关系偏移: PubMed摘要里的共现实体可能只是“在同一篇文献里提及”,不一定是关系——远监督要加过滤
- 版本不一致: 药品说明书经常更新,同一个药不同年份的说明书“不良反应”内容可能不同,做评测集要固定版本日期
- 解析难题: SPL文件是XML嵌套很深,我用lxml写了个专门解析函数,你们也可以直接用simpleSPL库
数据源选好了,后面章节就可以开始讲预处理和标注了。先把数据拿到手,别急着跑模型——数据质量决定了最终效果的上限。