数据源调研 — 摸清家底才能干活
做知识图谱,第一件事不是写代码,是搞清楚数据从哪来。我个人习惯先把所有可能用的数据源列出来,然后一个一个试,看看质量、更新频率、接口好不好用。说实话,这一步被很多人跳过,结果后面清洗到一半发现字段对不上、缺数据,整个重来。
这一章我们就聊聊常用的药品数据库、临床数据、以及文献全文。你想想看,这些来源的特点完全不同,融合的时候必须心里有数。
为什么数据源调研这么重要
我在项目里见过最惨的一次:团队花了三个月写代码,把 DrugBank 和 PubChem 的数据合并到一张表里,结果发现 PubChem 里化合物的 SDF 结构字段在 DrugBank 里根本不存在,而且两者对“药物靶点”的定义不一样。为啥?因为没提前调研数据模型。
说白了,调研阶段就是给你自己打预防针。知道哪个字段可能缺失、哪个接口有速率限制、哪个数据需要处理同义词,后面做清洗就能少走弯路。
四大类数据源一图览
下面这个图是我自己画的数据源调研框架,每次做新项目都会先对着它过一遍。
药品数据库三巨头
对做药物图谱来说,DrugBank、PubChem 和 CTD 是绕不开的三个库。我一个个说。
DrugBank — 药物领域的维基百科
DrugBank 是目前最权威的药物数据库之一,不仅包含药物分子信息,还有靶点、通路、给药途径、副作用等。我个人特别喜欢它的靶点-药物关联,清洗时可以直接拿来当标准正例。
它的 XML 导出文件结构很清晰,我一般是先解析成表再入库。核心字段大概长这样:
| 字段 | 说明 | 示例 |
|---|---|---|
| drugbank-id | 唯一标识 | DB00001 |
| name | 药物名称 | Leuprolide |
| type | 类型(small_molecule / biotech) | biotech |
| targets | 靶点列表(JSON) | [{"id":"BE0001","name":"GNRHR"}] |
| cpd | 计算化学性质 | {"logP":3.2,"mw":500.6} |
PubChem — 化合物宇宙
PubChem 是老大哥,化合物数量超过 1 亿。它的 REST API 很好用,我经常直接写脚本调取。
举个例子,查阿司匹林的 CID:
curl -X GET "https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/aspirin/property/MolecularFormula,MolecularWeight,InChIKey/JSON"
返回的 JSON 干净省心:
{
"PropertyTable": {
"Properties": [
{
"CID": 2244,
"MolecularFormula": "C9H8O4",
"MolecularWeight": 180.16,
"InChIKey": "BSYNRYMUTXBXSQ-UHFFFAOYSA-N"
}
]
}
}
我在项目里用 PubChem 做药物成分标准化,因为它覆盖全,而且有标准 InChIKey,对齐起来特别准。不过要注意 API 有速率限制,爬大量数据时记得加延时。
CTD — 化学物-基因-疾病的三角关系
CTD (Comparative Toxicogenomics Database) 的核心价值在于它把化学物、基因和疾病三者的关联都整理好了。说白了,你想知道“阿司匹林影响哪个基因,这个基因又和什么病有关”,CTD 直接给你表。
它的数据以 TSV 形式提供,下载后直接导入数据库。字段包括 ChemicalName、GeneSymbol、DiseaseName、ReferenceCount 等。我遇到过一个问题:CTD 里的化学名不是标准名,需要和 PubChem 做映射。嗯,这又是另一道清洗工序。
临床数据 — 真实世界的金矿
药品数据库再全,也只是体外表征。真正能反映药物效果和副作用的是临床数据。包括电子病历(EHR)、临床试验结果、以及真实世界数据(RWD)。
但临床数据有个老大难问题:隐私。我曾在一个项目中尝试爬取公开的临床试验结果(ClinicalTrials.gov),发现里面虽然脱敏了,但字段非常稀疏,很多试验只报了顶线结果,没有个体级数据。这时我通常会结合文献全文来补细节。
另外,电子病历如果拿不到结构化数据,就只能靠 NLP 从文本中抽。我之前用过一个开源工具 MedSpacy,效果还不错,但速度慢。一般来说,临床数据我只在内部项目用,对外发布的图谱很少直接用 EHR,因为合规风险高。
文献全文数据 — 大海捞针
文献全文是知识图谱的“增量知识源”。新发现的药物-靶点关系、不良反应报道、老药新用,通常先出现在论文里。
常用来源:
- PubMed:摘要免费,全文不一定。我会用 Entrez API 批量拉取 PMID 和摘要。
- PMC:开放获取全文库,可以直接下载 XML 格式,解析后做 NER。
- 预印本:如 medRxiv、bioRxiv,信息更新更快但质量参差不齐。
但全文数据噪音大,图表里的描述词、参考文献列表需要过滤。我一般先用句子边界检测切分,然后只拿包含药物名称的句子喂给关系抽取模型。
数据源选择策略
当你面对多个数据源,怎么选?我做了个对照表,每次调研时直接套用:
| 数据源 | 覆盖范围 | 更新频率 | 接口限制 | 推荐用途 |
|---|---|---|---|---|
| DrugBank | ~15k 药物,~5k 靶点 | 每年 2-3 次 | 学术免费下载,无速率限制 | 药物-靶点标准关系 |
| PubChem | >1亿 化合物 | 每日更新 | 5次/秒 | 化合物属性、结构对齐 |
| CTD | ~2万 化学物,~7万 基因 | 每月更新 | TSV下载无限制 | 化学-基因-疾病三角关联 |
| ClinicalTrials.gov | ~50万 试验 | 每周更新 | REST API 无限制但请求量大限 | 药物-不良反应、试验结果 |
| PubMed/PMC | ~3500万 摘要,~800万 全文 | 每日更新 | Entrez API 3次/秒 | 新发现、关系抽取 |
我自己做项目时,首选 DrugBank + PubChem 作为骨架,再视场景补充 CTD 或临床数据。文献全文一般只在做前沿挖掘时加进去。
避坑指南 — 我踩过的那些坑
- ID 不通用:DrugBank ID 和 PubChem CID 和 CHEBI ID 完全不同,融合前一定要建映射表。我曾经直接拿名称做 join,结果同义词对不上,数据丢了三分之一。
- 版本陷阱:不同时间下载的数据版本可能不同。我建议每次下载都记录日期和版本号,在融合时带上数据源版本标签。
- 接口变化:PubChem API 在 2022 年改过一次返回格式,老脚本直接崩溃。定期检查接口文档,或者给我自己写的爬虫加监控。
- 数据重复:同一个药物可能在多个来源出现,但名称写法不同(比如“Aspirin” vs “Acetylsalicylic acid”)。不处理重复,图谱就乱。我习惯用 InChIKey 作为第一候选去重字段。
- 许可证问题:前面提到了,DrugBank 商业版要钱,CTD 是 CC BY 许可证。先看清条款再开工,不然后面发不出论文。