我正在开发一个应用程序,其中需要从数据库中获取用户输入(自然英文文本)查询的结果。
对于启动,我将标记化,解析,NER,POS标记为输入文本(使用斯坦福 NLP库)。
但是下一步该怎么做。我的意思是我实际上应该做些什么,以便可以从可以在数据库上触发的输入文本创建正确的SQL查询。我应该如何处理文本上下文。

例如,我有一个公司的数据库,其中有不同的表,例如员工,部门等。
-因此,当用户在查询中输入“雇员列表”时,它应该能够显示雇员列表。
-当用户键入“计算机部门的雇员”时,应显示与计算机部门有关的雇员。

我正在将MS-SQL用于数据库(因此需要从自然语言为SQL创建查询)。对于编程,我正在使用C#。

我浏览了许多不同的文档,但是所有都是理论上的。但是我没有找到合适的实现方式。

因此,任何种类的信息,数据,链接,指南,解决方案,其他实现方式等都将有所帮助。

最佳答案

这是一个非常困难的问题。我怀疑是否可以明确回答。解决此任务的方法不止一种。我只能说其中一个。最简单的一个。它是基于规则的。为实现此目的,应完成许多手动映射工作。

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在这种情况下具有SOURCEFOREIGN 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 = 5select ID from EMPLOYEES where SALARY > 435 and ID = 23select ID from EMPLOYEES where SALARY > 435 and ID = 345。结果ID列表将被替换。

    当然,这种算法可以更好。例如,您可能希望合并当前节点所有边缘的条件。但是,很难为整个树构造一个查询。因此,您最好构造较小的对象(可能进行简单的优化),然后组合结果。

    另外,请看一下我最后给出的最后一个链接。存在定义上语义上可处理的问题。限制用户输入非常重要。这些条件应成立:
  • 该问题应包含wh单词(谁,在哪里,什么等)之一,以确定问题的类型(以及答案的类型)。在您的情况下,这不是必须的,因为允许使用list of employees之类的查询。
  • 允许使用一些停用词(例如theaan),并且只会被忽略。
  • 所有其他单词都应在本体节点上具有映射。
  • 句子中单词之间的任何链接都应由系统解释。

  • 如果有任何术语没有映射,则应显示错误。

    Wolfram | Alpha使用了另一种方法。 Their FAQ说他们的方法“不同于传统的NLP”。我不知道这些方法是什么。但是我会通过使用许多简单的语法模式来实现像Wolfram | Alpha这样的系统。例如,who is X-> show article Xlist of X-> select * from Xwith 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):构成具有语义可伸缩性的统计解析。

    09-09 21:13