详情请参考 知乎专栏
“奥巴马出生在火奴鲁鲁。”, “姚明是中国人。”,“谢霆锋的爸爸是谢贤。”
这些就是一条条知识,而把大量的知识汇聚起来就成为了知识库。我们可以在wiki百科,百度百科等百科全书查阅到大量的知识。然而,这些百科全书的知识组建形式是非结构化的自然语言,这样的组织方式很适合人们阅读但并不适合计算机去处理。为了方便计算机的处理和理解,我们需要更加形式化、简洁化的方式去表示知识,那就是三元组(triple)。
“奥巴马出生在火奴鲁鲁。” 可以用三元组表示为 (BarackObama, PlaceOfBirth, Honolulu)。
这里我们可以简单的把三元组理解为 (实体entity,实体关系relation,实体entity),进一步的,如果我们把实体看作是结点,把实体关系(包括属性,类别等等)看作是一条边,那么包含了大量三元组的知识库就成为了一个庞大的知识图。
Extracted KBs 知识库涉及到的两大关键技术是
知识库问答(knowledge base question answering,KB-QA)即给定自然语言问题,通过对问题进行语义理解和解析,进而利用知识库进行查询、推理得出答案.
与对话系统、对话机器人的交互式对话不同,KB-QA具有以下特点:
当我们在百度询问 2016年奥斯卡最佳男主角 时,百度会根据知识库进行查询和推理,返回答案,这其实就是KB-QA的一个应用。
关于KB-QA的方法,传统的主流方法可以分为三类:
随着深度学习(Deep Learning)在⾃然语⾔处理领域的⻜速发展,从15年开始,开始涌现出⼀系列基 于深度学习的KB-QA⽂章,通过深度学习对传统的⽅法进⾏提升,取得了较好的效果。
使⽤卷积神经⽹络对向量建模⽅法进⾏提升,使⽤卷积神经⽹络对语义解析⽅法进⾏提升,使⽤⻓短时记忆⽹络(LSTM),卷积神经⽹络共同进⾏实体关系分类,使⽤记忆⽹络(Memory Networks),注意⼒机制(Attention Mechanism)进⾏KB-QA。
直到2018年底,BERT对NLP的巨⼤突破,使得⽤BERT进⾏KB-QA也取得了较好的效果。本项⽬基于BERT模型实现。
本项目的主要目标是,构建一个知识库问答系统,从用户所提出的问题,对知识库进行检索,返回一个确定的答案,如果没有答案的 返回 无答案。
NLPCC全称⾃然语⾔处理与中⽂计算会议(The Conference on Natural Language Processing and Chinese Computing),它是由中国计算机学会(CCF)主办的 CCF 中⽂信息技术专业委员会年度学术会议,专注于⾃然语⾔处理及中⽂计算领域的学术和应⽤创新。
本项目的数据集采用的是NLPCC2017的Task5:Open Domain Question Answering;其包含 14,609 个问答对的训练集和包含 9870 个问答对的测试集。并提供一个知识库,包含 6,502,738 个实体、 587,875 个属性以及 43,063,796 个三元组。
NLPCC2017_task5
数据集格式如下:
请参考文件 preProcessData/createTrainingData.py
里面包含2 步, 1) 构建命名实体识别数据集, 2) 构建相似度训练数据集
构造命名实体识别NER数据集, 需要根据三元组-Enitity反向标注问题,给Question 打标签, 这里只需要识别实体,使用[’“O”, “B-LOC”, “I-LOC”]来做标记,其中O 表示其他非实体,B-LOC 实体开始,I-LOC 实体 非首字母。
生成结果放到 NERData 文件夹下面, 点开 train.txt 可以看到NERdata 结构如下:
构造知识库,主要提取原始数据集中的 作为知识库,传进database 里面,用于当检索。
构造正负样本,用于问题和属性相似度的训练。当用户输入问题时,第一个通过命名实体识别提取出实体, 进行数据库查询,有可能得到多条信息,因为一个实体会对应很多属性。 此时通过问题和属性相似度训练模型进行属性选择,选择一个与用户输入问题 最相近的属性,将答案返回。
构造的数据集如下: 一个正样本,五个负样本。
其中问题和属性 作为 seq1 和 seq2 输入BertForSequenceClassification 进行训练。
Ubuntu mysql 安装 请参考 链接: Ubuntu mysql 安装
使用请参考 Ubuntu mysql使用方法
python 操作mysqlubuntu python mysql
本项目用的是 hunggingface的Transformers版本的BERT .
思路:
transformers 自带的BertForTokenClassification 正好满足第一步和第二步的需求. 因为这里我们只需要获取输出的hidden,不需要计算损失,所以BERT的输入中不需要输入target label, 当没有label输入时, BertForTokenClassification的输出 第一项就是我们想要的结果 emission(batch_size, seq_len, num_labels=3). 请见代码:
emissions = self.bertModel(input_ids = input_ids,attention_mask = attention_mask, token_type_ids=token_type_ids)[0]
该模型是用来从问题中提取属性的。
当一个问题来的时候,我们第一步通过命名实体识别提取实体名,第二步要确认问题的属性。关于属性的确认就是通过分类模型来得到。
该模式输入是序列如下:[CLS] 问题 [SEP] 属性[SEP].
数据集就是上面构造的similarity 数据集,每一个正样本,对应有五个负样本。
通过二分类模型,进行 ‘问题’ 和 ‘属性’ 的相似度训练。
这里采用的是transformers 自带的BertForSequenceClassification. 这是一个在BERT基础上 添加一个序列分类 用于微调的模型。 大题步骤: 1. BertModel得到output 即最后一层的hidden_state(shape: batch_size, seq_len, hidden_size),取最后一层hidden_state的第一个token用于分类(batch_size, hidden_size) 2. 通过线性变换,将分类token 由 hidden_size 转成 num_labels, 此处num_labels = 2 即正负样本(0,1),与真实label计算交叉熵损失。
参考:
基于知识图谱的问答系统入门—NLPCC2016KBQA数据集
知乎专栏
问答QA(二)基于BERT的知识库问答实战
基于BERT模型的知识库问答(KBQA)系统