Task 4用户输入->摘要的查询语句

文章编写人:王翔
github地址:
特别鸣谢:QASystemOnMedicalGraph

目录

  • Datawhale知识图谱组队学习之Task 4用户输入->摘要的查询语句

    • 目录
    • 一,引言
    • 二,什么是问答系统?
      • 2.1问答系统简介
      • 2.2查询理解
        • 2.2.1查询理解介绍
        • 2.2.2预设识别
        • 2.2.3槽值填充
    • 三,任务实践
      • 四,主体类EntityExtractor框架介绍
    • 五,命名实体识别任务实践
      • 5.1命名实体识别整体思路介绍
      • 5.2结合代码介绍
        • 5.2.1建立AC树
        • 5.2.2使用AC树进行问句过滤
        • 5.2.3使用相似度进行实体匹配
    • 六,旨在识别任务实践
      • 6.1识别识别整体思路介绍
      • 6.2识别识别整体思路介绍
        • 6.2.1特征建构
        • 6.2.2使用朴素贝叶斯进行文本分类
    • 参考资料

一,引言

本部分任务主要是将用户输入问答系统的自然语言转换成合并的查询语句,因此本文将分为两部分进行介绍。

  • 第一部分介绍任务所涉及的背景知识;
  • 第二部分则是相应的代码和其注释

二,什么是问答系统?

2.1问答系统简介

问答系统(Question Answering System,QA System)是用来回答人提出的自然语言问题的系统。根据划分标准不同,问答系统可以被分为各种不同的类型。

  • 问答系统从知识领域划分:

    • 封闭领域:封闭领域系统专注于回答特定领域的问题,由于问题领域改变,系统有比较大的发挥空间,可以引入领域知识或将答案全部转换成结构性资料来有效提升系统的表现;
    • 开放领域:开放领域系统则希望不设限问题的内容范围,因此其困难也相对阻碍。
  • 问答系统从实现方式划分:

    • 基于流水线(pipeline)实现:如下图1所示,基于流水线实现的问答系统有四大核心模块,分别由自然语言理解(NLU),对话状态跟踪器(DST),对话策略(DPL)和自然语言生成(NLG)顺序层叠构成的一条流水线,各模块可独立设计,模块间协作完成任务。
    • 基于端到端(端到端)实现:基于端到端实现的问答系统,主要是结合深度学习技术,通过海量数据训练,挖掘出从用户自然语言输入到系统自然语言输出的整体映射关系,而忽略中间过程的一种方法。但就目前工业界整体应用而言,工业界的问答系统主要采用的还是基于流水线实现的方式。

图1基于流水线(pipeline)实现

  • 问答系统从答案来源划分:

    • 知识库(知识库基础知识问答,KB-QA)即给定自然语言问题,通过对问题进行语义理解和解析,以及利用合并进行查询,推理得出答案。如下图2所示:
    • 「常问问题问答」;
    • 「新闻问答」;
    • 「网际网路问答」;

图2知识库问答

2.2查询理解

2.2.1查询理解介绍

查询理解(QU,Query谅解),简单来说就是从词法,句法,语义三个维度对查询进行结构化解析。

  • 搜索查询理解包含的模块主要有:

    • 查询预
    • 查询纠错
    • 查询扩展
    • 查询归一
    • 本质识别
    • 槽值填充
    • 术语预期分析;
    • ...

由于本任务后面的代码主要涉及识别识别和槽位解析,因此这里仅对这两部分内容做介绍:

2.2.2预设识别

  • 简介:最初识别是用于检测用户当前输入的前缀,通常其被建模为将一段自然语言文本分类为预先定义的一个或多个替代的文本分类任务。
  • 所用方法:和文本分类模型的方法大同小异,主要有:
    • 基于词典模板的规则分类
    • 传统的机器学习模型(文本特征工程+分类器)
    • 深度学习模型(文字,TextCNN,BiLSTM +自我注意,BERT等)

图3基本意义

2.2.3槽值填充

  • 引入:槽值填充就是根据我们既定的一些结构化细分,将用户输入的信息中对应的对应的部分提取出来。因此,槽值填充经常被建模为序列标注的任务。
  • 表示介绍:例如下图所示的查询“北京飞成都的机票”,通过排序分类模型可以识别出查询整体整体是订机票,在此基础上进一步语义解析出对应的出发地Depart =“北京” ,到达地Arrive =“成都”,所以生成的形式化表达可以是:Ticket = Order(Depart,Arrive),Depart = {北京},Arrive = {成都}。

