4. 生物医学知识图谱资源:DrugBank、STRING、UniProt、GO 等数据库归纳总结
做药物靶点发现,说白了就是在海量生物数据里挖金子。你最先要搞清楚的,就是手头有哪些数据库能用。我自己这些年踩过不少坑,最深的体会是:数据库选不对,后面所有特征工程都是白搭。
今天咱们就把几个最核心的生物医学知识图谱资源掰开揉碎了聊。我会结合自己的项目经历,告诉你每个库到底能干什么、不能干什么、以及我怎么把它们揉进知识图谱特征学习里。
4.1 四大数据库概览
我习惯把这四个库当成知识图谱的四个“基座”:
- DrugBank —— 药物-靶点关系的金标准
- STRING —— 蛋白互作网络的大本营
- UniProt —— 蛋白质信息的“维基百科”
- Gene Ontology (GO) —— 功能注释的标准化术语集
你想想看,一个药物靶点发现的知识图谱,缺了其中任何一个,都会像缺了一条腿的桌子。下面这张图能帮你快速建立整体认知。
核心观点:这四个数据库不是孤立的。DrugBank里的靶点蛋白ID可以直接链接到UniProt;UniProt的蛋白又和STRING中的互作节点一致;GO则给这些蛋白贴上功能标签。它们天然构成了一张跨库知识网络。
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 跨库融合:一个实际案例
最后给个实际例子。假设你想预测某个新药的可能靶点,可以这样组合这些数据库:
- 从 DrugBank 取与目标疾病相关的已知药物-靶点关系,构建种子子图。
- 从 STRING 取这些靶点的互作蛋白(score ≥ 0.9),扩展候选池。
- 用 UniProt 给候选蛋白补充功能描述和疾病关联。
- 用 GO 注释计算候选蛋白与已知靶点的功能相似度(如
semantic similarity)。 - 把所有这些信息融合成知识图谱,跑 GraphSAGE 或 RGCN 学习节点表示,最后用 link prediction 预测药物-候选蛋白的边。
我自己在某个 kinase 抑制剂项目中就是这么干的。最后模型筛选出的 top-10 候选蛋白里,有 3 个后续被文献验证为真实靶点。虽然不算完美,但比起只用一个数据库的效果提升了近一倍。
工具推荐:跨库 ID 映射可以使用 pyBiodata 或 Biological ID Mapper (BridgeDb)。我常用的是 UniProt 官方 ID mapping API,返回格式选 JSON,然后直接用 pandas.DataFrame 处理。