表示学习旨在学习一系列低维稠密向量来表征语义信息,而知识表示学习是面向知识库中实体和关系的表示学习。当今大规模知识库(或称知识图谱)的构建为许多NLP任务提供了底层支持,但由于其规模庞大且不完备,如何高效存储和补全知识库成为了一项非常重要的任务,这就依托于知识表示学习。
transE算法就是一个非常经典的知识表示学习,用分布式表示(distributed representation)来描述知识库中的三元组。想象一下,这类表示法既避免了庞大的树结构构造,又能通过简单的数学计算获取语义信息,因此成为了当前表示学习的根基。
我们知道知识图谱中的事实是用三元组 ( h , l , t ) (h,l,t) (h,l,t) 表示的,那么如何用低维稠密向量来表示它们,才能得到这种依赖关系呢?transE算法的思想非常简单,它受word2vec平移不变性的启发,希望 h + l ≈ t h+l≈t h+l≈t(此为归纳偏差?)。
光有这一个约束可不够。想让 h + l ≈ t h+l≈t h+l≈t,如何设置损失函数是个关键。我们发现表示学习都没有明显的监督信号,也就是不会明确告诉模型你学到的表示正不正确,那么想要快速收敛就得引入“相对”概念,即相对负例来说,正例的打分要更高,方法学名“negative sampling”。损失函数设计如下:
其中 ( h ′ , l , t ′ ) (h',l,t') (h′,l,t′)称为corrupted triplet,是随机替换头或尾实体得到(非同时,其实也可以替换relation)。 γ \gamma γ为margin。细看发现这就是SVM的soft margin损失函数,所以可以说,transE针对给定三元组进行二分类任务,其中负例是通过替换自行构造的,目标是使得最相近的正负例样本距离最大化。
论文中给出了详细的算法流程:
其中距离度量方式有L1范数和L2范数两种。在测试时,以一个三元组为例,用语料中所有实体替换当前三元组的头实体计算距离 d ( h ′ + l , t ) d(h'+l,t) d(h′+l,t),将结果按升序排序,用正确三元组的排名情况来评估学习效果(同理对尾实体这样做)。度量标准选择hits@10和mean rank,前者代表命中前10的次数/总查询次数,后者代表正确结果排名之和/总查询次数。
还有一点值得一提,文中给了两种测试结果raw和filter,其动机是我们在测试时通过替换得到的三元组并不一定就是负例,可能恰巧替换对了(比如(奥巴马,总统,美国)被替换成了(特朗普,总统,美国)),那么它排名高也是正确的,把当前三元组挤下去也正常。(存疑:这样的话训练时是否也应当过滤corrupted triplet呢) 所以测试时在替换后要检查一下新三元组是否出现在训练集中,是的话就删掉,这就是filter训练方法(不检查的是raw)。
为了更好地理解(其实是因为看不懂别人的),用python简单实现了transE算法,使用数据集FB15k。这里记录一些细节和几个小坑。完整代码见github。
transE效果很好且非常简单,后续大量的工作都是在此基础上的改进(简称trans大礼包),传统方法已经基本不用了(有些思想还是值得借鉴的,比如矩阵分解、双线性模型)。改进大体针对以下几个问题:
理解或实现有错误欢迎指出!
参考文献:
[1] Bordes A, Usunier N, Garcia-Duran A, et al. Translating embeddings for modeling multi-relational data[C]//Advances in neural information processing systems. 2013: 2787-2795.
[2] 刘知远, 孙茂松, 林衍凯, et al. 知识表示学习研究进展[J]. 计算机研究与发展, 2016, 53(2):247-261.