#gStore-weekly | gAnswer源码解析 查询图生成

news/2023/11/30 8:56:41
简介

gAnswer通过将自然语言问题转化成查询图,再和图数据库中的RDF图做匹配以生成用于查询的SPARQL语句。今天讲解的就是生成查询图的主要代码。

// step 2: build query graph (structure construction, relation extraction, top-k join) 
t = System.currentTimeMillis();
BuildQueryGraph step2 = new BuildQueryGraph();
step2.process(qlog);
qlog.timeTable.put("step2", (int)(System.currentTimeMillis()-t));

这是生成查询图的函数入口部分,如注释中所示,该部分主要分为三个子模块:构建查询图结构、关系提取和子图匹配(top-k join)。在构建查询图结构之前,已经通过节点提取模块(Node Extraction)确定了图中的所有节点,因此构图的过程其实就是确定每两个点之间是否有连边的过程,通过在依存分析树(Dependency Parsing Tree)上深度优先搜索,可在(为树的大小)时间内完成。接下来,通过一种基于依存分析树和离线构造词典的方法完成关系提取(Relation Extraction)后,gAnswer会采用一种子图匹配的方法将生成的查询图和RDF图匹配,从而生成候选SPARQL.

因节点提取、关系提取在以往的文章中已经讲过,因此本文聚焦于构建查询图结构和子图匹配的过程。

构建查询图结构

在构建查询图之前,需要完成四个准备工作:fix stop nodes, detect modified node, detect target和coreference resolution.

Fix stop nodes和detect modified node主要是为了提高准确率针对英文语境和DBpedia数据集的一些经验性的修改,比如问句中出现短语“take place”,则实体"place"一定不是图中的节点。而detect modified node是针对一些名词词组(比如“Apollo 11 mission” "De Beers company"),选择其中一个词代表整个词组作为图中的节点。

在detect modified node中分为两个部分:检测连续的名词词组(getTheModifiedWordBySentence方法)和离散的名词词组(getDiscreteModifiedWordBySentence方法),但这两个部分的思想是一致的,即根据句子结构定义一些经验性的规则。在未来可通过训练一个节点识别模型替换掉当前的启发式规则。

public Word getDiscreteModifiedWordBySentence(Sentence s, Word curWord)
{ int curPos = curWord.position - 1;//[ent1](cur) 's [ent2], ent1->ent2, usually do NOT appear in SPARQL | eg:Show me all books in Asimov 's Foundation_seriesif(curPos+2 < s.words.length && curWord.mayEnt && s.words[curPos+1].baseForm.equals("'s") && s.words[curPos+2].mayEnt)return curWord.modifiedWord = s.words[curPos+2];//[ent1] by [ent2](cur), ent2->ent1, usually do NOT appear in SPARQL | eg: Which museum exhibits The Scream by Munch?if(curPos-2 >=0 && (curWord.mayEnt||curWord.mayType) && s.words[curPos-1].baseForm.equals("by") && (s.words[curPos-2].mayEnt||s.words[curPos-2].mayType))return curWord.modifiedWord = s.words[curPos-2];return curWord.modifiedWord;
}

getDiscreteModifiedWordBySentence方法

准备工作的第三步是detect target,即寻找问句的目标变量是什么。gAnswer通过判断Wh-word(即what, where等)来确定问句的类别,并结合句子和依存树的结构来确定目标变量。

if(target.word.baseForm.equals("where"))
{int curPos = target.word.position - 1;//!Where is the residence ofif(words[curPos+1].baseForm.equals("be") && words[curPos+2].posTag.equals("DT")){for(int i=curPos+4;i<words.length;i++)if(words[i-1].posTag.startsWith("N") && words[i].posTag.equals("IN")){target.word.represent = words[i-1];target = ds.getNodeByIndex(i);break;}}
}

如上图所示,以"where"为例,除了简单的问句,最常见的问法是"where is the xxx of ...",即where后面跟着be动词、限定词、名词和介词,那么我们会将这个名词作为目标,而不是where本身。

对于形如"Where is xxx from?"这样的简单问句,gAnswer认为目标就是"where",即查询图中的两个节点是"where"和"xxx".

最后一步是coreference resolution,即识别并解决指代关系(anaphora resolution)和指代消解(cataphora resolution),gAnswer目前只提供了一个基于规则的简单方法。

准备工作完成后,在构建时,首先建立一个队列,并将目标节点放进队列中。随后每次取出队首,并用深度优先搜索的方法在依存树上查找周围节点,直到遇到了其他中的节点,则认为这两个节点相连,并将这些节点放进队列。重复以上流程直到队列为空,至此的完整结构就构建出来了。

public void dfs(DependencyTreeNode head, DependencyTreeNode cur, ArrayList<DependencyTreeNode> ret)
{if(cur == null)return;visited.add(cur);if(isNode(cur) && head!=cur){ret.add(cur);return;}if(cur.father!=null && !visited.contains(cur.father)){dfs(head,cur.father,ret);}for(DependencyTreeNode child: cur.childrenList){if(!visited.contains(child))dfs(head,child,ret);}return;
}

深度优先搜索过程

需要注意的是,这样建立的图是一个超图,即在和RDF图进行子图匹配时,我们允许有的边失配,这种构图方法也一定程度上解决了语言歧义性的问题。

之后会通过节点提取方法为每条边寻找对应的谓词,从而生成完整的查询图。

子图匹配

子图匹配过程即生成SPARQL过程,调用方法部分如下图所示:

