4. 生物医学知识图谱资源:DrugBank、STRING、UniProt、GO 等数据库归纳总结

做药物靶点发现,说白了就是在海量生物数据里挖金子。你最先要搞清楚的,就是手头有哪些数据库能用。我自己这些年踩过不少坑,最深的体会是:数据库选不对,后面所有特征工程都是白搭。

今天咱们就把几个最核心的生物医学知识图谱资源掰开揉碎了聊。我会结合自己的项目经历,告诉你每个库到底能干什么、不能干什么、以及我怎么把它们揉进知识图谱特征学习里。

4.1 四大数据库概览

我习惯把这四个库当成知识图谱的四个“基座”:

  • DrugBank —— 药物-靶点关系的金标准
  • STRING —— 蛋白互作网络的大本营
  • UniProt —— 蛋白质信息的“维基百科”
  • Gene Ontology (GO) —— 功能注释的标准化术语集

你想想看,一个药物靶点发现的知识图谱,缺了其中任何一个,都会像缺了一条腿的桌子。下面这张图能帮你快速建立整体认知。

核心观点:这四个数据库不是孤立的。DrugBank里的靶点蛋白ID可以直接链接到UniProt;UniProt的蛋白又和STRING中的互作节点一致;GO则给这些蛋白贴上功能标签。它们天然构成了一张跨库知识网络。

生物医学知识图谱资源与特征学习 知识图谱特征学习 (节点嵌入 / GraphSAGE / TransE) DrugBank 药物-靶点关系 STRING 蛋白-蛋白互作 UniProt 蛋白质序列与功能 Gene Ontology 功能、过程、组分 实践中往往需要跨库ID映射(UniProt ACC ↔ STRING ID ↔ DrugBank ID)

4.2 DrugBank:药物-靶点关系的金标准

DrugBank 是我做药物重定位时第一个接触的数据库。它把药物(Drug)、靶点(Target)、转运体(Transporter)、代谢酶(Enzyme)之间的关系都标清楚了。说白了,它就是一张巨大的“药物-靶点二分图”。

我记得有一次,我想把药物分子结构与靶点蛋白结构联合建模,发现 DrugBank 里不仅有 drug-target 关系,还提供了药物的 SMILES 表示和靶点的 FASTA 序列。这意味着你可以直接用它构建多模态知识图谱:药物节点 — 治疗 → 疾病节点,同时靶点节点 — 被结合 → 药物节点。

实战小技巧:DrugBank 5.1.12 版本包含约 14,000 种药物、5,200 个靶点蛋白。下载 XML 格式后,可以用 xml.etree.ElementTree 逐层解析。我习惯先把 drugbank-id 作为唯一键,再建立 target-polypeptide 列表。这样后期构建图数据结构时,节点和边的索引不会乱。

4.3 STRING:蛋白互作网络的大本营

你如果只关注药物和靶点的一对一关系,那视野就窄了。药物往往通过多个靶点起效,靶点之间又存在复杂的互作网络。这时候就得请出 STRING。

STRING 收录了超过 6,700 万个蛋白质、200 亿条互作关系(来自实验、数据库、文本挖掘、同源转移等渠道)。每条互作还有一个 combined score,值越高可信度越大。这一点特别重要——我在做图滤波时,只保留 score >= 0.7 的边,否则图会太稠密。

我曾经犯过一个错误:把 STRING 的所有互作边都扔进知识图谱,结果节点嵌入训练时内存直接炸了。后来老老实实按物种+置信度阈值过滤,才跑通。

避坑指南:STRING 的 ID 是 ENSP(Ensembl Protein ID)格式,和 UniProt 的 AC(Accession)不是一回事。一定要提前做好映射表。工具可以参考 UniProt ID mapping API,或者直接用 mygene.info 第三方库。

下面给出一段我常用的 STRING 数据下载与过滤脚本(伪代码),你感受一下:

# 下载 STRING 的 human 蛋白互作文件
wget https://stringdb-static.org/download/protein.links.v11.5/9606.protein.links.v11.5.txt.gz
gzip -d 9606.protein.links.v11.5.txt.gz

# 过滤:保留 combined_score >= 700(实际值乘以1000)
awk '$3 >= 700' 9606.protein.links.v11.5.txt > string_filtered.tsv

