第3章:药物实体类型——药物、疾病、靶点、基因与副作用

做知识图谱的第一关,就是搞清楚「节点」长什么样。说白了,咱们要先把药物领域里最常见的几种实体类型拎清楚,不然后面的特征提取、关系推理全得跑偏。我个人习惯把实体类型理解成「角色」——每个角色在KG里承担什么样的属性、连接什么样的关系,这决定了后续模型能不能学到有意义的表示。

这一章,我就从药物、疾病、靶点、基因和副作用这五种核心实体入手,聊聊它们的定义、边界和典型特征。嗯,下面直接开工。

5.1 药物实体

药物实体是最直观的。它可以是化学小分子、生物制剂、中药复方,甚至是候选化合物。我在做项目时遇到过一个问题:同一个药物,在不同数据库里叫法完全不一样。比如“阿司匹林”在DrugBank里叫acetylsalicylic acid,在ChEMBL里可能给另一个ID。所以实体类型需要先定义标准字段。

下表是我总结的药物实体常用特征字段:

字段说明示例
drug_id唯一标识符(如DrugBank ID)DB00945
name通用名或代号阿司匹林
molecular_weight分子量(小分子药物)180.16
smiles化学结构线性表示CC(=O)Oc1ccccc1C(=O)O
drug_type小分子/大分子/中药smallmolecule
一点经验:千万别只靠名字做实体对齐。我曾经只用一个名称字段,结果把“诺氟沙星”和“左氧氟沙星”搞混了。建议加上SMILES或InChIKey做化学结构校验。

5.2 疾病实体

疾病实体通常来自ICD-10、DOID、MeSH等标准本体。它跟药物有一对多的治疗关系。你想想看,一个疾病可能对应几十个药物,但每个药物的适应症描述方式又不一样。比如“Ⅱ型糖尿病”可能被写成“type 2 diabetes mellitus”“T2DM”甚至“non-insulin-dependent diabetes”。

我做特征处理的时候,习惯把疾病实体分成两个维度:

  • 语义标签:标准名称、同义词、定义描述
  • 层级归属:所属类别(如代谢性疾病、心血管疾病)

下面给一段JSON格式的疾病实体特征定义,你可以参考:

{
  "disease_id": "DOID:9352",
  "name": "type 2 diabetes mellitus",
  "synonyms": ["T2DM", "adult-onset diabetes"],
  "definition": "A diabetes mellitus that is characterized by insulin resistance...",
  "category": "metabolic disease"
}
避坑提醒:我曾经在文本里直接用疾病名称做实体链接,结果“糖尿病”和“糖尿病肾病”被当成同一个节点。一定要区分不同细化程度的疾病实体,粒度不同,特征向量也该不同。

5.3 靶点实体

靶点实体一般指蛋白质、酶、受体、离子通道等生物大分子。它是药物作用机制的核心。我在今年一个靶点预测项目里发现,同一个蛋白质在不同物种或剪接变体下,结构差异极大,直接影响药物结合能力。

靶点实体特征我习惯收这几项:

  1. UniProt ID(标准蛋白标识)
  2. 基因名(比如EGFR)
  3. 蛋白类型(kinase, GPCR, nuclear receptor等)
  4. 细胞位置(membrane, cytosol, nucleus等)
  5. 结合口袋的氨基酸序列片段(用于深度学习特征输入)

举个例子,一个GPCR靶点的特征表达:

uniprot_id: P35372
gene_symbol: OPRM1
protein_class: mu-opioid receptor
cellular_location: membrane
binding_pocket_seq: "FL" (实际会有几十个残基)

说白了,靶点实体不只是个名字,它背后有一整套生物属性。我们把特征做全了,后面做药物-靶点相互作用预测才能更准。

5.4 基因实体

基因实体和靶点实体常常混淆。区别在于:靶点强调的是“功能的直接作用对象”,而基因是“编码该靶点的DNA序列”。实际数据里,一个基因可能编码多个蛋白亚型,每个亚型又可能是不同靶点。嗯,这里要注意层级关系。

