自然语言接口软件的设计与实现

来源:岁月联盟 作者:徐海云 钱斌 时间:2010-08-30
摘  要  为数据库设计语言接口成为数据库应用的一个研究方向。本文介绍了一种基于受限的汉语自然语言查询技术,通过建立机器辞典,对自然语言查询语句进行切词,再通过查找查询对象和查询条件,生成SQL语句。
    关键字 受限;自然语言;机器辞典;切词;SQL语句
 


1  引言
    随着人工智能的和数据库技术的广泛应用,人们非常希望以一种更方便的方法去查询数据库。使用自然语言进行查询无疑是解决这一问题的有效方法。它避免了以往命令式人机界面、图形式人机界面繁杂的操作训练。事实证明,通用的自然语言理解往往是低效的,而作为数据库人机接口的自然语言界面具有使用目的单一、用词范围有限等特点,在数据库查询意义上实现自然语言理解是完全可行的。另外,我们可以通过语音识别技术进行语音输入,从而简化复杂的输入工作。
    本系统针对数据库这一单一领域进行查询,从而简化了数据库查询的复杂操作。以提取查询对象和查询条件为手段,生成数据库查询语句为目的的软件。本软件的人机交互界面既可以单纯的通过输入语句,然后转换成SQL语句,也可以通过语音输入,再依靠复制-粘贴的手段进行输入,然后转换成SQL语句。
2  数据辞典的设计
2.1辞典结构的设计
    为了便于以后对机器辞典进行查找,本系统通过类来设计了机器辞典,具体结构如下:
    class jqcd                               //定义一个反映机器辞典的jqcd类
    {  char *ct;                           //词条字符串
        char *yzym;                     //标志
        char *yybz;                 //语义
        char *szb1;        //所在表1
        char *szb2;          //所在表2
        char *szb3;          //所在表3
    }
    其中:ct:表示词条字符串,在切词时进行匹配,便于以后生成SQL语句。yzym:表示句法标志,用来表示词条在语句中的功能。
    用九个数字表示不同的含义,其中:“0”表示域名,“1”表示域值,“2”表示逻辑操作符,“3”表示关系操作符,“4”表示查询动词,“5”表示疑问词,“6”表示连接动词,“7”表示使役动词,“8”表示中性词。yybz:表示语义标志,用来表示词条所对应的概念在语义框架中的功能。给词条加上合适的语义标志,有助于以后生成SQL语句。语义标志比语法标志复杂的多。szb1:表示词条所在表1,因为有些词条(如学号等)不只在一个表中,指出所在表有助于以后生成SQL语句。 szb2:表示词条所在表2,因为有些词条(如学号等)不只在一个表中,指出所在表有助于以后生成SQL语句。szb3: 表示词条所在表3,因为有些词条(如学号等)不只在一个表中,指出所在表有助于以后生成SQL语句。
2.2 辞典的排序
    辞典排序采取先按机内码由小到大,再按词条长度由大到小进行排序,通过排序以后,切词时可以先通过机内码找到该词第一个字,然后通过最大匹配法进行切词。【4】
3  切词及其存储
3.1 切词
    切词采取机内码匹配,然后通过匹配词条字符串进行切词,具体流程如图1所示。
    具体分析如下:首先,读入句子。然后,按照句子的第一个字的机内码与辞典中的词条第一个字相匹配,匹配成功则从辞典中顺序查找词条,找到词条后入栈。如果找不到,则进行容错处理。对于数字,我们给他添加特别标志,使其在辞典中的位置为“-1”,以后进行分析时,只要遇到位置为“-1”的词时,就认为是数字。
3.2 存储
    切词完毕,用栈进行存储中间结果,栈的结构如下:
    struct save       
    {  char *savestr; 
        int indexInDirectory;
        struct save *next;
    };
    其中:savestr存储切出的词。indexInDirectory存储切出的词在辞典中的位置,便于以后查询机器辞典中的词条。

图1 切词流程图4  中间链表的生成
    生成中间链表【2】的目的是为了便于以后的语句分析,便于生成查找对象和查找条件中间链表的结构如下:
    struct wTypeList                  
    {  char word;              //词条
        char*wordType;             //词性
        char field_value;            //对应的域值
        char field_name;            //对应的域名
        int  locationlibrary;         //在辞典中的位置
        struct wTypeList *next;       //next 指针
    }; 
    其中:该中间链表中的词性是关系到以后生成查询对象和查询条件的关键项。通过词性的判断可以提取查询对象和查询条件,以便生成SQL语句。
