2. 知识图谱基础:三元组、实体、关系与语义网络
说起知识图谱,很多人第一反应是Google那个搜索框下面的知识卡片。其实说白了,知识图谱就是一种用图结构来组织知识的技术。它的核心,就是三元组。
我刚开始接触这个领域的时候,总觉得"三元组"这名字挺唬人。后来才发现,它就是我们日常说话里最自然的单位——谁,干了什么,对谁。比如"阿司匹林抑制COX-2酶",去掉那些修饰,留下来的骨架就是阿司匹林、抑制、COX-2酶。就这么简单。
2.1 实体与关系:图的节点和边
先说说实体。实体就是知识图谱里的"节点",可以是一个具体的药物、一个蛋白质、一个疾病,甚至一个抽象的术语。在药物靶点发现里,我常用的实体类型包括:
- 药物 (Drug) — 比如伊马替尼、阿司匹林
- 靶点 (Target) — 比如EGFR、COX-2
- 疾病 (Disease) — 比如肺癌、类风湿关节炎
- 基因 (Gene) — 比如ABL1、PTGS2
- 通路 (Pathway) — 比如JAK-STAT信号通路
关系就是连接这些实体的"边"。关系的类型决定了知识图谱能表达什么。给你看一个简单的对比:
| 关系类型 | 例子 | 说明 |
|---|---|---|
| 抑制 | 伊马替尼 抑制 ABL1 | 药物对靶点的抑制作用 |
| 激活 | EGF 激活 EGFR | 配体-受体激活 |
| 治疗 | 伊马替尼 治疗 CML | 药物对症的疾病 |
| 相互作用 | EGFR 相互作用 STAT3 | 蛋白-蛋白相互作用 |
看到没?就是这三元组模板。我以前做过一个项目,要把PubMed里20万篇文献的关系抽出来,结果发现最头疼的不是抽关系本身,而是怎么统一关系类型。比如"抑制"和"下调",很多文献混着用,你不规范化,后面推理全是错的。嗯,这里要注意——关系类型一定要提前定义好一个可控的词汇表。我当时就是吃了这个亏,后来重写了整个映射逻辑。
2.2 三元组:知识的原子单位
三元组的通用形式是 (主语, 谓语, 宾语),在RDF标准里叫 (主体, 属性, 客体)。在知识图谱里,主语和宾语都是实体,谓语就是关系。
举个例子:
(阿司匹林, 抑制, PTGS2)
(PTGS2, 参与, 前列腺素合成通路)
(前列腺素合成通路, 关联疾病, 疼痛)
这三条三元组连起来,就能回答"阿司匹林为什么能镇痛"这种问题。说白了,知识图谱就是靠这种链式推理来发现新知识的。
你可能会问:那一个三元组能表示复杂关系吗?比如"伊马替尼治疗慢性粒细胞白血病",其中"慢性粒细胞白血病"是一个疾病,但可能还有更细的亚型。这时候我们可以引入URI来唯一标识每个实体,避免歧义。RDF标准里每个实体都用IRI来表示:
<http://example.org/drug/imatinib>
<http://example.org/relation/treats>
<http://example.org/disease/cml> .
我不建议你在项目早期就把IRI设计得太复杂。先拿短名字跑起来,等数据量上去了再标准化。我吃过那种"一上来就搞本体设计"的亏——纠结了一个月的IRI层级,最后业务需求一变,全废了。
2.3 语义网络:从三元组到图
三元组本身是离散的,但把它们放在一起,就形成了一张语义网络。网络中的每个实体连出来的边,构成了它的语义上下文。
想象一下,我们有三个实体:阿司匹林、布洛芬、COX-2。如果三元组是:
(阿司匹林, 抑制, COX-2)
(布洛芬, 抑制, COX-2)
(COX-2, 参与, 炎症反应)
那么这张小图里,阿司匹林和布洛芬就通过COX-2建立了间接联系。在做药物重定位时,我们经常利用这种模式——如果药物A和药物B共享了同一个靶点或通路,它们可能具有相似的适应症。我做过一个案例:用这个逻辑从已经上市的药里找到了几个老药的新用途,其中一个后来还进了临床前验证。
绘制整个知识图谱的结构,可以帮我们直观理解实体之间的连通性。下面这张图展示了药物-靶点-通路-疾病的核心连接模式:
在构建语义网络时,有几个基本原则我建议你记住:
- 一致的关系方向 — 比如"抑制"和"被抑制"不要混用,统一从主体指向客体。
- 实体去重 — 同一个药物可能在不同数据库里叫不同的名字,要用唯一ID对齐。我当时用的UniProt ID和DrugBank ID做锚点。
- 稀疏性处理 — 真实知识图谱里很多实体只有一两条边,推理时需要借助路径传播信号。图神经网络就是干这事的。
2.4 三元组存储与查询
手工写三元组文本还行,数据量一大就必须上专业的图数据库。常见的存储方案有:
- RDF三元组库 — 如Apache Jena、Virtuoso,支持SPARQL查询。
- 属性图 — 如Neo4j,用Cypher查询,节点和边都可以带属性。
- 关系型数据库 — 最简单的就是用一张三列的表来存,但查询性能差。
我个人习惯在项目早期用CSV或者JSON存三元组,方便迭代。等确定了Schema再迁移到图数据库。下面是一个简单的JSON格式示例:
[
{"subject": "imatinib", "predicate": "inhibits", "object": "ABL1"},
{"subject": "ABL1", "predicate": "involved_in", "object": "cell_proliferation"},
{"subject": "imatinib", "predicate": "treats", "object": "CML"}
]
这种格式的好处是容易解析,也容易用Python转成各种图结构的输入。我写过一个脚本,直接从PubMed挖掘出来的三元组转成这个JSON,然后再喂给图神经网络训练。
confidence: 0.95的字段,这样在后续特征学习时可以过滤低质量的边。
2.5 小结:从三元组到知识图谱特征学习
总结一下,知识图谱的基础就是三元组。实体是节点,关系是边,整个图就是一个语义网络。在这个网络上,我们可以做路径分析、子图匹配,甚至用图神经网络(GNN)学出每个节点的向量表示,用于药物靶点预测。