transH算法实现知识图谱补全实验

更新时间:2023-06-09 17:44:57 阅读: 评论:0

transH算法实现知识图谱补全实验
transH算法实现知识图谱补全实验
1. ⽬的
使⽤transH算法进⾏知识图谱补全实验
2. 数据集
本次实验采⽤freeba数据集的FB15k, 该数据集共有,,,和共五个⽂件。实验过程中,训练时主要采⽤,,三个⽂件,测试集使⽤。
3. ⽅法
金鹿角本次实验主要采⽤transH模型进⾏知识图谱补全实验,使⽤pytorch⼯具辅助算法实现。
1. transH算法原理
TransH 模型在 TransE 的基础上为每个关系多学⼀个映射向量, 具体思路是将三元组中的关系(relatio
n),抽象成⼀个向量空间中的超平⾯(Hyperplane),每次都是将头结点或者尾节点映射到这个超平⾯上,再通过超平⾯上的平移向量计算头尾节点的差值。
这样做⼀定程度上缓解了transE模型不能很好地处理⼀对多,多对⼀等关系属性的问题.
2. 具体算法实现
3. 将头节点h和尾节点t映射到超平⾯上,计算三元组的差值
Wr是超平⾯的法向量,dr是超平⾯上的平移向量
2. 将头节点h和尾节点t映射到超平⾯上,计算三元组的差值
3. 计算损失函数
其中[ x ]+ 看做 max(0, x),y为margin值⽤于区分正例与负例。
4. 损失函数通过随机梯度下降法进⾏训练
5. 代码实现过程:(见代码)
数据集训练:
1. 数据集加载,得到实体集,关系集和三元组集
2. 数据预处理,将实体集,关系集和三元组集初始化为向量,计算每个关系中每个头结点平均对应的尾节点数,以及每个尾结点平均对
应的头节点数红尘客栈简谱
3. 初始化transH所需参数,包括向量维度,以及损失函数所需的各种参数
4. 使⽤torch.Tensor()⽅法初始化实体向量,关系向量dr和关系超平⾯法向量Wr
5. 开始分批训练,分成100批数据
6. 计算tph/(tph+hpt),决定负例随机替换掉头节点还是尾节点,由此获得负例集
7. 计算损失函数,使⽤随机梯度下降法调整向量来最⼩化损失函数
8. 更新实体集和关系集中的向量
9. 从第5步开始,重复训练100次,不断降低损失函数的值
10. 得到归⼀化向量的实体集和关系集
4. 指标
测试验证:
1. 求Mean rank值
将每个testing_triple的尾节点⽤实体集中每⼀个实体代替,计算f函数,将得到的结果升序排列,将所有testing triple的排名做平均得到Mean rank
2. 求hit@10值
按照上述进⾏f函数值排列,计算测试集中testing triple正确答案排在序列的前⼗的个数,除以总个数得到hit@10的值
5. 结论
Trans模型是是知识图谱补全算法中经典的算法,TransE模型最为经典但是⽆法很好解决⼀对多,多对⼀的问题,TransH和TransE算法类似,但增加了关系映射超平⾯,⼀定程度上缓解了不能很好地处理多映射属性关系的问题。
代码:
transH_torch.py
import torch随心所欲拼音
import torch.optim as optim
functional as F
import codecs
import numpy as np
import copy
import time
import random
entity2id ={}
relation2id ={}
relation_tph ={}#关系每个头结点平均对应的尾节点数
relation_hpt ={}#关系每个尾结点平均对应的头节点数
'''
数据加载
entity2id: {entity1:id1,entity2:id2}
relation2id: {relation1:id1,relation2:id2}
'''
def data_loader(file):
print("")
file1 =file+""
file2 =file+""
file3 =file+""
with open(file2,'r')as f1,open(file3,'r')as f2:
lines1 = f1.readlines()
lines2 = f2.readlines()
for line in lines1:
line = line.strip().split('\t')
if len(line)!=2:
continue
entity2id[line[0]]= line[1]
for line in lines2:
line = line.strip().split('\t')
if len(line)!=2:
continue
relation2id[line[0]]= line[1]
entity_t =t()#训练集中的所有实体
relation_t =t()#训练集中的所有关系
triple_list =[]#训练集中的所有三元组
relation_head ={}#训练集中的关系的所有头部和头部数量,格式:{r_:{head1:count1,head2:count2}}    relation_tail ={}#训练集中的关系的所有尾部和尾部数量,格式:{r_:{tail1:count1,tail2:count2}}
with codecs.open(file1,'r')as f:
content = f.readlines()
for line in content:
triple = line.strip().split("\t")
if len(triple)!=3:中国的饮食
continue
h_ = entity2id[triple[0]]
t_ = entity2id[triple[1]]
r_ = relation2id[triple[2]]
发疯文学triple_list.append([h_, t_, r_])
entity_t.add(h_)
entity_t.add(t_)
relation_t.add(r_)
if r_ in relation_head:
if h_ in relation_head[r_]:
relation_head[r_][h_]+=1
el:
relation_head[r_][h_]=1
el:
relation_head[r_]={}
relation_head[r_][h_]=1
if r_ in relation_tail:
if t_ in relation_tail[r_]:
relation_tail[r_][t_]+=1
el:
relation_tail[r_][t_]=1走天堂
el:
relation_tail[r_]={}
relation_tail[r_][t_]=1
#计算关系中个头结点平均对应的尾节点数
for r_ in relation_head:
sum1, sum2 =0,0
sum2 += relation_head[r_][head]
tph = sum2/sum1
relation_tph[r_]= tph
#计算关系每个尾结点平均对应的头节点数
for r_ in relation_tail:
离婚协议书样板sum1, sum2 =0,0
for tail in relation_tail[r_]:
sum1 +=1
sum2 += relation_tail[r_][tail]
hpt = sum2/sum1
relation_hpt[r_]= hpt
print("Complete load. entity : %d , relation : %d , triple : %d"%(
len(entity_t),len(relation_t),len(triple_list)))
return entity_t, relation_t, triple_list
class TransH:
def__init__(lf, entity_t, relation_t, triple_list, embedding_dim=50, lr=0.01, margin=1.0, norm=1, C=1.0, epsilon =1e-5):        lf.entities = entity_t  #实体集
lf.dimension = embedding_dim  #向量维度
lf.learning_rate = lr
lf.margin = margin
< = norm
lf.loss =0.0
<_relations ={}#Wr
lf.hyper_relations ={}#dr
lf.C = C  #软约束的权重
lf.epsilon = epsilon  #艾普西隆
def data_initiali(lf):
entityVectorList ={}#实体向量列表
relationNormVectorList ={}
relationHyperVectorList ={}
device ="cpu"
#将实体和关系映射成50维的向量
for entity ities:
entity_vector = torch.Tensor(lf.dimension).uniform_(-6.0/ np.sqrt(lf.dimension),6.0/ np.sqrt(lf.dimension))
entityVectorList[entity]= quires_grad_(True)
for relation lations:
relation_norm_vector = torch.Tensor(lf.dimension).uniform_(-6.0/ np.sqrt(lf.dimension),6.0/ np.sqrt(lf.dimension))            relation_hyper_vector = torch.Tensor(lf.dimension).uniform_(-6.0/ np.sqrt(lf.dimension),6.0/ np.sqrt(lf.dimension))
print(relation_norm_vector)
relationNormVectorList[relation]= relation_quires_grad_(True)
relationHyperVectorList[relation]= relation_quires_grad_(True)
<_relations = relationNormVectorList    #{id:vector,id:vector}
lf.hyper_relations = relationHyperVectorList  #{id:vector,id:vector}
def training_run(lf, epochs=100, nbatches=100):
#每⼀批的数量
batch_size =int(iples)/ nbatches)
print("batch size: ", batch_size)
start = time.time()
#损失
lf.loss =0.0
# Normali the embedding of the entities to 1
# for entity ities:
#    lf.entities[entity] = lf.ities[entity])
#分批处理
for batch in range(nbatches):
#随机抽取batch_size⼤⼩的样本
batch_samples = random.iples, batch_size)
Tbatch =[]
for sample in batch_samples:
#将sample深度拷贝给corrupted_sample
corrupted_sample = copy.deepcopy(sample)
pr = np.random.random(1)[0]#从0到1中随机获得⼀个浮点数
#p表⽰头结点被替换的概率
p = relation_tph[corrupted_sample[2]]/(
relation_tph[corrupted_sample[2]]+ relation_hpt[corrupted_sample[2]])
#pr>p时,head任意改变为另⼀个实体,pr<=p时,tail任意改变为另⼀个实体
if pr > p:
# 随机选择⼀个实体替换头结点corrupted_sample[0]
corrupted_sample[0]= random.ities.keys(),1)[0]
while corrupted_sample[0]== sample[0]:
corrupted_sample[0]= random.ities.keys(),1)[0]
el:
# 随机选择⼀个实体替换尾结点corrupted_sample[1]
corrupted_sample[1]= random.ities.keys(),1)[0]微观学社
while corrupted_sample[1]== sample[1]:
corrupted_sample[1]= random.ities.keys(),1)[0]
# Tbatch加⼊(正例,负例)
if(sample, corrupted_sample)not in Tbatch:
Tbatch.append((sample, corrupted_sample))
#更新
lf.update_triple_embedding(Tbatch)
#结束时间
end = time.time()
print("epoch: ", epoch,"cost time: %s"%(round((end - start),3)))
print("running loss: ", lf.loss)
with codecs.open("entity_"+str(lf.dimension)+"dim_batch"+str(batch_size),"w")as f1:
for e ities:
f1.write(e +"\t")
f1.write(str(ities[e])))
f1.write("\n")
with codecs.open("relation_norm_"+str(lf.dimension)+"dim_batch"+str(batch_size),"w")as f2: for r _relations:
f2.write(r +"\t")
f2.write(str(_relations[r])))
f2.write("\n")
with codecs.open("relation_hyper_"+str(lf.dimension)+"dim_batch"+str(batch_size),"w")as f3: for r in lf.hyper_relations:
f3.write(r +"\t")
f3.write(str(list(lf.hyper_relations[r])))
f3.write("\n")
def normalization(lf, vector):

本文发布于:2023-06-09 17:44:57,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/913110.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:关系   向量   节点   实体
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图