5  查询对象的生成
    语言的查询语句不外乎是命令性的祈使句、疑问句、条件判断句,根据相应句型,采用不同搜索方式来确定查询对象,本软件采用三种搜索方式:不需要搜索查询对象、需正向搜索查询对象【5】、需逆向搜索查询对象。
    经过反复比较和自然语言查询语句,共有六种句型【3】:
    (1)who—sentence 如“谁的学号为100033102?”,这种句型的查询对象隐含在“谁”中,搜索方式为“不需搜索”。
    (2)us—sentence如“哪些学生的籍贯是山东?”
    (3)特殊语句:即verb qus不在句子首尾,而可以在其他的任何位置上。如“戴子强是哪个地方的人?”。 以上句型一般采用正向搜索查询对象。
    (4) find---sentence  这是以动词开头的句型,大部分的祈使句的查询句都是这种句型。如“查询学号为1000033102的学生的姓名”。
    (5)  b(把)---sentence  这是以“把”为首的祈使句。如“把学号为1000033102的学生找出来”。
    (6)sentence--verb—qus(who)  这种句型是以verb qus或verb who结尾的句子,如“张三的学号是多少?”
    (4)(5)(6)三种句型采取逆向搜索查询对象。以上六种句型,其覆盖的查询句子已相当广泛,所以当句型和搜索方式确定以后,就可以找出查询对象。查询对象的搜索规则渗透到程序中,采取的办法是一边搜索中间词链,一边根据句型搜索查询对象。
6  查询条件的生成
    首先,根据前面生成的中间词链,在通过查询对象寻找的程序后用一个指针从中间词链的头移动到尾,分别判断当前指针指向的结点的词性是不是为“-1”、“8”、“4”,即为查询对象、查询动词、中性词、一般动词。如果是,指针后移;如果不是,则复制该结点,然后执行插入查询条件词链中的程序。这样指针移动到头后,所生成的查询条件链就是下一步程序所要的词链。若中间词链的头指针和首结点相等的话,即中间词链为空,则直接返回查询条件栈的头指针。
    其次,根据七种基本模版:(1)域名+关系符+域值(2)域名+关系符(3)域名+域值(4)域值(5)域值+域名+关系符(6)域值+域名(7)关系符+域名进行匹配。一个查询条件链可以有一个或多个模版组成。
    最后,将匹配成功的一个或多个模版分别压入条件栈,返回入栈后的栈顶指针。在没有找到匹配的模版或条件链为空时,直接返回没有结点的条件栈的栈顶指针。
查询条件栈的结构为:
    struct condStack             //查询条件栈
    {  char *name;            //域名
        int  nameIndex;        //域名在字典中的位置
        char *condition;         //关系(逻辑或者一般关系)
        char *value;            //域值 
        int  valueIndex;        //域值在字典中的位置
        struct condStack *next;
    };    
7  SQL语句的生成
    根据前面生成的查询对象栈和查询条件栈,进行SQL语句的转换。【1】 
    首先,判断对象栈和条件栈是否为空。如果这两个栈有一个为空,则SQL转化没有办法执行,直接返回空。
    其次,分别将对象栈和条件栈中的结点做出栈处理。并分别记下查询对象和条件的个数,并判断该查询语句属于哪一种情况:(1)单对象,单条件(2)单对象,多条件(3)多对象,但条件(4)多对象,多条件。
    然后,根据属于哪一种情况,来进行对汉语查询语句的SQL转换。但是,不管查询语句属于哪一种情况,都要进行判断查询对象和查询条件是否在同一个表中。这是通过szb()函数和OneOrMoreTable()函数结合来实现的。
    在单对象,单条件中,如果查询对象和条件在同一表中,则直接调用函数one()来执行SQL语句的转化。在one()函数中,将select、from、where等SQL语句中必要的单词转换成字符串,将查询对象和查询条件根据他们能在SQL中的位置进行转换。当查询对象和查询条件不在同一个表中,此时就是一个嵌套查询的语句。根据提供的9个表,找出查询对象和查询条件分别所在表之间的联系。因这9个表之间都是通过什么号(例如:学号、院系号)进行联系的,所以最后在多表问题上通过表之间的联系并调用more()函数来进行SQL语句的转换。
    在单对象,多条件情况中,先判断条件是否在同一个表中,然后在分别判断多条件和单个对象是否在同一个表中。这样就又会出现多条件在同一个表中,与单对象在同一个表中,与单对象不再同一个表中;多条件不在同一个表中,单条件与单对象在同一个表中,单条件与对象不再同一个表中等多种情况。分别对这些情况进行判断和分析,最后都将它们转换成简单的单对象单条件的情况进行处理。对于实在没有办法处理的句子情况,采用返回空值的办法,继续下一条查询语句的执行。
    对于多对象、单条件和多对象、多条件的情况也是这样进行判断、分析和处理的。
    最后,我们返回生成的SQL语句,并将它们写入D:/sysdata/output.txt文件中。
8  结论
    以上详细介绍了设计自然语言接口的过程,依据其设计出了一个完整的自然语言数据库查询接口软件,该软件运行效果良好,并在济南市第二届软件大赛中荣获三等奖。

【1】  许龙飞,杨晓昀,唐世谓. 基于受限汉语的数据库自然语言接口技术研究[J]. 软件学报,2002,13(4).
【2】 王新民,叶延滨. 数据库自然语言查询界面.小型微型机系统,Vol.18,No.3,1997
【3】 徐九韵,王新民,仝兆歧. 文法识别与数据库汉语查询语言的结构分析, 石油大学学报(自然版), Vol. 21,No. 2,1997
【4】 张剑平.用于管理信息系统检索的自然语言接口模型.小型微型计算机系统,Vol. 15,No. 8,1994
【5】 徐九韵,仝兆歧,向逐聪,王新民. 数据库汉语查询语言的分词研究与实现.中文信息学报,Vo1. 12 No. 4,1998.

图片内容