2. 知识图谱嵌入基础:TransE 与 DistMult
在正式啃 ComplEx 之前,咱们得先把地基打牢。知识图谱嵌入(KGE)说白了,就是给图谱里的每个实体和关系找一个“数学位置”。你想想看,药物和蛋白质相互作用这种复杂网络,用文字描述太绕了,不如把它们都扔进一个向量空间里,用算数代替推理。
我最早接触 KGE 是在一个药物重定位项目里。当时数据量大得吓人,光用规则匹配根本跑不动。后来我就明白了:嵌入的本质,就是“用连续向量代替离散符号,用距离表示语义”。
2.1 核心思想:用向量“翻译”三元组
知识图谱里的每一条知识都是一个 三元组 (h, r, t):
- h(头实体):比如“阿司匹林”
- t(尾实体):比如“头痛”
- r(关系):比如“治疗”
嵌入模型的任务,就是给每个 h、r、t 都分配一个低维实数向量(比如 128 维或 256 维),然后定义出一个打分函数 f(h, r, t)。
这个分数越高,说明这个三元组成立的可能性越大。说白了,就是让正确的三元组得分远高于错误的三元组。
我习惯把这个过程叫“结构化压缩”——几千几万个实体,压缩成几百维的向量,还要保留它们之间复杂的语义关系。嗯,这里要记住:得分的幅度本身不重要,重要的是正负样本之间的排序差异。
2.2 TransE:最直觉的翻译模型
TransE 是所有 KGE 模型里最简单的一个,也是我新手时期用的第一个模型。它的思路极度朴素:
h + r ≈ t。
意思是,头实体沿着关系的方向“走”一步,就应该到达尾实体。你想象一下在欧氏空间里:
- 如果阿司匹林( h) 加上治疗( r),结果应该≈ 头痛( t)。
- 如果加上之后离头痛很远,那这个三元组就很可疑。
它的打分函数长这样:
f(h, r, t) = -|| h + r - t ||²
对的,就是负的 L2 距离的平方。分数越高,三角形走得越“顺”。
损失函数与训练
TransE 用的是基于边际的排序损失(margin-based ranking loss),我直接贴一段简化实现吧,这是当年我在项目里手写的核心:
import torch
def transE_loss(pos_score, neg_score, margin=1.0):
# 正样本分数高,负样本分数低
# 我们希望 pos_score - neg_score 的差距 ≥ margin
loss = torch.relu(neg_score - pos_score + margin)
return loss.mean()
训练流程:
- 对每个正确三元组,随机替换头或尾,构造一批负样本。
- 算正负样本分数。
- 利用边际损失更新所有向量。
- 每轮训练后归一化实体向量,维持数值稳定。
TransE 的软肋
说白了,TransE 只能处理 1-1 关系。遇到 N-1、1-N 或者对称关系,它就开始犯糊涂了。
我遇到过最典型的问题:“药物A治疗疾病B”和“药物A治疗疾病C”在 TransE 的框架下,B 和 C 的向量会被拉近,不管它们是不是同一个概念。这就是所谓的“自反关系”问题。
2.3 DistMult:用点积取代距离
DistMult 换了一个思路。它不再用向量加减法,而是用 点积和。打分函数变成:
f(h, r, t) = h^T · Diag(r) · t = Σ_i h_i * r_i * t_i
说白了,就是三个向量对应元素相乘再求和。这里 r 是一个对角矩阵,只在对角线上有值。
为什么这么做?因为点积天然适合衡量相似度——如果 h、r、t 的对应维度趋势一致,得分就高。这很符合药物关系中的一些场景,比如“多个靶点通过同一个机制被同一个药物激活”。
DistMult 的参数比 TransE 少了一截:关系只用 d 维的对角矩阵( d 就是向量长度),而不是满矩阵 d×d。训练速度更快,内存占用也更友好。
DistMult 的天生局限
然而,DistMult 有一个致命弱点:它只能处理对称关系。因为点积本身是对称的:h^T · Diag(r) · t = t^T · Diag(r) · h。
这就意味着,如果数据中存在方向性关系(比如“药物A靶向蛋白B”≠“蛋白B靶向药物A”),DistMult 就完全无能为力了。你的模型会把逆关系也学成高得分,导致预测严重走偏。
2.4 TransE vs DistMult 核心对比
| 对比维度 | TransE | DistMult |
|---|---|---|
| 关系建模方式 | h + r ≈ t (向量平移) | h^T · Diag(r) · t (点积) |
| 参数数量 | 每个关系一个向量 (d维) | 每个关系一个对角矩阵 (d个参数) |
| 对称关系 | ❌ 无法建模 | ✅ 天然支持 |
| 方向性关系 | ✅ 天然支持 | ❌ 无法建模 |
| 计算复杂度 | O(d) | O(d) |
| 适合场景 | 1-1关系、方向性强 | 对称关系、相似性建模 |
这两者就像左右手——各有特长,也各有软肋。那有没有一个模型能同时处理这两种关系?这就要引到 ComplEx 了。不过在那之前,我们先看看它们各自的知识图谱嵌入流程,这样你心里就有个全景图。
下面这张图展示了我自己在项目中总结的 KGE 通用流程,以及 TransE 与 DistMult 分别卡在哪一阶段:
2.5 小结
我们把这一章的内容串一下:
- 知识图谱嵌入的本质是把符号化的三元组映射到连续向量空间,用距离或相似度进行推理。
- TransE 靠的是向量平移,适合方向性强的 1-1 关系,但在对称/多关系上表现不佳。
- DistMult 靠的是三向点积,天然支持对称关系,但完全无法处理方向性。
- 两者都是参数少、训练快的轻量级模型,适合作为基线模型。