这是一个相当难的问题。我怀疑它可以毫不含糊地回答。可以有不止一种方法来解决这个任务。我只能讲述其中之一。最简单的一种。它是基于规则的。应该做很多手动映射工作来实现这一点。
在 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 的含义。示例规则是table1 - link: POSSESSION - table2如果table1中存在对应的外键和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. Natural Language Interfaces to Databases - An Introduction。
Microsoft English Query:来自 Microsoft 的 NLIDB 实现。
在这项工作中给出了语义易处理问题的定义:Popescu, A-M., Armanasu, A., Etzioni, O., Ko, D., Yates, A. Modern Natural Language Interfaces to Databases: Composing Statistical Parsing具有语义可追踪性。