知识图谱关系抽取与总结展望
Posted ZSYL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识图谱关系抽取与总结展望相关的知识,希望对你有一定的参考价值。
实验介绍
在上一节的实验中【知识图谱】命名实体识别(NLP)我们学习了如何将实体从文本中抽取出来,在实体抽取出来之后得到的是离散的节点,为了构成网状的知识,还需要从文本中提取实体之间的关系。
因此,本实验中将学习如何从文本中抽取实体之间的关系。
在本实验中,你将掌握:
- 关系抽取任务的定义与理论解决方法
- 关系抽取任务中数据集处理方法
- 关系抽取模型——PCNN 的理论知识
- 用 Keras 构建 PCNN
- PCNN 的训练与预测方法
实验原理
关系抽取任务
在本实验中,我们关心的是有监督的关系抽取任务,即已知所有文本中包含的关系种类。此时关系抽取的任务形式就是一个文本分类的问题——任务的输入是一句话以及这句话中包含的两个实体,输出是关系类别。
如文本 “杨康,杨铁心与包惜弱之子,金国六王爷完颜洪烈的养子。” 中,一共有四个人名实体,要获得 “杨康”与“杨铁心” 的关系,那么就要把 “杨康”,“杨铁心”,“杨康,杨铁心与包惜弱之子,金国六王爷完颜洪烈的养子。” 这三个数据都输入到算法中。
数据预处理
首先对数据进行位置编码,按句子中各个词离实体的距离进行编码。 如 “杨康,杨铁心与包惜弱之子,金国六王爷完颜洪烈的养子。” 中,实体为“杨康”和“杨铁心”。然后记录句子中每个字与实体首字之间的距离。
如:
杨 康 , 杨 铁 心 与 包 惜 弱 之 子 , 金 国 六 王 爷 完 颜 洪 烈 的 养 子 。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
pos_1=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25]
,0 就是杨康的起始位置
杨 康 , 杨 铁 心 与 包 惜 弱 之 子 , 金 国 六 王 爷 完 颜 洪 烈 的 养 子 。
-3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
pos_2=[-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22]
,0 就是杨铁心的起始位置
实验步骤
先安装需要的包:
pip install tensorflow==1.13.1
pip install keras==2.1.6
Tensorflow 2.0 最新版(2.4.1) 安装教程
数据处理
原始文本和标签定义为:
# 对于 lists 中每一个子列表,第一个元素为实体1,第二个元素为实体2,第三个元素为实体1对实体2的关系,第四个元素为文本。
lists = [['杨康','杨铁心','子女','杨康,杨铁心与包惜弱之子,金国六王爷完颜洪烈的养子。'],
['杨康','杨铁心','子女','丘处机与杨铁心、郭啸天结识后,以勿忘“靖康之耻”替杨铁心的儿子杨康取名。'],
['杨铁心','包惜弱','配偶','金国六王爷完颜洪烈因为贪图杨铁心的妻子包惜弱的美色,杀害了郭靖的父亲郭啸天。'],
['杨铁心','包惜弱','配偶','杨康,杨铁心与包惜弱之子,金国六王爷完颜洪烈的养子。'],
['张翠山','殷素素','配偶','张无忌,武当七侠之一张翠山与天鹰教紫微堂主殷素素之子。'],
['小龙女','杨过','师傅','小龙女是杨过的师父,与杨过互生情愫,但因师生恋不容于世。'],
['黄药师','黄蓉','父','黄药师,黄蓉之父,对其妻冯氏(小字阿衡)一往情深。'],
['郭啸天','郭靖','父','郭靖之父郭啸天和其义弟杨铁心因被段天德陷害,死于临安牛家村。']]
relation2idx = {'子女':0,'配偶':1,'师傅':2,'父':3}
lists, relation2idx
首先,我们先将 lists
中的实体、关系与文本都单独拆分开来,并对文本进行位置编码。
datas, labels, pos_list1, pos_list2 = [], [], [], []
translation = 32
for entity1, entity2, relation, text in lists:
# 找到第一个实体出现的下标
idx1 = text.index(entity1)
# 找到第二个实体出现的下标
idx2 = text.index(entity2)
sentence, pos1, pos2 = [], [], []
for i, w in enumerate(text):
sentence.append(w)
# 计算句子中每个字与实体1首字的距离
pos1.append(i-idx1+translation)
# 计算句子中每个字与实体2首字的距离
pos2.append(i-idx2+translation)
datas.append(sentence)
labels.append(relation2idx[relation])
pos_list1.append(pos1)
pos_list2.append(pos2)
datas, labels, pos_list1, pos_list2
from collections import Counter
# 统计每个字出现的次数, sum(datas,[]) 的功能是将列表铺平
word_counts = Counter(sum(datas, []))
# 建立字典表,只记录出现次数不小于 2 的字
vocab = [w for w, f in iter(word_counts.items()) if f >= 2]
word_counts, vocab
# 构建词袋模型,和上一节实验相同,将字典从 2 开始编号,把 0 和 1 空出来,0 作为填充元素,1 作为不在字典中的字的编号
word2idx = dict((w,i+2) for i,w in enumerate(vocab))
word2idx
import numpy as np
from keras.preprocessing.sequence import pad_sequences
from keras.utils.np_utils import to_categorical
# 构建输入,即对于样本中每一个字,从词袋模型中找到这个字对应的 idx,出现频率过低的字,并没有出现在词袋模型中,此时将这些字的 idx 取为 1
train_x = [[word2idx.get(w, 1) for w in s] for s in datas]
max_len = 64
# 在输入的左边填充 0
train_x = pad_sequences(train_x, max_len, value=0)
## 填充位置编码
train_pos1 = pad_sequences(pos_list1, max_len, value=0)
train_pos2 = pad_sequences(pos_list2, max_len, value=0)
# one_hot 编码 label
train_y = to_categorical(labels, num_classes=len(relation2idx))
train_x.shape, train_y.shape, train_pos1.shape, train_pos2.shape
构建网络模型
因为网络有多个输入:文本与位置编码,属于复杂模型,因此我们这里使用 Keras 的函数式 API 来定义网络结构
from keras.layers import Input, Embedding, concatenate, Conv1D, GlobalMaxPool1D, Dense, LSTM
from keras.models import Model
# 定义输入层
words = Input(shape=(max_len,),dtype='int32')
position1 = Input(shape=(max_len,),dtype='int32')
position2 = Input(shape=(max_len,),dtype='int32')
# Embedding 层将输入进行编码
pos_emb1 = Embedding(output_dim=16, input_dim=256)(position1)
pos_emb2 = Embedding(output_dim=16, input_dim=256)(position2)
word_emb = Embedding(output_dim=16, input_dim=256)(words)
# 分别拼接 文本编码与位置1 和文本编码与位置2
concat1 = concatenate([word_emb, pos_emb1])
concat2 = concatenate([word_emb, pos_emb2])
# 卷积池化层
conv1 = Conv1D(filters=128, kernel_size=3)(concat1)
pool1 = GlobalMaxPool1D()(conv1)
conv2 = Conv1D(filters=128, kernel_size=3)(concat2)
pool2 = GlobalMaxPool1D()(conv2)
# 拼接,最后接全连接层,激活函数为 softmax
concat = concatenate([pool1, pool2])
out = Dense(units=len(relation2idx),activation='softmax')(concat)
model = Model(inputs=[words, position1, position2],outputs=out)
# 编译模型
model.compile(optimizer='ADAM', loss='categorical_crossentropy', metrics=['accuracy'])
model.summary()
# 训练 50 次
model.fit([train_x, train_pos1, train_pos2], train_y, batch_size=8, epochs=50)
model.save('model.h5')
模型预测
在这里我们使用训练集中的一个实例进行预测
test_instance = ['张翠山','殷素素','张无忌,武当七侠之一张翠山与天鹰教紫微堂主殷素素之子。']
test_ne1, test_ne2, test_text = test_instance
test_ne1, test_ne2, test_text
# 将预测数据转换为向量
pred_x = [word2idx.get(w, 1) for w in test_text]
idx1 = test_text.index(test_ne1)
idx2 = test_text.index(test_ne2)
pos1 = [i-idx1+translation for i in range(len(test_text))]
pos2 = [i-idx2+translation for i in range(len(test_text))]
pred_x = pad_sequences([pred_x], max_len, value=0)
test_pos1 = pad_sequences([pos1], max_len, value=0)
test_pos2 = pad_sequences([pos2], max_len, value=0)
pred_x, test_pos1, test_pos2
# 翻转 relation2idx 字典
idx2relation = dict(zip(relation2idx.values(),relation2idx.keys()))
# 使用模型进行预测
pred = model.predict([pred_x, test_pos1, test_pos2])
# 模型预测最大值的位置作为预测值
output_idx = np.argmax(pred)
# 找到 idx2relation 中实际的标签
output_label = idx2relation[output_idx]
pred, output_idx, output_label
总结展望
在本实验中,我们了解了关系抽取任务的定义,并使用了一个小型的神经网络来实现关系抽取任务中的数据处理、训练与预测。
由于小型的神经网络的参数量较少,拟合能力有限,从而随着训练数据量的增加就会出现欠拟合的现象。因此,用少量数据集在小型网络上训练完成后,再逐渐增大数据量,同时将小型网络复杂化,如使用现有的 PCNN,Attention-BiLSTM 等用于关系抽取的经典神经网络结构,将任务的精度提升到我们想要的结果。
展望未来
在本课程中,我们采用了“知识图谱是什么”,“知识图谱怎么用”,“知识图谱是怎么生成的”的顺序进行学习。
-
第一步介绍了知识图谱的基本知识与构成,然后通过《射雕三部曲》中的人物图谱,来掌握
Neo4j
的使用方法,在掌握使用方法后,再学习操作Neo4j
的Cypher
语言与Python
驱动py2neo
。 -
第二步则是学习如何通过结构化数据生成知识图谱,在本实验中使用了两种方法,
load csv
和neo4j-import
。 -
第三步是构建知识图谱最基础的一步,即提取结构化数据。
实际应用
在实际的项目中,构建知识图谱的顺序正好与本课程相反,先要提取结构化数据,然后构建知识图谱,最后用 Cypher 语法进行查询。
结构化数据
在结构化数据的过程中,除了会使用到本课程中的命名实体识别和关系抽取外,还可能用到的技术有:
- 属性抽取
属性抽取主要是针对实体,通过属性来形成对实体的完整刻画。由于实体的属性可以看成是实体与属性值之间的一种名称关系,因此也可以将实体属性的抽取问题转换为关系抽取问题。
- 实体消歧
实体消歧用于解决同名实体产生的歧义,如在金庸小说《神雕侠侣》中有位女性角色“林朝英”,是古墓派的开山祖师,同时在古龙的小说中有一位男性角色叫做“林朝英”,因此需要通过实体消歧,根据当前语境,准确地建立实体链接。
- 共指消解
共指消解与实体消歧相反,主要用于解决多个称呼对应于同一实体对象的问题,如“靖哥哥”,“靖儿”,“郭靖”等指称都指向同一个实体对象。
知识推理
知识推理则是在已有的知识库的基础上进一步挖掘隐含的知识,从而丰富、扩展知识库,如在知识库中存在两个三元组(郭啸天,父亲,郭靖),(郭靖,父亲,郭襄),那么就可以推理出(郭啸天,祖父,郭襄)。
知识推理的主要方法有基于逻辑的推理和基于图的推理。
应用领域
- 智能搜索
传统的搜索引擎,在一定程度上解决了用户从互联网中获取信息的难题,但由于它们是基于关键词或字符串的,并没有对查询的目标(通常为网页)和用户的查询输入进行理解。例如,用户用自然语言搜索“谁会降龙十八掌”,智能搜索引擎能够理解用户的意图,并结合知识图谱以图文并茂的形式把答案“乔峰,洪七公,郭靖,宋青书”呈现给用户。
- 社交网络
Facebook 于 2013 年推出了 Graph Search 产品,其核心技术就是通过知识图谱将人,地点,事情等联系在一起形成一张社交网络,在新角色加入时,给新角色推荐社交网络中最相似的节点。比如构建完金庸角色的知识图谱后,问到“你认为你最像金庸武侠小说中哪一个人物?”时,就可以将自己转换为一个知识图谱,再去金庸角色的知识图谱中进行匹配,找到最相似的子图。
- 垂直行业应用
-
金融行业
金融知识图谱,可以为风险评估、预测、反欺诈、精准营销、智能搜索和数据可视化等提供技术支撑。越来越多的金融机构及企业在探索构建金融领域的知识图谱研究,将海量非结构化信息自动化利用起来,为金融领域应用决策提供更精准、更可靠的依据。 -
医疗行业
随着医疗大数据时代的到来,如何从海量的数据中提取有用的医学知识,是医疗大数据分析的关键。知识图谱技术提供了一种从海量文本和图像中抽取结构化知识的手段,如病历结构化,临床决策支持系统,全科机器人医生等。
知识图谱的重要性不仅在于它是一个全局知识库,是支撑智能搜索和深度问答等智能应用的基础,而且在于它是一把钥匙,能够打开人类的知识宝库,为许多相关学科领域开启新的发展机会。从这个意义上来看,知识图谱不仅是一项技术,更是一项战略资产。本课程的主要目的是介绍和宣传这项技术,希望吸引更多人重视和投入这项研究工作。
参考文献
刘峤,李杨,段宏,刘瑶,秦志光.知识图谱构建技术综述[J].计算机研究与发展,2016,53(03):582-600.
徐增林,盛泳潘,贺丽荣,王雅芳.知识图谱技术综述[J].电子科技大学学报,2016,45(04):589-606.
All Link
以上内容摘自蓝桥云课,感谢其带领我初识知识图谱,希望随着学习的深入,我可以有更大的理解与进步。
加油!
以上是关于知识图谱关系抽取与总结展望的主要内容,如果未能解决你的问题,请参考以下文章