4. 数据来源:公开数据库(DrugBank、UniProt等)
做药物靶点知识图谱,数据从哪来?这是最基础的问题。说实话,我刚入行时也犯过傻——自己爬论文、手动整理,累死累活搞了两个月,最后发现别人早就把结构化数据公开了。公开数据库是建图的基石,选对数据源,你的项目就成功了一半。
我个人习惯,优先用这几个:DrugBank、UniProt、ChEMBL、PDB。它们覆盖了药物-靶点关系的核心信息。今天咱们就逐个拆解,怎么拿数据、怎么用、有什么坑。
4.1 DrugBank:药物-靶点的“全家桶”
DrugBank 是加拿大阿尔伯塔大学的宝贝。它把药物、靶点、通路、相互作用全串在一起。我当年做第一个KG原型时,80%的药物-靶点关系就是从这拉的。
数据怎么拿? 两种方式:直接下载XML/TSV文件,或者用REST API。
我个人倾向于先用TSV做快速探索。DrugBank官方提供 drugbank.tsv 和 target_uniprot_id.tsv,里面药物ID、靶点ID、作用机制(mechanism of action)都列好了。示例:
DrugBank ID Name Target ID Target Name Action
DB00001 Lepirudin P01048 Thrombin Inhibitor
DB00002 Cetuximab P00533 Epidermal growth factor receptor Antagonist
DB00003 Denileukin diftitox P01589 Interleukin-2 receptor alpha Agonist
但注意:TSV版本是社区维护的,不一定最新。我建议去官网申请学术账户,拿到完整XML。XML结构更全,包含了药物分类、ATC代码、靶点的UniProt ID列表。解析XML你可以用Python的 xml.etree.ElementTree 或 xmltodict,我习惯用后者,代码干净:
import xmltodict
with open('drugbank.xml', 'r') as f:
data = xmltodict.parse(f.read())
drugs = data['drugbank']['drug']
for drug in drugs[:5]:
print(drug['name'], drug['drugbank-id'])
关键点:DrugBank 的靶点关系里,action 字段很珍贵——它告诉你药物是抑制剂、激动剂还是拮抗剂。做KG时,这个属性要挂到关系上。
小技巧:如果你只想拿“已批准”药物,过滤掉实验药物。我用这个条件:drug['groups'] == 'approved'。
4.2 UniProt:靶点蛋白的“身份证”
DrugBank 给了你靶点的UniProt ID,但蛋白的完整信息(序列、功能、结构域、疾病关联)都在 UniProt 里。说白了,UniProt 就是蛋白质界的维基百科。
怎么查? 两种主流方式:
- SPARQL 端点:官方提供的知识图谱查询接口。你可以写类似SQL的语句,灵活抽取数据。
- RESTful API:常用的
https://rest.uniprot.org/uniprotkb/P01048返回JSON,包含所有注释。
举个例子,我想批量拉取某个药物所有靶点的功能描述:
curl -X GET "https://rest.uniprot.org/uniprotkb/search?query=accession:P01048 OR accession:P00533&format=json" -H "Accept: application/json"
返回的JSON里,proteinDescription 和 function 字段就是你要的。我曾在项目里直接用Python的 requests 循环调用,但小心限速——UniProt 没有API key,但限制每秒最多30次请求。我吃过一次亏:写了个for循环忘了加time.sleep,结果被临时封了IP。
避坑指南:我曾经直接用DrugBank的UniProt ID去UniProt搜,发现20%的ID已经废弃。你得用 id mapping 服务更新。UniProt提供 https://rest.uniprot.org/idmapping/run 批量映射。
还有一个我常用的数据:Gene Ontology (GO) 注释。靶点的GO项能告诉你它参与哪些生物学过程、分子功能。这些属性做知识推理时特别有用。比如一个靶点有“G蛋白偶联受体活性”的GO,那它大概率是GPCR类靶点。
4.3 ChEMBL:活性数据“集散地”
DrugBank 告诉你“这个药跟那个靶点有相互作用”,但没告诉你“结合有多强”。ChEMBL 正好补这个缺口。它收集了文献里发表的化合物-靶点活性数据,包括 IC50、Ki、EC50 等。
数据下载:ChEMBL 提供 MySQL dump 和 SDF 文件。我推荐用他们的 ChEMBL Web资源客户端 (chembl_webresource_client),Python 包,一行代码就能查:
from chembl_webresource_client.new_client import new_client
molecule = new_client.molecule
target = new_client.target
activities = new_client.activity
# 查找某个靶点的所有化合物活性
acts = activities.filter(target_chembl_id='CHEMBL1827').only(['molecule_chembl_id', 'standard_value', 'standard_type'])
for a in acts:
print(a['molecule_chembl_id'], a['standard_value'], a['standard_type'])
你看,返回的直接是Python字典,省去了解析JSON的麻烦。我自己做KG时,会把ChEMBL的活性值作为实体属性加到“药物-靶点”关系上,这样后续可以做“效力排序”。
| 数据库 | 核心数据 | 获取方式 | 推荐场景 |
|---|---|---|---|
| DrugBank | 药物-靶点关系、机制 | XML/TSV/REST API | 基础骨架 |
| UniProt | 蛋白质序列、功能、GO | REST API/SPARQL | 丰富靶点属性 |
| ChEMBL | 化合物-靶点活性值 | Python客户端/MySQL | 量化相互作用 |
| PDB | 蛋白质3D结构 | REST API/下载mmCIF | 结构信息 |
| NCBI Gene | 基因位置、别名、疾病 | Entrez API/E-utilities | 跨物种映射 |
4.4 数据整合的核心思路
数据库多了,怎么把它们串起来?核心就是 ID映射。DrugBank 的靶点ID是 DBXXXXX 格式,但UniProt用的是 PXXXXX 格式。好在每个数据库都提供了交叉引用表。比如DrugBank的XML里,每个靶点节点下面就有 <uniprot-id> 字段。
我总结了一个三步整合流程:
- 建立种子列表:从DrugBank筛选出全部已批准药物及其靶点UniProt ID。
- 属性扩展:用UniProt ID去拉取功能描述、GO项、疾病关联。
- 活性注入:用ChEMBL的化学分子ID(CHEMBL ID)关联到药物,然后取对应靶点的活性数据。
下面这个SVG图展示了数据源到知识图谱的流动过程:
4.5 实战避坑:数据质量与更新
公开数据库看起来美好,但用起来到处是坑。我踩过几个,列出来你注意:
- ID 过时:UniProt 的 accession 号会合并或拆分。最好每次用 id mapping 服务重新映射一次。
- 重复关系:DrugBank 里同一个药物-靶点对可能出现多次(不同出版物)。合并时取置信度最高的。
- 许可协议:DrugBank 的学术版不能商用。你如果要上生产,得买商业授权。UniProt 和 ChEMBL 是CC BY-SA 4.0,相对宽松。
- API 限流:类似 UniProt 30次/秒,ChEMBL 10次/秒。批量拉数据时记得用
time.sleep(0.5)或并发控制。
踩坑经验:我曾经直接拿社区版的 DrugBank TSV 文件做全量导入,结果几个月后官方更新了数据,我的图谱里20%的药物-靶点关系变了。现在我每次建图前都跑一遍增量同步脚本,只更新有变更的条目。
最后总结一句:数据源选对了,建图就成功了一半。DrugBank 给骨架,UniProt 填血肉,ChEMBL 加活性,PDB 加结构,NCBI Gene 连基因。你能把这几个串起来,知识图谱的质量基本就稳了。实际项目中,我还会加一些疾病数据库(如 DisGeNET)做疾病-靶点关联,但那已经是下一章的内容了。
核心建议:不要试图一次性搞全所有数据。先拿 DrugBank + UniProt 做一个最小可行图谱(MVP),然后逐步扩增ChEMBL、PDB。这样迭代快,早期就能看到效果。