//step3: item mapping & top-k join
t = System.currentTimeMillis();
SemanticItemMapping step5 = new SemanticItemMapping();
step5.process(qlog, qlog.semanticRelations); //top-k join (generate SPARQL queries), disambiguation
qlog.timeTable.put("BQG_topkjoin", (int)(System.currentTimeMillis()-t));

子图匹配的算法的主体是top-k join,即匹配过程中取得分前高的子图作为答案。因子图匹配需要不断和图数据库进行交互,通信成本较高,因此gAnswer采用检查预先离线处理的“fragment”来模拟子图匹配的过程。

fragment:相当于将RDF图的信息离线存储在本地,每个fragment相当于图中的一个节点,包含该节点信息,以及该节点的出边信息等。

提取的信息后(点的信息存储在entityPhrasesList中,边的信息存储在predicatePhraseList中),top-k join算法首先枚举图中的所有节点的mention对应的实体,再枚举这些节点之间是否有边,以及边对应的谓词。这些全部枚举出来后,会通过scoringAndRanking方法判断枚举出来的的子图是否是RDF的子图,以及为其打分。

在scoringAndRanking中,首先会判断子图是否连通(若边的数量大于1,且存在一对节点他们的度数都为1,说明不连通)。若子图连通,会根据fragment判断每条边是否为RDF图上的边。因为RDF图是有向图,因此判断的过程即判断RDF图中是否存在 这样的三元组,若存在,会为这个三元组新建一个Triple类的对象,认为其是一条SPARQL三元组。

if(sr.isArg1Constant && (sr.arg1Word.mayEnt || sr.arg1Word.mayType) ) // Constant 
{// For subject, entity has higher priority.if(sr.arg1Word.mayEnt){EntityMapping em = currentEntityMappings.get(sr.arg1Word.hashCode());subjId = em.entityID;sub = em.entityName;score *= em.score;}else{TypeMapping tm = sr.arg1Word.tmList.get(0);subjId = Triple.TYPE_ROLE_ID;sub = tm.typeName;score *= (tm.score*100); // Generalization. type score: [0,1], entity score: [0,100].}
}
else // Variable
{subjId = Triple.VAR_ROLE_ID;sub = "?" + sr.arg1Word.originalForm;
}

通过fragement进行子图匹配过程(以判断subject节点为例)

至此,gAnswer根据构建的超图生成了对应的SPARQL,只要在对应的图数据库中执行便能获得问题的答案了。


https://www.xjx100.cn/news/3091670.html

相关文章

如何快速让苹果TF上架

苹果TF上架是一个相对复杂的过程&#xff0c;需要经过多个步骤和审核环节。以下是一些建议&#xff0c;可以帮助你快速让苹果TF上架&#xff1a; 确保应用程序符合苹果的审核指南和规则。在提交应用程序之前&#xff0c;仔细阅读苹果的审核指南&#xff0c;并确保你的应用程序…

基于人工水母算法优化概率神经网络PNN的分类预测 - 附代码

基于人工水母算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于人工水母算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于人工水母优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神…

Consumer的负载均衡

想要提高Consumer的处理速度&#xff0c;可以启动多个Consumer并发处理&#xff0c;这个时候就涉及如何在多个Consumer之间负载均衡的问题&#xff0c;接下来结合源码分析Consumer的负载均衡实现。 要做负载均衡&#xff0c;必须知道一些全局信息&#xff0c;也就是一个Consum…

安全+Linux!IBM新一代大型机Z14全新发布

导读本周&#xff0c;以“架构 人机同行”为主题的IBM Systems创行者高峰论坛在北京召开&#xff0c;IBM全球及大中华区硬件系统部负责人&#xff0c;金融、医疗、制造等领域的企业、合作伙伴共与这一年度盛会&#xff0c;探讨认知时代下的基础架构技术趋势及IBM硬件系统业务的…

KT142C语音芯片客户反馈电脑端的配置文件,打开都正常,但是拷贝到KT142C内部就乱码

KT142C语音芯片客户反馈电脑端的配置文件&#xff0c;打开都正常&#xff0c;但是拷贝到KT142C内部就乱码 首先解释一下原理&#xff0c;KT142C内置的330Kbyte空间可供用户下载&#xff0c;实际上拿出程序部分的空间 作为声音存储介质的&#xff0c;也就是说&#xff0c;代码空…

VAD监测(一)

麦克风的采样率是16000&#xff0c;代表一秒钟采集16000个数据点 我们每次拿1024个采样点作为一个buffer&#xff0c;buffer是一个b类型&#xff0c;也就是字节类型。 这一个buffer的长度不一定是1024&#xff0c;取决于每个采样点的采样点的位深度&#xff0c;如果音频数据是…

如果文件已经存在与git本地库中,配置gitignore能否将其从git库中删除

想把项目的前后台代码放到同一个git仓库管理&#xff0c;由于未设置.gitignore&#xff0c;就使用vscode做stage操作&#xff08;相当于git add . 命令 其中【.】点表示全部文件&#xff09;&#xff0c;观察将要入库的文件发现&#xff0c;node_modules、target、.idea、log等…

MatrixOne完成与麒麟信安、欧拉的兼容互认

近日&#xff0c;超融合异构云原生数据库MatrixOne企业版软件V1.0完成了与欧拉开源操作系统&#xff08;openEuler简称“欧拉”&#xff09;、麒麟信安操作系统系列产品和虚拟化平台的相互兼容认证&#xff0c;通过了欧拉兼容性测评&#xff0c;获得了《openEuler技术测评证书》…