图4槽值填充

  • 序列标注的任务常用的模型有:【注:这部分内容,第二期知识图谱组队学习将进行介绍】

    • 词典匹配
    • BiLSTM + CRF;
    • 网络
    • BERT等。

三,任务实践

图5基于知识图谱的问答系统框架

四,主体类EntityExtractor框架介绍

#!/ usr / bin / env python3
#编码:UTF -8
进口OS
进口ahocorasick
从sklearn.externals进口JOBLIB
进口解霸
进口numpy的为NPEntityExtractor类:def __init __():通过#构造actree,加速过滤def build_actree(self,wordlist):“”“构造actree,加速过滤:param wordlist ::return:”“”通过#模式匹配,得到匹配的词和类型。如疾病,疾病别名,并发症,症状defentity_reg(自我,问题):“”“模式匹配,得到匹配的词和类型。如疾病,疾病别名,并发症,症状:param question:str :return:”“”通过#当全匹配失败时,就采用相似度计算来找相似的词def find_sim_words(自我,问题):“”当全匹配失败时,就采用相似度计算来找相似的词:param问题::返回:“”“通过#采用DP方法计算编辑距离def editDistanceDP(self,s1,s2):“”“采用DP方法计算编辑距离:param s1 ::param s2 ::return:”“”通过#计算单词和字典中的词的相似度def simCal(自身,单词,实体,标志):“”“计算词和字典中的词的相似度相同
字符的个数/ min(| A |,| B |)+余弦相似度        :param字词:str :param实体:列表:返回值:”“”通过#基于特征词分类def check_words(自己,wds,已发送):“”“基于特征词分类:param wds ::param发送::return:”“”通过#提取问题的TF-IDF特征def tfidf_features(self,text,vectorizer):“”“提取问题的TF-IDF特征:param text ::param vectorizer ::return:”“”通过#提取问题的关键字特征def other_features(self,text):“”“提取问题的关键字特征:param text ::return:”“”通过#预测推测def model_predict(self,x,model):“”“预测变量:param x ::param model ::return:”“”通过#实体撤主函数def提取器(自己,问题):通过

五,命名实体识别任务实践

5.1命名实体识别整体思路介绍

  • 步骤1:对于用户的输入,先使用预先合并的疾病,疾病别名,并发症和症状的AC Tree进行匹配;
  • 步骤2:若全都无法匹配到相应实体,则使用结巴切词库对用户输入的文本进行切分;
  • 步骤3:然后将每一个单词都去与疾病词库,疾病别名词库,并发症词库和症状词库中的词计算相似度重叠(重叠分数,余弦相似度分数和编辑距离分数),如果相似度超过0.7,则认为该词是这一类实体;
  • 步骤4:最后排序选取最相关的词作为实体(项目所有的实体类型如下图所示,但实体识别时仅使用了疾病,别名,关联和症状和实体)

图6实体介绍

本部分所有的代码都来自entity_extractor.py中的EntityExtractor类,为了方便讲解,对类内的内容进行重新组织注释

5.2结合代码介绍

5.2.1建立AC树

