第2章 生物医药数据源介绍:DrugBank、UniProt、KEGG等

做知识图谱,你得先搞清楚“数据从哪来”。

我刚入行那会,觉得只要会写代码、会搭图数据库就行。结果第一个项目就栽了跟头——图谱搭好了,但里面的实体和关系全对不上。为什么?因为数据源本身就有问题。

这一章,我带你过一遍生物医药领域最常用的几个公开数据库。你不必全记住,但得知道每个库的脾气、特长、以及我踩过的坑。

2.1 DrugBank:药物数据的“权威字典”

DrugBank(https://go.drugbank.com)是目前最全的开源药物与靶点数据库。它由加拿大阿尔伯塔大学维护,每年更新两次。说起这个库,我最开始用的时候真是又爱又恨。

2.1.1 核心特点

  • 数据覆盖广:超过16,000种药物条目,包括FDA批准的小分子药物、生物药、以及实验阶段的候选化合物。
  • 靶点信息丰富:每个药物条目都会列出靶点蛋白、作用机制、代谢酶、转运体等关联信息。
  • 结构化程度高:提供XML和JSON格式下载,方便批量处理。

2.1.2 数据分层与典型字段

DrugBank的数据分三层:药物层、靶点层、交互层。我习惯用它的XML版本做知识图谱的实体抽取。

DrugBank XML结构示例(简化):
<drugbank xmlns="http://www.drugbank.ca">
  <drug type="biotech">
    <drugbank-id primary="true">DB00001</drugbank-id>
    <name>Lepirudin</name>
    <description>A recombinant hirudin...</description>
    <targets>
      <target>
        <id>BE0000115</id>
        <name>Thrombin</name>
        <organism>Human</organism>
        <actions>
          <action>inhibitor</action>
        </actions>
      </target>
    </targets>
  </drug>
</drugbank>

我个人习惯把drugbank-id作为药物实体的唯一标识,把targets节点下的信息展开成“药物-抑制/激活-靶点”这样的关系。

我的实战经验:DrugBank的XML文件很大(完整版约1.5GB),千万不要用DOM方式一次性解析。用SAX或者Streaming API逐行读取,否则内存很容易爆掉。
我曾经在笔记本上跑一次解析用了4个小时还没出结果,后来改用lxml.iterparse(),15分钟搞定。

2.1.3 常用字段映射表

概念 XML路径 说明 图谱中角色
药物ID /drugbank/drug/drugbank-id[@primary="true"] 主键标识 实体ID
药物名称 /drugbank/drug/name 通用名 实体标签
药物类型 /drugbank/drug/@type small_molecule或biotech 实体类别
靶点蛋白ID /drugbank/drug/targets/target/id 内部ID,需映射到UniProt 关联节点标识
作用类型 /drugbank/drug/targets/target/actions/action inhibitor, agonist, antagonist等 边类型/关系
避坑提醒:DrugBank的靶点ID并不是UniProt ID,而是它自己的内部编号。你需要通过/drugbank/drug/targets/target/polypeptide/@id找到UniProt的映射关系。
我曾经直接拿DrugBank靶点ID去查UniProt,结果发现根本查不到,后来才意识到中间还有一个映射步骤。

2.2 UniProt:蛋白质信息的终极“户口本”

UniProt(Universal Protein Resource)是全世界最权威的蛋白质序列与功能数据库。说白了,你要查一个蛋白的基本信息,翻UniProt准没错。

它有两个核心子库:

  • Swiss-Prot:人工校验,质量高,但覆盖少(约57万条)。
  • TrEMBL:自动注释,数据量大(约2.5亿条),但可能有错误。

2.2.1 为什么知识图谱要用UniProt?

在药物靶点知识图谱中,蛋白是连接药物和基因的关键桥梁。DrugBank只说“这个药作用于某个靶点”,但靶点的序列、结构域、相关疾病、基因名称,都得靠UniProt补齐。

我建议你在图谱中直接把UniProt ID作为蛋白实体的主键。原因很简单:它是跨数据库的“通用语言”。

2.2.2 数据下载与解析

UniProt提供多种格式:

  • XML:结构清晰,适合解析。
  • Flat File(.dat):体积最小,但解析起来比较麻烦。
  • JSON:逐渐成为主流,也推荐你使用。
UniProt JSON格式示例(核心字段):
{
  "entryType": "UniProtKB_Swiss-Prot",
  "primaryAccession": "P68871",
  "uniProtkbId": "HBB_HUMAN",
  "proteinDescription": {
    "recommendedName": {
      "fullName": {
        "value": "Hemoglobin subunit beta"
      }
    }
  },
  "genes": [
    {
      "geneName": {
        "value": "HBB"
      }
    }
  ],
  "organism": {
    "scientificName": "Homo sapiens",
    "taxonId": 9606
  }
}

嗯,这里要注意:UniProt的JSON API有流量限制。如果你要批量下载成千上万个蛋白,别用REST API一个个请求,去它的FTP服务器下完整数据集才是正道。

# 下载完整版Swiss-Prot的XML文件(2024年9月版)
wget ftp://ftp.uniprot.org/pub/databases/uniprot/current_release/knowledgebase/complete/uniprot_sprot.xml.gz
gunzip uniprot_sprot.xml.gz
我的小技巧:解析Uniprot XML时,重点关注<comment type="function">和<dbReference type="GO">这两块。前者描述蛋白功能,后者关联基因本体(GO),这些都是知识图谱中非常有价值的语义信息。

2.3 KEGG:通路与疾病网络的“导航图”

KEGG(Kyoto Encyclopedia of Genes and Genomes)是日本京都大学和东京大学联合维护的数据库。它的特色不是单个基因或蛋白,而是把生物过程看成“通路”。

我觉得KEGG最牛的地方在于:它把“基因”、“化合物”、“疾病”、“药物”串成了一张网。你想想看,这跟知识图谱的思维方式是不是天然契合?

2.3.1 核心子库

子库缩写 全称 包含内容 图谱用途
KEGG PATHWAY 通路数据库 540+条通路图 构建“基因-通路”关系
KEGG DISEASE 疾病数据库 疾病与基因、药物的关联 构建“疾病-靶点”关系
KEGG DRUG 药物数据库 日本批准药物+全球药物 补充DrugBank未覆盖的药物
KEGG COMPOUND 化合物数据库 小分子化合物信息 化学实体层

2.3.2 如何获取KEGG数据

KEGG提供REST风格的API,不需要KEY,但有并发限制。我习惯用它来查询“某个基因参与了哪些通路”。

# 获取基因hsa:3569(即IL6)参与的通路
curl "https://rest.kegg.jp/link/pathway/hsa:3569"

# 返回结果示例:
# hsa:3569  path:hsa04630  (JAK-STAT signaling pathway)
# hsa:3569  path:hsa05140  (Leishmaniasis)
# hsa:3569  path:hsa05142  (Chagas disease)
# hsa:3569  path:hsa05150  (Staphylococcus aureus infection)
# hsa:3569  path:hsa05160  (Hepatitis C)
# hsa:3569  path:hsa05161  (Hepatitis B)
# hsa:3569  path:hsa05162  (Measles)
# hsa:3569  path:hsa05164  (Influenza A)
# hsa:3569  path:hsa05168  (Herpes simplex infection)
# hsa:3569  path:hsa05202  (Transcriptional misregulation in cancer)

你看,一个IL6基因就关联了10条通路。这在知识图谱里就是“基因-参与-通路”的三元组关系。

2.3.3 KEGG DISEASE的独特价值

DrugBank虽然有适应症字段,但很多时候药理上“这个药能治这种病”并不等于“这种病的病因跟这个靶点有关”。KEGG DISEASE提供了更严谨的疾病-基因关联。

# 查看疾病D00045(Alzheimer disease)关联的基因
curl "https://rest.kegg.jp/link/genes/H00045"

# 结果包含已知的AD相关基因:
# hsa:3422  (IDUA)
# hsa:3426  (IFI16)
# hsa:351   (APP)
# hsa:5647  (PSEN1)
# hsa:5663  (PSEN2)
# hsa:5664  (PSENEN)
注意:KEGG的API限制是一次只能查询少数几个条目。如果你要大规模获取,建议预先准备好所有需要查询的ID列表,分批请求,每次间隔至少1秒。
我曾经写了个并发脚本,一次性发了1000个请求,结果IP被KEGG封了24小时。嗯,从那以后我就老老实实加sleep(1)了。

2.4 知识体系总览

这三个数据库各司其职,组合起来就能搭建一个初步的药物靶点知识图谱。我习惯把它们叫做“铁三角”:

  • DrugBank:提供药物实体+药物-靶点关系
  • UniProt:提供蛋白实体+功能描述+基因映射
  • KEGG:提供通路、疾病与基因/药物的关联

SVG图展示这三者如何共同支撑起知识图谱的“实体-关系-语义”三层结构:

药物靶点知识图谱数据源架构 DrugBank 药物实体(16,000+) 药物-靶点关系(20,000+) 靶点作用类型 UniProt 蛋白实体(2.5亿+) 蛋白序列、功能、结构域 Gene映射、GO注释 KEGG 通路数据库(540+) 疾病-基因关系(1,800+) 药物-疾病关联 知识图谱实体-关系-语义层 实体(药物|蛋白|基因|疾病|通路)+ 关系(抑制|激活|参与|关联) 药物重定位 靶点发现 机制推理 说明: 三个数据库通过实体ID映射(DrugBank-uniprot-mapping.txt / KEGG gn: → UniProt)关联 知识图谱层负责统一ID体系、消歧、融合关系三元组

2.5 建图前的关键一步:ID映射

数据源介绍完了,有件事你必须心里有数:ID映射。

同一个蛋白,在DrugBank里是一个ID,在UniProt里是另一个ID,在KEGG里可能又是一个ID。你不把ID打通,图谱就是一张“断头路”。

我建议你在建图之前,先拉一张ID映射表:

# drugbank_uniprot_map.txt(示例)
DB00001  P68871
DB00002  P01019
DB00003  P00734
DB00004  P01375

UniProt官方提供了一个映射服务API,可以用来做批量转换:

# 使用UniProt ID Mapping API(POST请求)
curl -X POST "https://rest.uniprot.org/idmapping/run" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "from=DRUGBANK_DRUG_ACCESSION&to=UniProtKB&ids=DB00001,DB00002,DB00003,DB00004"

# 返回一个jobId,然后轮询结果:
curl "https://rest.uniprot.org/idmapping/results/{jobId}"

还记得我刚才说过的吗?ID映射是建图前最繁琐、但也最重要的预处理步骤。别偷懒,把这一步做扎实了,后面所有查询都不会报“节点不存在”的错误。

我在搭建第一个药物知识图谱时,就是因为忽略了这一步,导致图谱里出现了大量“孤儿节点”和“断头关系”,花了整整一周才补上。