药物图谱数据来源:公开数据库

这一章我们聊聊数据从哪来。你可能以为做药物图谱对齐,最难的是算法本身。其实我这些年踩过最多的坑,反而是数据源的问题。数据不好,再牛的模型也白搭。

公开数据库是药物图谱的根基。我个人习惯把它们分成三大类:药物专库、化学-基因交叉库、副作用信息库。每个库都有自己的脾气,摸透了才能用好。

DrugBank:药物数据的“维基百科”

DrugBank 是我最先接触的数据库。说白了,它就是药物领域的百科全书。不仅有药物的化学结构,还包含了靶点、代谢酶、转运体、药物相互作用等核心信息。

我刚开始做图谱时,第一个想到的就是它。为什么?因为它够全,够权威。截至最新版,DrugBank 收录了超过 15000 种药物条目,其中 FDA 批准的就有 2600 多种。

它的核心字段很清晰:

  • DrugBank ID:唯一标识,比如 DB00001
  • 通用名/商品名:用于名称对齐
  • 靶点列表:蛋白质靶点信息
  • 药物相互作用:DDI 数据
  • ATC 编码:解剖学治疗学分类
使用建议:DrugBank 提供 XML 和 API 两种获取方式。我建议优先用 API,因为 XML 数据量大,解析容易出错。我在项目中遇到过 XML 嵌套结构解析失败的问题,后来改用 API 清爽多了。

获取 DrugBank 数据的一个 API 示例:

GET https://api.drugbank.com/drugs/DB00001
Authorization: Bearer YOUR_API_KEY

Response (简化):
{
  "drugbank_id": "DB00001",
  "name": "Leptirudin",
  "type": "biotech",
  "targets": [
    {
      "id": "BE00001",
      "name": "Thrombin",
      "action": "inhibitor"
    }
  ],
  "drug_interactions": [...]
}

CTD:化学-基因-疾病的桥梁

CTD(Comparative Toxicogenomics Database) 是另一个宝藏。它不像 DrugBank 那样只关注药物本身,而是把化学物质、基因和疾病串起来了。

你想想看,药物图谱不仅要对齐药物名,还得对齐基因名、疾病名。CTD 在这方面的数据,是我见过最完整的。它收录了超过 200 万条化学-基因相互作用,以及 100 多万条化学-疾病关联。

CTD 的核心数据表:

数据类别 字段说明 对齐价值
Chemical-Gene Interactions 化学物质、基因符号、相互作用类型 帮助对齐化学名和基因名
Chemical-Disease Associations 化学物质、疾病名、关联证据 对齐化学名和疾病名
Gene-Disease Associations 基因符号、疾病名、关联类型 对齐基因名和疾病名

CTD 的数据下载下来是 TSV 格式,解析起来很方便。我曾经用它做过一个化学物质-疾病关系的实体对齐任务,效果出奇得好。因为它的数据是人工标注的,质量很高。

CTD 数据片段示例: 化学物质标识符 D003042(咖啡因)与疾病“帕金森病”存在关联,证据来自 PubMed 文献。这个关联在 CTD 里被标记为“治疗”关系。

SIDER:药物副作用的“信号灯”

SIDER(Side Effect Resource) 是专门做药物副作用的数据库。它从公开的 FDA 标签和文献中提取副作用信息,覆盖面相当广。

数据拿到手就完事了?其实不是。SIDER 的数据有个特点:副作用名称来自 MedDRA 术语库,而药物名来自 PubChem。这就涉及两个词表的对齐。

我在做这个库的时候,踩过一个坑:SIDER 里同一个药物可能有多个名称变体。比如“阿司匹林”可能是“Aspirin”,也可能是“Acetylsalicylic acid”。如果不做实体对齐,图谱里就会有重复节点。

SIDER 的数据结构:

# SIDER 药物-副作用关联数据示例
drug_name    side_effect       frequency
Aspirin      Nausea            frequent
Aspirin      Gastric ulcer     rare
Ibuprofen    Headache          common
Ibuprofen    Dizziness         uncommon
注意:SIDER 的数据是文本挖掘出来的,噪音比较多。比如“Nausea”和“Nauseous”可能被当成两个不同的实体。我建议拿到数据后先用 MedDRA 层级结构做一次归一化。

其他值得关注的公开数据库

除了上面三个,还有几个库我觉得很有用:

  • UniProt/Swiss-Prot:蛋白质靶点数据,用于对齐基因名和蛋白质名
  • PharmGKB:药物基因组学数据,包含基因型-药物反应关联
  • DGIdb:药物-基因相互作用数据库,整合了多种来源
  • PubChem:化合物数据库,提供化学结构的统一标识

常见数据挑战和应对思路

数据多了,问题也来了。我罗列几个常见情况:

  1. 命名不统一:同一个药物在不同库可能用不同名字。比如“扑热息痛”在 DrugBank 叫“Acetaminophen”,在 SIDER 叫“Paracetamol”。
  2. ID 映射缺失:有些库没有提供跨库 ID 映射,需要手动桥接。
  3. 数据版本不一致:不同库的更新频率不同,对齐时可能碰到过期数据。
  4. 冗余和冲突:同一个关系在不同库里有不同的描述方式。

嗯,遇到这些问题别慌。我的建议是先做一次全量 ID 映射,把 DrugBank ID、PubChem CID、ChEBI ID、UniProt ID 这些统一起来。然后基于映射结果去去重。

# 伪代码:ID 映射流程
mapping_dict = {}
for drug in drugbank_data:
    pubchem_cid = lookup_pubchem(drug.name)
    mapping_dict[drug.drugbank_id] = pubchem_cid
    mapping_dict[drug.name] = pubchem_cid

# 统一后,实体对齐就简单多了
药物图谱数据来源概览 DrugBank CTD SIDER 实体对齐任务 药物-靶点关联 药物-疾病关联 药物相互作用 核心挑战 命名不统一 → ID 映射缺失 → 跨库版本不一致

这张图展示了数据源和下游任务的关系。虚线箭头是提醒你:数据拿过来不是直接用的,中间得做实体对齐这把关键工序。

实战:数据预处理流程

最后,我分享一下我的标准预处理流程。不管用哪个库,这个流程基本通用:

  1. 下载原始数据:从各数据库官网获取最新版本
  2. 提取核心字段:只保留对齐所需的最小字段集
  3. ID 标准化:统一使用 PubChem CID 或 DrugBank ID 作为主键
  4. 名称归一化:统一大小写、去除空格、处理同义词
  5. 跨库关联:基于 ID 映射表,把不同源的数据串起来
  6. 质量校验:检查是否有缺失、重复、冲突的数据

这个流程听起来简单,但每个步骤都有坑。尤其是名称归一化这一步,我曾经因为没处理好连字符导致上千条记录匹配失败。所以,细节决定成败。