这是一个很难回答的问题。我怀疑它可以毫不含糊地回答。可以有多种方法来解决这个任务。我只能说出其中的一个。最简单的一个。这是基于规则的。为了实现这一点,应该做大量的手动映射工作。
POS标记后,应完成语法分析。您不仅应该找到每个单词的属性,还应该找到单词之间的依赖关系:单词之间链接和链接类型。例如:"list of employees"
。这里主要是"list"
,"employees"
是依赖的。链接的类型是possession
。
然后应该进行语义分析。你有一个语法树。它应该转换为抽象语法树(AST)。
- 每个单词或短语(子树)应该变成一个语义节点。 NER没问题。节点
word: "employees"
变成table: EMPLOYEES
。节点word: "list"
和节点word: "of"
成为种类action: SELECT
。你应该有你的域的本体论。语法树的节点被映射到本体的节点。映射由规则控制。示例规则:if the word is found in the list of tables then replace the node "word: x" with the node "table: x"
。或者另一个:if the word is "list" and a child word is "of" then replace these nodes with "action: SELECT"
。
- 每条边(语法链接)都应该变成语义链接。映射也受规则控制。例如,子树
table: EMPLOYEES
-link: POSSESSION
-entity: ID = 234 ("Computer department") of table DEPARTMENTS
显示在这种情况下的语法链接POSSESSION
具有含义SOURCE
或FOREIGN KEY
。如果表1中存在对应的外键和表2的主键,则样本规则为table1 - link: POSSESSION - table2
变为table1 - where FK_FIELD_OF_TABLE1 = PK_FIELD_OF_TABLE2 - table2
。
您的本体应包含您的域的所有条款。一些术语是静态的(例如,动作)。一些是动态的,应该在解析用户NL-查询(例如表名或字典表内容)时在运行时查询。
然后,您在AST的每个边缘处构建SQL中的小型查询,并在达到顶部时汇总结果。样本AST:
action: SELECT
|
table: EMPLOYEES
/ \
where e.DEP_ID = d.ID where e.SALARY > ?
| |
entity: ID = 234 (DEPARTMENTS) constant: 435
左边缘应该减少为一个常量相等节点像右边一样。然后处理一个小的查询select ID from EMPLOYEES where DEP_ID = 234
。结果列表存储在table: EMPLOYEES
节点中。
action: SELECT
|
table: EMPLOYEES (entities: ID in (5, 23, 345))
|
where e.SALARY > ?
|
constant: 435
然后右边缘(现在它是唯一一个)是为每一位员工处理: select ID from EMPLOYEES where SALARY > 435 and ID = 5
,select ID from EMPLOYEES where SALARY > 435 and ID = 23
,select ID from EMPLOYEES where SALARY > 435 and ID = 345
。 ID的结果列表被替换。
当然,这个算法可以更好。例如,您可能希望组合当前节点的所有边的条件。但是为整棵树构造一个查询将会很困难。所以你最好构建小的(可能有简单的优化),然后结合结果。
另外,请看看我在最后给出的最后一个链接。有定义的语义易处理的问题。限制用户输入非常重要。这些条件应该保留:
- 该问题应该包含用于确定问题类型(以及答案类型)的wh-词之一(who,where,what等)。在您的情况下这不是强制性的,因为像
list of employees
这样的查询是允许的。
- 允许使用一些停用词(如
the
,a
,an
),并且只是被忽略。
- 所有其他词都应该在本体节点上映射。
- 句子中单词之间的任何链接都应该由系统解释。
如果有任何术语没有映射,那么应该显示一个错误。
另一种方法用于Wolfram | Alpha。 Their FAQ表示他们的方法“不同于传统的NLP”。我不知道那些方法是什么。但是我会通过使用大量简单的语法模式来实现像Wolfram | Alpha这样的系统。例如,who is X
→show article X
,list of X
→select * from X
,with salary more than X
→where SALARY > X
。
另外,看看控制语言。 NL查询的结果可能不明确且不可预测。受控语言查询的结果是确切的。
更多理论:
Wikipedia article关于自然语言界面(以数据库也)。
关于NLIDB最综合的概述作品之一:Androutsopoulos,I.,Ritchie,G。和Thanisch,P.自然语言接口到数据库 - 介绍。
Microsoft English Query:来自Microsoft的NLIDB实现。
在这项工作中给出了语义易处理问题的定义:Popescu,A-M。,Armanasu,A。,Etzioni,O.,Ko,D.,Yates,A.现代自然语言接口到数据库:用语义可牵引性编写统计分析。
你看过域特定语言吗?这可能是一个很好的信息来源:https://msdn.microsoft.com/en-us/library/ee943825.aspx – 2015-04-05 12:40:46
取决于你想付出多少努力,你可以尝试训练一个语义分析器用于该任务(例如,http://www-nlp.stanford.edu/software/sempre/)。您需要查询及其相关结果的培训示例,并且您需要一些代码才能在数据库上运行逻辑表单,但最终应该能够正常运行。 – 2015-04-08 09:13:44
嗨GD,我面临同样的问题,你能告诉我你是如何解决它的。 – rakesh 2015-10-02 06:13:43