# knowledge_graph_transx_pytorch **Repository Path**: xiaomingzhan/knowledge_graph_transx_pytorch ## Basic Information - **Project Name**: knowledge_graph_transx_pytorch - **Description**: 知识图谱表示学习TransX系列、KG2E等算法的pytorch实现 - **Primary Language**: Python - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2021-09-03 - **Last Updated**: 2021-09-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ### 基于翻译模型(Trans系列)的知识表示学习 *** 【**简介**】实现知识图谱的表示学习方法——`Trans`系列,工程旨在构建完整的数据处理、输入,模型搭建、训练、评估流程,以及实现灵活的模型配置和可视化的训练过程 - 解决问题:知识表示与推理 > 将实体向量表示(Embedding)在低维稠密向量空间中,然后进行计算和推理。 #### 项目结构 ```angular2html knowledge_graph_transx_pytorch transx_torch data --- 放置训练所需数据 train.txt --- 训练集 valid.txt --- 验证集 entity2id.txt --- 实体字典 relation2id.txt --- 关系字典 output --- 项目输出,包含模型、向量表示等 logs --- 日志输出 source --- 源代码 models --- transx模型 config.py --- 项目配置 evaluation.py --- 模型验证 main.py --- 程序入口 preprocessor.py --- 数据预处理 ``` #### 数据预处理 `TransX`模型训练的数据样例为:`头实体 \t 关系 \t 尾实体`。每一行都是一个三元组,`head`,`relation`和`tail`,通过`\t`或者空格隔开。将其放入`transx_torch/data`目录下。为了方便在训练、预测过程中访问实体和关系列表,需要根据训练数据生成实体和对应索引的映射关系,此步骤可以通过多种方式实现,样例数据可见`transx_torch/data/xxx2id.txt`。 #### 模型训练 模型训练需要生成的`实体字典`、`关系字典`、`处理的数据`,将数据放置在`transx_torch/data`目录下,训练代码见`source/main.TransX().train()` #### 向量保存与预测 - 可以将向俩个保存为`txt`文件,通过相似度比较,找出与待查向量相似的节点向量; - 从海量文本中快速查找出相似的`top_k`,可以使用`Annoy`算法 - 构建索引 - 查询-返回最终近邻节点 ``` 官方DEMO from annoy import AnnoyIndex import random f = 40 t = AnnoyIndex(f) # Length of item vector that will be indexed for i in xrange(1000): v = [random.gauss(0, 1) for z in xrange(f)] t.add_item(i, v) t.build(10) # 10 trees t.save('test.ann') # ... u = AnnoyIndex(f) u.load('test.ann') # super fast, will just mmap the file print(u.get_nns_by_item(0, 1000)) # will find the 1000 nearest neighbors ``` - `annoy`函数包使用 - `AnnoyIndex(f, metric='angular')` 初始化新的索引树,元素向量维度为`f`,`Metric`可以是 `angular、euclidean、manhattan、 hamming 、 dot` - `a.add_item(i, v)` 添加向量元素`v`到索引树,其中,`i`应该为非负整数 - `a.build(n_trees)` 建立索引树,`n_trees`表示所建树的个数。树的个数更多,则精度更高,但也要考虑到效率,建立索引树比较耗费时间,一般`n_trees=100`均能满足精度要求 - `a.save(fn, prefault=False)` 保存模型到磁盘上`fn`表示文件路径 - `a.load(fn, prefault=False)`下来模型进行计算,`loads (mmaps) an index from disk. If prefault is set to True, it will pre-read the entire file into memory (using mmap with MAP_POPULATE). Default is False.` - `a.get_nns_by_item(i, n, search_k=-1, include_distances=False)`使用item索引号进行计算,`i`表示item索引号, `n`表示计算要得到的最近邻的item个数 - `a.get_item_vector(i)`:返回之前添加的`item`索引号`i`所对应的向量 - `a.get_n_items()` 返回整个索引树中`item`的数量 - `a.get_n_trees()` 返回整个索引树中树的个数 - `a.get_nns_by_vector(v, n, search_k=-1, include_distances=False)` 使用`item`向量`v`进行计算 - `a.on_disk_build(fn)`将索引树建立到具体文件上,这样建立完树后就不用手动保存 代码见`source/main.TransX().create_annoy_index()`与`source/main.TransX().similarity_topk_annoy()` #### 关于生成负例三元组 - 假设将所有输入正例三元组看成是`shape(N, 3)`的矩阵,按照论文的要求,要么替换`head`,要么替换`tail`,那么可以生成三个中间向量: - `shuffleHead`:将矩阵第一列使用`random.shuffle()`得到的混排的`head`(相当于论文里面所说的随机找一个替换`head`的实体) - `shuffleTail`:将矩阵第三列使用`random.shuffle()`得到的混排的`tail`(相当于论文里面所说的随机找一个替换`tail`的实体) - `replaceDistribution`:使用`random.random((0, 1))`生成长度为`N`的随机数列表 那么可以设定一个阈值`repProba`,如果`replaceDistribution`的值小于`repProba`,那么使用`shuffleHead`对应位置的实体替换原来的头实体,反之,使用`shuffleTail`对应位置的实体替换原来的尾实体。可以看出,当`N`足够大时,产生出来的负样本与正样本碰撞的概率几乎为零,基本符合论文要求。 #### 目前基于翻译模型(Trans系列)的知识表示学习的研究情况 - `TransE, NIPS2013, Translating embeddings for modeling multi-relational data` - `TransH, AAAI2014, Knowledge graph embedding by translating on hyperplanes` - `TransR, AAAI2015, Learning Entity and Relation Embeddings for Knowledge Graph Completion` - `TransD, ACL2015, Knowledge graph embedding via dynamic mapping matrix` - `TransA, arXiv2015, An adaptive approach for knowledge graph embedding` - `TranSparse, AAAI2016, Knowledge graph completion with adaptive sparse transfer matrix` - `TransG, arXiv2015, A Generative Mixture Model for Knowledge Graph Embedding` - `KG2E, CIKM2015, Learning to represent knowledge graphs with gaussian embedding` #### TransE: 多元关系数据嵌入(Translation embeddings for modeling multi-relation data) > 问题:如何建立简单且易拓展的模型把知识库中的实体和关系映射到低维向量空间中,从而计算出隐含的关系? > 方案:将实体与关系嵌入到同一低维向量空间。 提出了一种将实体与关系嵌入到低维向量空间中的简单模型,弥补了传统方法训练复杂、不易拓展的缺点,对实体和关系的建模十分简单明了,可解释性也很强。尽管现在还不清楚是否所有的关系种类都可以被这种方法建模,但目前这种方法相对于其他方法表现不错。在后续的研究中,`TransE`更是作为知识库`vector`化的基础,衍生出来了很多变体。 ![1](.\pic\1.jpg) 受`word2vec`启发,利用了词向量的平移不变现象。将每个三元组实例 (`head,relation,tail`) 中的关系`relation`看做从实体`head`到实体`tail`的翻译,通过不断调整`h、r`和`t `(`head、relation` 和`tail`的向量),使 (`h + r`) 尽可能与`t`相等,即`h + r ≈ t`。数学上表示就是通过约束来对实体和关系建模,将它们映射到相同的向量空间中。 #### TransH: 将知识嵌入到超平面(Knowledge graph embedding by translating on hyperplanes) > 问题:对知识库中的实体关系建模,特别是一对多,多对一,多对多的关系。设计更好的建立负类的办法用于训练。 > 方案:将实体和关系嵌入到同一的向量空间,但实体在不同关系中有不同的表示。 ![2](./pic/2.jpg) #### TransR: 实体和关系分开嵌入(Learning Entity and Relation Embeddings for Knowledge Graph Completion) > 问题:一个实体是多种属性的综合体,不同关系关注实体的不同属性。直觉上一些相似的实体在实体空间中应该彼此靠近,但是同样地,在一些特定的不同的方面在对应的关系空间中应该彼此远离。 > 方案:将实体和关系嵌入到不同的空间中,在对应的关系空间中实现翻译。 ![3](.\pic\3.jpg) #### TransD: 通过动态映射矩阵嵌入(Knowledge graph embedding via dynamic mapping matrix) > 问题:TransR过于复杂,在TransR的基础上减少参数。。。 > 方案:实体和关系映射到不同的空间中,用两个向量表示实体或关系,一个表征实体或关系,另一个用来构造动态映射矩阵。 ![4](.\pic\4.jpg) #### TransA: 自适应的度量函数(An adaptive approach for knowledge graph embedding) > 问题:如何解决了translation-based 知识表示方法存在的过于简化损失度量,没有足够能力去度量/表示知识库中实体/关系的多样性和复杂性的问题。 > 方案:更换度量函数,区别对待向量表示中的各个维度,增加模型表示能力。 ![5](.\pic\5.jpg) 光看这张图可能会意义不明,其实模型在`TransE`的基础上的改进也非常小,简单地说就是给实体/关系的每一个维度都加上了一个权重,增加模型的表示能力。 #### TranSpare: 自适应稀疏转换矩阵(Knowledge graph completion with adaptive sparse transfer matrix) > 问题: heterogeneous(异质性:有的实体关系十分复杂,连接许多不同的实体,而有些关系又非常简单)和unbalanced(不均衡性:很多关系连接的head和tail数目很不对等)。 > 关键:针对不同难度的实体间关系,使用不同稀疏程度的矩阵(不同数量的参数)来进行表征,从而防止对复杂关系欠拟合或者对简单关系过拟合;对头尾两种实体采用不同的投影矩阵,解决头尾实体数目不对等的问题。 ##### 针对异质性(heterogeneous) 在`TransR`的基础上,使用可变的稀疏矩阵代替`TransR`的稠密矩阵:关系连接的实体数量越多,关系越复杂,矩阵约稠密;关系链接的实体数量越少,关系越简单,矩阵约稀疏。 使用参数描述关系的复杂程度,使用一个稀疏矩阵和一个关系向量表示一类关系,其中,表示连接实体数量最多的关系,为其连接的实体的数量,为设置的超参,表示关系的稀疏程度。 ##### 针对不平衡性(unbalanced) 与上述方法类似,不同点在于对于每个关系三元组,头尾实体的映射矩阵为两个不同的稀疏矩阵,其稀疏程度与该关系的头尾实体的数目有关,即头/尾涉及到的实体越多,矩阵约稠密;反之涉及到的实体越少,矩阵越稀疏。 使用参数与分别描述头尾实体映射矩阵的稠密程度,则,其中表示关系在位置(即头或者尾)上关联的实体数量,则表示关系在位置(即头或者尾)上关联的实体数量最多的关系的数量,对应的设置超参表示其稀疏程度。 #### TransG: 高斯混合模型(A Generative Mixture Model for Knowledge Graph Embedding) > 问题:解决多关系语义的问题,同一种关系在语义上是不同的,eg, (Atlantics, HasPart, NewYorkBay)与(Table, HasPart, Leg)。 > 方案:利用贝叶斯非参数高斯混合模型对一个关系生成多个翻译部分,根据三元组的特定语义得到当中的最佳部分。 ![6](.\pic\6.jpg) 考虑到一种关系存在的多语义问题,相当于对关系进行了细化,就是找到关系的隐形含义,最终从细化的结果中选出一个最佳的关系语义。 #### KG2E: 高斯分步表示实体和关系(Learning to represent knowledge graphs with gaussian embedding) > 关键:使用Gaussian Distribution 来表示实体和关系,提出了用Gaussian Distribution的协方差来表示实体和关系的不确定度的新思想,提升了已有模型在link prediction和triplet classification问题上的准确率。 ![7](.\pic\7.jpg)