先通过entity_extractor.py中类EntityExtractor的build_actree函数编译AC树

  • 功能模块
    def build_actree(self,wordlist):“”“构造actree,加速过滤:param wordlist ::return:”“”actree = ahocorasick.Automaton()#向树中添加单词对于 index,在enumerate(wordlist)中的单词:actree.add_word(word,(index,word))actree.make_automaton()返还行为
  • 函数调用模块
    def __init __():...self.disease_path = cur_dir +'disease_vocab.txt'self.symptom_path = cur_dir +'symptom_vocab.txt'self.alias_path = cur_dir +'alias_vocab.txt'self.complication_path = cur_dir +'complications_vocab.txt'self.disease_entities = [w.strip()为 瓦特在开放(self.disease_path,编码= 'UTF8')若w.strip()]self.symptom_entities = [w.strip()for  w in open(self.symptom_path,encoding ='utf8')如果w.strip()self.alias_entities = [w.strip()for  w in open(self.alias_path,encoding ='utf8')如果w.strip()self.complication_entities = [w.strip()for  w in open(self.complication_path,如果w.strip(),编码为'utf8')]self.region_words = list(设置(self.disease_entities + self.alias_entities + self.symptom_entities))#构造领域self.disease_tree = self.build_actree(list(set(self.disease_entities)))self.alias_tree = self.build_actree(list(set(self.alias_entities)))self.symptom_tree = self.build_actree(list(set(self.symptom_entities)))self.complication_tree = self.build_actree(list(set(self.complication_entities)))...

5.2.2使用AC树进行问句过滤

  • 功能模块
    defEntity_reg(self,问题):“”“模式匹配,得到匹配的词和类型。如疾病,疾病别名,并发症,症状:param question:str :return:”“”self.result = {}为 我在self.disease_tree.iter(问题)中:字= i [ 1 ] [ 1 ]如果“疾病” 不在self.result中:self.result [ “疾病” ] = [单词]其他:self.result [ “ Disease” ] .append(word)为 我在self.alias_tree.iter(question)中:字= i [ 1 ] [ 1 ]如果“别名” 不在self.result中:self.result [ “ Alias” ] = [word]其他:self.result [ “ Alias” ] .append(word)为 我在self.symptom_tree.iter(问题)中:wd = i [ 1 ] [ 1 ]如果“症状” 不在self.result中:self.result [ “症状” ] = [wd]其他:self.result [ “症状” ] .append(wd)为 我在self.complication_tree.iter(问题)中:wd = i [ 1 ] [ 1 ]如果“并发症” 不在self.result中:self.result [ “ complication” ] = [wd]其他:self.result [ “ complication” ] .append(wd)返回自我结果
  • 函数调用模块
    def提取器(自己,问题):self.entity_reg(问题)...

5.2.3使用相似度进行实体匹配

当AC Tree的匹配都没有匹配到实体时,使用查找相似词的方式进行实体匹配

def find_sim_words(self,question):“”“当全匹配失败时,就采用相似度计算来找相似的词:param question ::return:”“”汇入导入字符串从gensim.models导入KeyedVectors#使用结巴加载自定义词典jieba.load_userdict(self.vocab_path)#加载词向量self.model = KeyedVectors.load_word2vec_format(self.word2vec_path,binary = False)#数据预处理,正则去除特殊符号句子= re。sub(“ [{}]”,re.escape(string。标点符号),问题)句子= re。sub(“ [,。”;:?,!【【】]“,”“,句子)句子=句子.strip()#使用结巴进行分词词语= [w.strip()为 瓦特在jieba.cut(句子)如果w.strip()未在self.stopwords和LEN(w.strip())> = 2 ]alist = []#对每个词,都让其与每类实体词典进行相似对比,#最终挑选分数最高的实体和其属于的实体类型对于 单词的词:temp = [self.disease_entities,self.alias_entities,self.symptom_entities,self.complication_entities]对于 我在范围内(len(temp)):标志=''如果i == 0:标志= “疾病” elif i == 1:flag = “ Alias” elif i == 2:标志= “症状”其他:标志= “并发症”分数= self.simCal(单词,temp [i],标志)alist.extend(分数)temp1 =排序(alist,key = lambda k:k [ 1 ],reverse = True)如果temp1:self.result [temp1 [ 0 ] [ 2 ]] = [temp1 [ 0 ] [ 0 ]]#计算单词和字典中的词的相似度
def simCal(self,word,Entity,flag):“”“计算词和字典中的词的相似度相同字符的个数/ min(| A |,| B |)+余弦相似度:param word:str :param实体:列表:return:“”“a = len(字)分数= []对于 实体中的实体:sim_num = 0b = len(实体)c = len(set(entity + word))临时= []对于 w而言:如果w在实体中:sim_num + = 1如果sim_num!= 0:score1 = sim_num / c#重叠分数temp.append(score1)尝试:score2 = self.model.similarity(单词,实体)#余弦相似度分数temp.append(score2)除:通过score3 = 1 -self.editDistanceDP(word,实体)/(a + b)#编辑距离分数如果score3:temp.append(score3)得分=总和(温度)/ len(温度)如果分数> = 0。7:scores.append((实体,得分,标志))scores.sort(key = lambda k:k [ 1 ],reverse = True)回报分数

六,旨在识别任务实践

6.1识别识别整体思路介绍

  • 步骤1:利用TF-IDF文字特征,同时建立一些人工特征(每一类连续常见词在句子中出现的个数);
  • 步骤2:训练朴素贝叶斯模型进行连续识别任务;
  • 步骤3:使用实体资讯进行预设的校正和补充。

图7估计识别整体模仿介绍

该项目通过手工标记210条预期分类训练数据,并采用朴素贝叶斯算法训练得到分类模型。其最佳测试效果的F1值达到了96.68%。

6.2识别识别整体思路介绍

6.2.1特征建构

  1. TF-IDF特征
#提取问题的TF-IDF特征
def tfidf_features(self,text,vectorizer):“”“提取问题的TF-IDF特征:param text ::param vectorizer ::return:”“”jieba.load_userdict(self.vocab_path)词语= [w.strip()为 瓦特在jieba.cut(文本)如果w.strip()和w.strip()未在self.stopwords]sends = [''.join(words)]tfidf = vectorizer.transform(sents).toarray()返回tfidf
  1. 人工特征
self .symptom_qwds = ['什么症状','什么样的症状','症状有什么','症状是什么','什么表征','某种表征','表征是什么',“什么现象”,“某种现象”,“现象有什么”,“症候”,“什么表现”,“某种表现”,“表现有什么”,'什么行为','某种行为','行为有什么','什么状况','某种状况','状况有什么','现象是什么','表现是什么','行为是什么']#询问症状
self .cureway_qwds = [ '药','药品','用药','胶囊','口服液','炎片','吃什么药','用什么药','怎么办',“买什么药”,“怎么治疗”,“如何医治”,“怎么医治”,“怎么治”,“怎么医”,“如何治”,'医治方式','疗法','咋治','咋办','咋治','治疗方法']#询问治疗方法
self .lasttime_qwds = ['周期','多久','多延长','多少时间','几天','几年','多少天','多少小时','几个小时','多少年','多久能好','痊愈','康复']#询问治疗周期
self .cureprob_qwds = ['多大概率能治好','多大几率能治好','治好希望大么','几率','几成','比例','可能','能治','可治','可以治','可以医','能治好吗','可以治好吗','会好吗','能好吗','治愈吗']#询问治愈率
self .check_qwds = ['检查什么','检查项目','某些检查','什么检查','检查该','项目','检测什么',“某种检测”,“检测某​​些”,“化验什么”,“什么化验”,“化验某些”,“某些体检”,“如何查找”,'如何查找','如何检查','如何检查','如何检测','如何检测']#询问检查项目
self .belong_qwds = ['属于什么科','什么科','科室','挂什么','挂哪个','该科','其中科']#询问
科室self .disase_qwds = ['什么病”,“啥病”,“得了什么”,“得了某种”,“怎么回事”,“咋回事”,“回事”,'什么情况','什么问题','什么毛病','啥毛病','这类病']#询问疾病def other_features(self,text):“”“提取问题的关键字特征:param text ::return:”“” features = [ 0 ] * 7 for  self.disase_qwds中的d:如果d在文本中:功能[ 0 ] + = 1对于 self.symptom_qwds中的s:如果s在文本中:功能[ 1 ] + = 1对于 self.cureway_qwds中的c:如果c在文本中:功能[ 2 ] + = 1对于 self.check_qwds中的c:如果c在文本中:features [ 3 ] + = 1 for  self.lasttime_qwds中的p:如果p在文本中:功能[ 4 ] + = 1对于 self.cureprob_qwds中的r:如果r在文字中:功能[ 5 ] + = 1对于 self.belong_qwds中的d:如果d在文本中:功能[ 6 ] + = 1m =最大(特征)n =最小值(特征)normed_features = []如果m == n:normed_features =功能其他:对于 我而言,功能:j =(i-n)/(m-n)normed_features.append(j)返回np.array(normed_features)

6.2.2使用朴素贝叶斯进行文本分类

  • 项目没有提出训练过程,可参考以下sklearn的例子
    #项目没有提出训练过程,可参考以下sklearn的例子从sklearn.naive_bayes导入MultinomialNB mnb = MultinomialNB()   mnb.fit(X_train,y_train)   y_predict = mnb.predict(X_test)#初步分类模型文件self.tfidf_path = os.path.join(cur_dir,'model / tfidf_model.m')self.nb_path = os.path.join(cur_dir,'model / intent_reg_model.m')#朴素贝叶斯模型self.tfidf_model = joblib.load(self.tfidf_path)self.nb_model = joblib.load(self.nb_path)#初步预测tfidf_feature = self.tfidf_features(问题,self.tfidf_model)other_feature = self.other_features(问题)m = other_feature.shapeother_feature = np.reshape(other_feature,(1,m [ 0 ]))功能= np.concatenate((tfidf_feature,other_feature),axis = 1)预测= self.model_predict(功能,self.nb_model)wishs.append(predicted [ 0 ])
  • 根据所识别的实体进行补充和纠正
#已知疾病,查询症状,
如果self.check_words(self.symptom_qwds,问题)和(类型为'疾病'或类型为'别名'):如果意图不是故意的,意图= “ query_symptom”:意图。附加(意图)
#已知疾病或症状,查询治疗方法
如果self.check_words(self.cureway_qwds,问题)和\(“疾病”在类型或“症状”在类型或“别名”在类型或“并发症”在类型):如果意图不是故意的,意图= “ query_cureway”:意图。附加(意图)
#已知疾病或症状,查询治疗周期
如果self.check_words(self.lasttime_qwds,问题)和(类型为'疾病'或类型为'别名'):如果意图不是故意的,意图= “ query_period”:意图。附加(意图)
#已知疾病,查询治愈率
如果self.check_words(self.cureprob_qwds,问题)和(类型为'疾病'或类型为'别名'):如果意图不是故意的,意图= “ query_rate”:意图。附加(意图)
#已知疾病,查询检查项目
如果self.check_words(self.check_qwds,问题)和(类型为'疾病'或类型为'别名'):如果意图不是故意的,意图= “ query_checklist”:意图。附加(意图)
#查询科室
如果self.check_words(self.belong_qwds,问题)和\(“疾病”在类型或“症状”在类型或“别名”在类型或“并发症”在类型):如果意图不是故意的,意图= “ query_department”:意图。附加(意图)
#已知症状,查询疾病
如果self.check_words(self.disase_qwds,问题)和(类型为“症状”或 类型为“并发症”):如果意图不是故意的,意图= “ query_disease”:意图。附加(意图)#若没有检测到本质,且已知疾病,则返回疾病的描述
如果 不意图和(“疾病”在类型或“别名”在类型):如果意图不是故意的,意图= “ disease_describe”:意图。附加(意图)
#若是疾病和症状同时出现,且出现了查询疾病的特征词,则必然为查询疾病
如果self.check_words(self.disase_qwds,问题)和(类型为'Disease'或类型为'Alias')\和(类型为“ Symptom”或 类型为“ Complication”):如果意图不是故意的,意图= “ query_disease”:意图。附加(意图)
#若没有识别出实体或意图则调用其他方法
如果 没有意图或 不种类型:如果意图不是故意的,意图= “ QA_matching”:意图。附加(意图)自我.result [ “意图” ] =意图

后续就是通过上述得到的预期信息和实体信息选择对应的模版,将实体信息填充入组成查询语句进行数据库查询。

参考资料

  1. QASystemOnMedicalGraph

知识图谱用户输入->摘要的查询语句相关推荐

  1. php使mysql显示错误_如何针对依赖用户输入的长查询在PHP中显示MySQL错误?

    在PHP中,我试图执行一个长的MySQL查询,该查询取决于用户输入.但是,我的查询失败,并显示以下消息, "Query Failed". 实际上,每当查询失败时,我都会打印此消息, ...

  2. php 通过对话框获取参数,利用对话框提示用户输入参数的查询过程称为()

    按负担能力收费 使用噪声测量仪器前后应作哪些校准和检查? 电力市场分析收集的数据资源主要有哪些? 下列关于期权投资策略的表述中,不正确的是( ). 酒精-水型防冻液的冰点限制在()左右. 哪些交易或者 ...

  3. Datawhale 知识图谱组队学习 之 Task 4 用户输入->知识库的查询语句

    文章编写人:王翔 特别鸣谢:QASystemOnMedicalGraph 目录 Datawhale 知识图谱组队学习 之 Task 4 用户输入->知识库的查询语句 目录 一.引言 二.什么是问 ...

  4. Datawhale 知识图谱组队学习之Task 4 用户输入->知识库的查询语句

    Datawhale 知识图谱组队学习 之 Task 4 用户输入->知识库的查询语句 文章编写人:王翔 github 地址: 特别鸣谢:QASystemOnMedicalGraph 目录 Dat ...

  5. Task 4 用户输入->知识库的查询语句

    Task 4 用户输入->知识库的查询语句 引言 本部分任务主要是将用户输入问答系统的自然语言转化成知识库的查询语句,因此本文将分成两部分进行介绍. 第一部分介绍任务所涉及的背景知识; 第二部分 ...

  6. 使用neo4j_知识图谱Task00:Neo4j安装配置

    知识图谱开源内容: https://github.com/datawhalechina/team-learning-nlp/tree/master/KnowledgeGraph_Basic 19 学习 ...

  7. 【Query Embedding on Hyper-relational Knowledge Graphs】 超关系知识图谱上的查询嵌入 论文结果复现

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.背景知识 二.写作动机 三.技术概述 1.查询嵌入: 2.超关系知识图谱: 3. 超关系查询: 四.模型概述: 五 ...

  8. 论文浅尝 - 计算机工程 | 知识图谱可视化查询技术综述

    本文转载自公众号:计算机工程. 知识图谱可视化查询技术综述 王鑫, 傅强, 王林, 徐大为, 王昊奋 知识图谱作为符号主义发展的产物,是人工智能技术和系统中的重要组成部分,其在百科知识.生物信息.社交 ...

  9. 虚拟专题:知识图谱 | DDoS攻击恶意行为知识库构建

    来源:电信科学 DDoS攻击恶意行为知识库构建 刘飞扬, 李坤, 宋飞, 周华春 北京交通大学电子信息工程学院 摘要:针对分布式拒绝服务(distributed denial of service,D ...

最新文章

  1. iPhone12 safeArea顶部区域尺寸变化
  2. 帝国cms内部会员组的使用方法以及应用场景
  3. Jquery中使用SweetAlert使弹窗更漂亮
  4. Checkstyle 简介 以及各版本下载地址
  5. 中文文件名乱码_全能型Mac解压缩软件 MacZip2.0.1(41)中文版 原ezip
  6. jmeter 循环取值赋值给form_JMeter系列(三)逻辑控制器详解
  7. OSEK直接网络管理(NM)
  8. 新手记录SPSS学习笔记1
  9. 员工满意度调查问卷的设计注意事项
  10. 安卓pdf阅读器_【软件分享】自用的一款PDF阅读器——悦书PDF阅读器,支持护眼模式、注释涂鸦、PDF转换,功能齐全,界面简洁美观。...
  11. AutoIT - 加域工具
  12. 小红书推广方式和技巧有哪些?
  13. 树莓派基础实验24:超声波测距传感器实验
  14. idea的java项目怎么连数据库_idea 使用Java连接SQL Server数据库教程
  15. TimeSformer:抛弃CNN的Transformer视频理解框架
  16. Python单元测试unittest测试框架
  17. 2.8 数值分析: 矩阵的范数
  18. Python txt转pcd(带RGB值,点云)
  19. 前端开发工程师——面试题总结
  20. DMMS transfer error: Permission denied问题

热门文章

  1. [Windows]_[系统内部版本号对照表]
  2. 百度前端笔试题 css3画三角形
  3. 《魔兽争霸3》怎么打兽族内战
  4. J storm战队成员_DOTA2J.Storm战队介绍-DOTA2MD迪士尼Major预选赛J.Storm战队介绍_牛游戏网攻略...
  5. Vijos1234 口袋的天空 题解
  6. angular.js-服务-http-路由(5)
  7. 编程题目分类(剪辑)
  8. 【STM32F429】第4章 ThreadX FileX文件系统移植到STM32F429(SD卡)
  9. 模拟器,预览,自动预览,自动真机调试有用,扫二维码真机调试报错
  10. SWIFT,国际清算与数字人民币