第1章:知识图谱基础——从三元组到药物数据

做知识图谱嵌入模型,你首先得搞清楚什么是知识图谱。我见过不少同学一上来就调参,结果模型的输入输出都搞反了。说白了,知识图谱就是一种用图结构来组织知识的方式。它不是什么玄学,就是一种数据表达手段。

1.1 知识图谱的定义与三元组结构

知识图谱的核心单元是 三元组。每个三元组就三个要素:头实体、关系、尾实体。用大白话说,就是“谁”和“谁”之间有什么“关系”。

标准三元组格式:

(head_entity, relation, tail_entity)

举个例子:

(阿司匹林, 用于治疗, 头痛)
(布洛芬, 与, 阿司匹林) 存在交互作用
(ChEMBL_COMPOUND123, 结合于, 靶点_COX1)

每个三元组就是一个事实。你想想看,把成千上万个这样的三元组连起来,就形成了一张巨大的知识网络。我刚开始做药物KG时,总觉得三元组太简单,后来才发现,正是这种简单的结构,才能支撑复杂的推理任务。

三元组在存储时,通常会用 索引表 来管理:

索引 头实体 关系 尾实体
0 阿司匹林 用于治疗 头痛
1 阿司匹林 与 布洛芬
2 布洛芬 用于治疗 头痛

在模型训练时,我们会把这些实体和关系映射成向量。这种映射就叫 嵌入。嗯,这里要注意:嵌入的质量,直接取决于你三元组数据的完整度和准确度。

1.2 药物知识图谱的独特特征

药物知识图谱和通用的知识图谱不太一样。我个人习惯把它称为“带着生命科学的镣铐跳舞”。为什么这么说?

  • 实体类型多且层次复杂:药物、靶点、疾病、基因、代谢通路、副作用……每个类型内部还有层级。
  • 关系类型丰富:不只是简单的“治疗/抑制/激活”,还有“结合亲和力 > 10nM”、“半衰期 4-6小时”这类带数值的关系。
  • 时间维度重要:一个药物在不同时间点的状态可能不同,比如“获批上市于2010年”。
  • 数据稀疏性高:大部分药物只和少量靶点有明确关系,这会导致嵌入训练时负采样困难。

我曾经接手过一个项目,数据集里包含大量“药物-靶点”关系,但靶点实体描述有50%以上是别名。结果训练出来的嵌入完全没法用。所以,数据清洗是第一步,别跳过。

你也可以用一些简单的脚本,把原始数据转成三元组格式。比如从CSV里提取药物与靶点的关系:

import pandas as pd

df = pd.read_csv('drug_target.csv')
triples = []
for _, row in df.iterrows():
    triples.append((row['drug_id'], 'binds_to', row['target_id']))

# 保存三元组
with open('triples.txt', 'w') as f:
    for h, r, t in triples:
        f.write(f"{h}\t{r}\t{t}\n")

你想想看,一个药物KG通常包含多少三元组?少则几十万,多则上亿。这就是为什么我们需要嵌入模型——把图结构压缩到一个低维空间里。

1.3 常见药物KG资源

现在我来介绍两个最常用的公开资源。做药物嵌入研究,你绕不开它们。

DrugBank

DrugBank 算是我见过的综合度最高的药物数据库。它涵盖药物化学结构、药理作用、靶点、代谢酶、转运体等。最新版本(5.1.x)里有超过14000种药物本体,以及数千种靶点蛋白。

它的三元组抽取逻辑类似这样:

# 示例:DrugBank XML 中的三元组提取片段
drug_id: DB01050
relations:
  - (DB01050, has_target, TARGET_IBUPROFEN_1)
  - (DB01050, has_metabolic_enzyme, CYP2C9)
  - (DB01050, treats_condition, 原发性痛经)

ChEMBL

ChEMBL 更偏向生物活性数据,包含大量结合亲和力实验数据。它的优势在于数值化关系非常多,比如 IC50、Ki、EC50 等。我建议你用 ChEMBL 来做那些需要“关系强度”的嵌入任务。

ChEMBL 的典型三元组:

# 从 ChEMBL SQLite 导出示例
Compound: CHEMBL25
Target: CHEMBL_target_252
Relation: has_activity_value
Value: 6.5 (pIC50)

下面是两个资源的对比表:

特征 DrugBank ChEMBL
核心数据 药物中心(药理、化学、靶点) 化合物中心(生物活性、实验数据)
关系类型 定性为主(治疗/抑制/激活) 定量为主(IC50/Ki/EC50)
更新频率 年更新 季度更新
适用嵌入场景 药理作用预测、药物重定位 亲和度预测、构效关系建模
数据格式 XML / 自定义CSV SQLite / SDF / CSV

光说不练假把式。你下载好数据后,可以用这样几行代码快速看一下数据结构:

# 以 ChEMBL 为例,查看表格结构
import sqlite3
conn = sqlite3.connect('chembl_28.db')
cursor = conn.cursor()
cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
tables = cursor.fetchall()
print(tables[:5])  # 打印前5个表名

本章核心知识结构

为了让你对整个体系有个直观印象,我画了一张图。这张图概括了从三元组定义到两个典型数据集的全貌。

第1章:知识图谱基础 — 核心结构 知识图谱定义 三元组 (头实体, 关系, 尾实体) 药物KG独特特征 常见KG资源 实体类型多 关系类型丰富 时间维度重要 数据稀疏性高 DrugBank ChEMBL 💡 个人经验提示 在做药物KG嵌入前,先花20%时间整理数据。 我每次都用一段脚本检查三元组重复率和实体覆盖度。 数据质量决定了模型效果的上限。

我的建议:刚开始接触药物KG时,别急着跑模型。先把 DrugBank 或 ChEMBL 的数据结构看透。我花了一周时间,只为了搞明白 ChEMBL 里的 activity 表和 compound 表是怎么关联的。后来才知道,这个投入太值了。

好了,这一章的内容就到这儿。打好基础,后面练功才不慌。