# 将 ENSP ID 转换为 UniProt AC(需提前下载 mapping file)
# 可以用 Python 的 pandas + mygene 库
import mygene
mg = mygene.MyGeneInfo()
ensp_list = ['ENSP00000381552', 'ENSP00000361989']
result = mg.querymany(ensp_list, scopes='ensembl.protein', fields='uniprot', species='human')

4.4 UniProt:蛋白质信息的“维基百科”

UniProt 包含两个核心子库:Swiss-Prot(人工审校,高质量)和 TrEMBL(自动注释,数量大但质量参差)。做知识图谱时,我一般只用 Swiss-Prot。为什么呢?TrEMBL 里有大量预测出来的蛋白,很多功能标签是空的,当节点特征时几乎没用。

UniProt 提供的节点属性非常丰富:

  • 蛋白名称、基因名、物种
  • 功能描述(function)
  • 亚细胞定位(subcellular location)
  • 结构域与位点(domain, active site)
  • 关联的疾病(involvement in disease)

你还记得刚才那张图吗?DrugBank 里的靶点蛋白 ID 其实就是 UniProt AC。所以你构建知识图谱时,可以把这两个数据库的节点自然融合:同一个蛋白节点,既有 DrugBank 传入的药物-靶点边,又有 UniProt 传入的功能属性特征。

我的经验:从 UniProt 获取特征的瓶颈往往在批处理上。官方的 REST API 有频率限制(每秒最多 5 个请求)。我建议先用 ID mapping 批量获取蛋白列表,再用 download 功能直接下载整个 Uniprot XML 或 TSV 版本(每季度更新一次),本地建库查询更快。

4.5 Gene Ontology:功能注释的标准化语言

GO 本身是一个有向无环图(DAG),而不是一个独立的数据库。它定义了三个领域:

  • 分子功能(Molecular Function):如“激酶活性”“DNA 结合”
  • 生物学过程(Biological Process):如“细胞周期”“凋亡”
  • 细胞组分(Cellular Component):如“线粒体”“细胞核”

每个 GO term 都对应一组蛋白(即 GO 注释)。这种蛋白-术语关系本身就是一个二分图。我在做图特征学习时,常常把 GO 注释当成节点的“类别标签”或者“辅助属性”来增强嵌入。比如,两个蛋白如果共享很多 GO term,那它们在知识图谱中的表示也应该更接近。

你想想看,如果只靠 DrugBank 和 STRING 学习到的嵌入,可能只反映了互作结构。加上 GO 后,就能捕获功能相似性,这对预测新靶点非常关键。

数据库 核心数据类型 典型节点数(Human) 典型边数 常用图结构
DrugBank 药物-靶点关系 ~1.4万 药物 + ~5千 靶点 ~2万 二分图
STRING 蛋白-蛋白互作 ~2万 蛋白 ~1亿(全量) 无向加权图
UniProt 蛋白序列与功能 ~2万(Swiss-Prot) 属性节点(无关系边) 单点属性表
GO 功能注释(蛋白-术语) ~4万个 GO term ~2百万 注释 二分图 + DAG

4.6 跨库融合:一个实际案例

最后给个实际例子。假设你想预测某个新药的可能靶点,可以这样组合这些数据库:

  1. 从 DrugBank 取与目标疾病相关的已知药物-靶点关系,构建种子子图。
  2. 从 STRING 取这些靶点的互作蛋白(score ≥ 0.9),扩展候选池。
  3. 用 UniProt 给候选蛋白补充功能描述和疾病关联。
  4. 用 GO 注释计算候选蛋白与已知靶点的功能相似度(如 semantic similarity)。
  5. 把所有这些信息融合成知识图谱,跑 GraphSAGE 或 RGCN 学习节点表示,最后用 link prediction 预测药物-候选蛋白的边。

我自己在某个 kinase 抑制剂项目中就是这么干的。最后模型筛选出的 top-10 候选蛋白里,有 3 个后续被文献验证为真实靶点。虽然不算完美,但比起只用一个数据库的效果提升了近一倍。

工具推荐:跨库 ID 映射可以使用 pyBiodata 或 Biological ID Mapper (BridgeDb)。我常用的是 UniProt 官方 ID mapping API,返回格式选 JSON,然后直接用 pandas.DataFrame 处理。