我通常把基因实体当作桥梁节点。比如:

  • 药物 → 靶点 → 基因:表示该药物通过靶点调控基因表达
  • 基因 → 疾病:表示该基因突变与疾病关联

基因实体常用特征:

字段说明示例
entrez_idNCBI Gene ID1814
symbol标准基因符号DRD3
chromosome染色体位置3q13.31
gene_type蛋白编码/非编码RNAprotein-coding
关键点:基因实体特征的稀疏性很高。很多基因在药物KG里只有ID和名称,没有更丰富的序列或功能信息。这时候,可以用图神经网络从邻居实体(比如它参与的靶点、对应的疾病)学习embedding,反补缺失特征。

5.5 副作用实体

副作用实体往往从SIDER、FAERS等数据库抽取。它的特征处理比较棘手,因为同一个副作用表现可能有不同描述,比如“恶心”可能写成“nausea”“vomiting sensation”“queasiness”。我建议先用义原规范(比如MedDRA的LLT)做标准化。

副作用实体特征可以包括:

  • 副作用名称(标准化后)
  • 严重等级(轻/中/重)
  • 发生率(常见/偶见/罕见)
  • 关联药物列表(多对多)

下面是一个副作用节点在Neo4j中的属性示例:

CREATE (:SideEffect {
  name: "nausea",
  severity: "moderate",
  frequency: "common",
  meddra_code: "10028813"
});
如果搞不定频率字段:我踩过坑——直接把FAERS里的报告数量当成特征,结果不同年份数据量差异大,特征分布全乱。正确做法是归一化到“每百万处方报告数”或直接用分类标签。

5.6 实体类型的关系与特征融合思路

到这五种实体类型都有了,它们之间天然形成网络结构。我个人习惯先把每个实体的文本特征(名称、描述、同义词)用预训练语言模型(如BioBERT)转成稠密向量,再与数值/结构特征拼接,最后丢进GCN或TransE做推理。

下面这张SVG图展示了五种核心实体及它们之间的典型关系:

药物知识图谱核心实体类型与关系 药物知识图谱核心实体类型与关系 药物 (Drug) DB00945, SMILES, 分子量 疾病 (Disease) DOID:9352, ICD-10 靶点 (Target) UniProt ID, 蛋白类型 基因 (Gene) Entrez ID, 染色体 副作用 (SideEffect) MedDRA, 严重等级 治疗 作用于 导致 编码 关联

你看这张图,每种实体都有自己的特征集,关系线也标明了。实际建图时,我还会给关系加上权重或时间属性,比如“治疗成功率”“副作用发生率”。这些额外的结构化信息,对后面做实体特征聚合非常有帮助。

一个小技巧:如果关系稀疏,可以对实体做类型级别的特征共享。比如所有“靶点”实体共享一个基础embedding,再附加UniProt对应的个性化embedding。这样既缓解冷启动,又保留了特异性。我在几个工业级KG上试过,F1提升了近6%。

回到本章核心:五种实体类型不是孤立存在的。特征处理的关键,是让模型知道每种实体「属于什么类型、拥有什么属性、连接什么邻居」。说白了,类型本身就是一个重要特征。我习惯在embedding层直接加入一个可学习的类型向量,跟其他特征向量拼接,效果立竿见影。

总结一下实践要点:

  • 每个实体必须有一个类型标识(drug/disease/target/gene/side_effect)
  • 文本特征用专用预训练模型(BioBERT、PubMedBERT)提取
  • 数值特征(分子量、严重等级)做归一化或分桶
  • 结构特征(SMILES、序列)可以用图方法或CNN/RNN编码
  • 关系方向性很重要:药物→靶点是有向,药物→副作用也是有向

对了,我曾在一个医疗数据集里发现“基因”和“靶点”被混着标。明明是同一个蛋白质,一个叫法说它是基因,另一个叫法说它是靶点。这个问题不解决,后面特征冲突会害死模型。所以案例上,必须做类型冲突检测:同一条UniProt ID不能同时挂“gene”和“target”标签,除非建模多类型节点(比如用type_list)。