药物数据源概览:公开数据库、文献与临床试验

做知识图谱的第一步是什么?搞数据。

说白了,没有优质的数据源,后面所有的对齐、融合、推理都是空中楼阁。我自己踩过这个坑——早期想偷懒,只从单一数据库抓数据,结果图谱建成后查一个药,连靶点信息都拼不全,简直没法用。

这一章咱们就把主流的药物数据源捋一遍。你不需要背下所有API参数,但得知道每个库擅长什么、数据长什么样、怎么拿到手。

核心原则: 多源互补。单一库覆盖率有限,至少融合3~5个权威数据源,才能支撑起一个有实际价值的药物知识图谱。

公开数据库一览

先上一张总览图,你看一眼就知道各个库在知识图谱里的定位。

药物数据源总览(知识图谱视角) 药物知识图谱 多源融合层 🔵 DrugBank 药物-靶点-通路 🔴 PubMed 文献摘要 · 术语 🟣 CTD 化学-疾病关联 🟠 UniProt 蛋白质功能 · 序列 🟢 ClinicalTrials.gov 临床试验状态/结果 🔵 ChEMBL 活性数据 · IC50 💡 说明 结构数据(DrugBank/PubMed/CTD)提供实体与关系,分子数据(UniProt/ChEMBL)提供属性与活性, 临床数据(ClinicalTrials.gov)提供验证与时效。三者缺一不可。

DrugBank —— 药物核心知识库

DrugBank号称药物界的维基百科。它收录了超过1.3万个药物实体(包括获批药、实验药、中药),每个药物都关联了靶点、酶、载体、代谢产物、通路。

我一般用它的XML格式全量导出,做图谱的三元组抽取。举个例子:

<drug type="biotech">
  <drugbank-id primary="true">DB00001</drugbank-id>
  <name>Lepirudin</name>
  <targets>
    <target position="1">
      <id>BE0000005</id>
      <name>Thrombin</name>
      <actions>
        <action>inhibitor</action>
      </actions>
    </target>
  </targets>
</drug>
小技巧: 不要直接用XML解析库暴力加载全量文件(2GB+),我习惯用 xml.etree.ElementTree.iterparse 流式解析,只抽取目标标签,内存占用能降到200MB以内。

另外,DrugBank也提供REST API,适合小批量查询。我个人测过,每秒5个请求比较稳妥,超了容易被限流。

PubMed —— 文献中挖关系

PubMed有超过3500万篇生物医学文献摘要。它的价值在于:很多药物-疾病新关联、不良反应、联合用药信息都藏在文献里,还没被结构化数据库收录。

我建议你用PubMed的E-utilities API批量拉取。核心流程是三步:先搜 esearch 拿到PMIDs,再用 efetch 拉XML,最后用正则或SPARQL抽取实体关系。

# 第一步:搜索
curl "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=pubmed&term=metformin+liver+cancer&retmax=100"

# 第二步:获取摘要XML
curl "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&id=34567890,34567891&retmode=xml"
避坑: 我曾经一次性发1000个并发请求,直接被NCBI封IP三天。后来改成每秒3个请求,加上重试机制,才稳定跑完。记得遵守官方频率限制(默认3次/秒,允许API key后10次/秒)。

CTD(比较毒理基因组学数据库)

CTD整理的是化学物质与基因、疾病之间的三元组关联,而且带有置信度标注(inferred vs. curated)。它对药物安全性知识图谱很有用。

数据下载是制表符分隔的文本,一行一个关联:

ChemicalName     DiseaseName     DirectEvidence
Acetaminophen    Liver Injury    T
Valproic Acid    Neural Tube Defects    T
Ibuprofen        Acute Kidney Injury    marker/mechanism

我一般直接用pandas读,按chemical和disease做count后建立关联权重,再导入Neo4j。

UniProt —— 蛋白质细节补全

当你在DrugBank里拿到靶点ID后,需要去UniProt补全蛋白质的序列、功能描述、互作网络。UniProt的SPARQL端点可以直接查询:

PREFIX up: <http://purl.uniprot.org/core/>
SELECT ?protein ?name ?seq
WHERE {
  ?protein up:mnemonic "THRB_HUMAN" .
  ?protein up:fullName ?name .
  ?protein up:sequence ?seq .
}

结果是个JSON,解析后可以塞进图谱的节点属性里。

ClinicalTrials.gov —— 临床试验状态

药物到底有没有进展?临床几期?副作用频率多少?这些信息在ClinicalTrials.gov上最权威。它提供AACT数据库(MySQL备份),也可以直接用API搜索。

我常用的参数组合:

https://clinicaltrials.gov/api/query/study_fields?expr=metformin&fields=NCTId,BriefTitle,OverallStatus,Phase&min_rnk=1&max_rnk=20

返回是XML格式,直接拉解析就行。注意 OverallStatus 字段可以反映药物退市风险,这是图谱时效性的关键。

数据源对比总结

数据源 主要用途 数据格式 获取方式 推荐频次
DrugBank 药物-靶点-通路三元组 XML / JSON 全量下载 / REST API 每月更新
PubMed 药物-疾病新关联抽取 XML / TXT E-utilities API 持续增量
CTD 化学-疾病关联+证据 TSV / CSV 全量下载 每季度
UniProt 蛋白质属性补全 RDF / JSON SPARQL / FTP 每季度
ClinicalTrials.gov 临床阶段与安全性 XML / CSV AACT / API 每周
ChEMBL 化合物活性数据(IC50, Ki) SDF / TSV / RDF 全量下载 / 接口 每月

文献与临床试验数据的特殊性

结构化的数据库好处理,但文献和临床试验数据才是图谱价值的放大器。为什么?

  • 文献:用自然语言描述的因果关系、不良反应、药物联用,是结构化数据库的补充。你需要用NER(如tmChem、BioBERT)+ RE(关系抽取)来转换成三元组。
  • 临床试验:除了结构化的phase、enrollment,还有Outcome Measures和Adverse Events表格,这些可以用来构建药物-不良反应边,并带上发生频率属性。
个人经验: 在做不良反应图谱时,仅靠DrugBank的副作用字段(只有2000多种相关关系)远远不够。我整合了CTD的chemical-disease关联(约200万条)和ClinicalTrials.gov的不良事件日志,才把覆盖率提升到80%以上。

一个小提醒:数据版本管理

不同数据源的更新节奏不同,你不可能每次重爬全量。我建议这样管理:

data/
  drugbank/
    v5.1.12/   ← 2024-01 全量XML
    v5.1.13/   ← 2024-04 增量补丁
  pubmed/
    daily_2024-06-01.csv
    daily_2024-06-02.csv
  ctd/
    v2024Q1/   ← 每季度
  clinical_trials/
    weekly_2024-06-01.xml

每条记录带上source和version标签,图谱中才能追溯数据时效。我曾经遇到过一个案例:某药物在2023年已退市,但陈旧数据在图谱中仍标记为“上市”,差点误导了合作方。从那以后,数据版本字段成了我的硬性要求。