我正在开发一个应用程序,其中需要从数据库中获取用户输入(自然英文文本)查询的结果。
对于启动,我将标记化,解析,NER,POS标记为输入文本(使用斯坦福 NLP库)。
但是下一步该怎么做。我的意思是我实际上应该做些什么,以便可以从可以在数据库上触发的输入文本创建正确的SQL查询。我应该如何处理文本上下文。
例如,我有一个公司的数据库,其中有不同的表,例如员工,部门等。
-因此,当用户在查询中输入“雇员列表”时,它应该能够显示雇员列表。
-当用户键入“计算机部门的雇员”时,应显示与计算机部门有关的雇员。
我正在将MS-SQL用于数据库(因此需要从自然语言为SQL创建查询)。对于编程,我正在使用C#。
我浏览了许多不同的文档,但是所有都是理论上的。但是我没有找到合适的实现方式。
因此,任何种类的信息,数据,链接,指南,解决方案,其他实现方式等都将有所帮助。
最佳答案
这是一个非常困难的问题。我怀疑是否可以明确回答。解决此任务的方法不止一种。我只能说其中一个。最简单的一个。它是基于规则的。为实现此目的,应完成许多手动映射工作。
POS标记后,应进行语法分析。您不仅应该找到每个单词的属性,还应该找到单词之间的依存关系:链接和单词之间链接的类型。示例:"list of employees"
。这里"list"
是主要的,"employees"
是依赖的。链接的类型为possession
。
然后应该执行语义分析。您有语法树。应该将其转换为抽象语法树(AST)。
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列表将被替换。当然,这种算法可以更好。例如,您可能希望合并当前节点所有边缘的条件。但是,很难为整个树构造一个查询。因此,您最好构造较小的对象(可能进行简单的优化),然后组合结果。
另外,请看一下我最后给出的最后一个链接。存在定义上语义上可处理的问题。限制用户输入非常重要。这些条件应成立:
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查询的结果可能是模棱两可且不可预测的。受控语言查询的结果是准确的。
更多理论:
关于自然语言接口(interface)的Wikipedia article(也用于数据库)。
关于NLIDB的最综合的综述之一:Androutsopoulos,I.,Ritchie,G.和Thanisch,P.数据库的自然语言接口(interface)-简介。
Microsoft English Query:Microsoft的NLIDB实现。
这项工作给出了语义上易处理的问题的定义:Popescu,AM。,Armanasu,A.,Etzioni,O.,Ko,D.,Yates,A.数据库的现代自然语言接口(interface):构成具有语义可伸缩性的统计解析。