摘要 自然语言理解一直是一个很大很麻烦的问题,本文讨论了自然语言理解的基本概念,以及几个实现自然实现方法的讨论。最后,提出一个叫做nltk的工具,并介绍这个工具如何使得开发自然语言理解应用更加迅速
关键词 自然语言理解;规则;nltk
中***分类号TP31 文献标识码A 文章编号 1674-6708(2010)30-0243-02
1 自然语言理解之原理解析
如何来理解自然语言呢?怎样才能让机器理解自然语言呢?这是自然语言理解,特别是计算语言学要讲的问题。
“理解”是什么意思?事实我们常常说,“我明白了你的意思”。一个人说这句话的意思实际上时说,他可以利用你刚告诉他的东西进行事情推理和利用了。实际上,对于计算机来说,机器明白了人的意思实际上说,机器可以利用人用自然语言输入的信息进行计算。
那么如何进行映射呢?这里可以参考下编译原理,编译原理通过一个开始符号一步步往下推导,一直到一个非终结符号都没有的情况,这个时候一个句子就算是解析完成了,而解析出来的句子通过一些符号运算,最终可以映射成计算机可以理解的机器语言。
那么该如何转换呢?比较直观的想法就是使用编译原理技术,使用一个开始符号 S,然后一步步推导到每个单词(这里的单词实际上就是终结符号)。然后对于每次归约,使用action来操作,最终映射成电脑所能理解的sql。对于一个像c语言的语法解析器来说,它在很大的程度上依赖于用户―也就是程序员―对于语言的理解,像那个if else 语法,不管你怎么对齐,else也就只能和最近的一个if组成一个句子。但自然语言的情况就复杂得多了。在现实的生活中,不但有一词多义的多义的情况,而且就是对于同一句话,断句不同都会造成非常不同的效果。比如说对于like这个词来说,在不同的情况就有不同的意思。We like flying 和you are like your mom.的时候就分别是喜欢和像的意思。如何区分?我们可以根据搭配来解决这个问题。对于像is like 这种情况我们可以给like的“像”意思一个比较高的概率,而在另一种情况则给“喜欢”一个比较高的概率,这样,碰到不同的搭配就可以有不同意思理解。这个这种方法可以参考《统计自然语言处理基础》中的马可夫链。马可夫链就是就是根据概率状态转移模型来分析在什么样的情况下,使用哪个表达方式更好。
当然,在分析一句话的时候,我们可能会碰到大量的重复情况,比如说,对于“I see a boy on the chair,使用普通分析技术,必定是先分析掉“I” “see”
“a boy on the chair ”再继续分析“I see a boy”“on the chair ”。对于一个比较大型的系统来说,时间上可能会非常吃不消。而在自然语言理解中,我们一般可以这样做在分析一个句子的时候,不是每次只规约一种情况,而是把所有可规约的情况都规约出来,然后再继续分析,这样缓存的结果就是,我们不必要每次都回溯到开始符号s来重新分析,而是在分析到每个词的时候更新一下当前分析句子的状态就可以了。经过统计,使用这中技术的系统比不使用的要快5 000倍~100 000倍,当然,同时因为缓存中间结果,系统开销也大得多。
但是,如何才能句子的意思进行理解呢?我们回到我开始的那个问题。对于像下面一个对话:
a. Which country is Athens in? b. Greece
来说,我们可以使用下面的规则来进行
% start S
S[SEM=(?np + WHERE + ?vp)] -> NP[SEM=?np] VP[SEM=?vp]
VP[SEM=(?v + ?pp)] -> IV[SEM=?v] PP[SEM=?pp]
VP[SEM=(?v + ?ap)] -> IV[SEM=?v] AP[SEM=?ap]
NP[SEM=(?det + ?n)] -> Det[SEM=?det] N[SEM=?n]
PP[SEM=(?p + ?np)] -> P[SEM=?p] NP[SEM=?np]
AP[SEM=?pp] -> A[SEM=?a] PP[SEM=?pp]
NP[SEM='Country="greece"'] -> 'Greece'
NP[SEM='Country="china"'] -> 'China'
Det[SEM='SELECT'] -> 'Which' | 'What'
N[SEM='City FROM city_table'] -> 'cities'
IV[SEM=''] -> 'are'
A[SEM=''] -> 'located'
P[SEM=''] -> 'in'
其中,s是代表开始符号,后面的则是一个个的推导符号。而中间最关键的地方就是那个sem特征,这个特征可以帮助分析器在规约的时候将一个简单的句子分析成相应的sql.
2 自然语言理解之工具与实现
除了有基础的理论之外,实现自然语言理解系统也很重要。出于效率的情况,真正的系统可能使用分布式计算,然后在每个节点上使用像c++这样的语言来进行计算。但是对于像c++这样的语言,可能在开发与调试上需要大量的时间和极度的细致,这对于新应用的研究工作来说是不太合适的。在这种情况,使用基于python的nltk会比较好一些。
Nltk的全称是”自然语言工具包”,可以再google code上找到这个开源项目。目前的最新版本是2.0b9。这个工具支持了很多关于自然语言理解方面的技术,是一个比较好的开发框架。
我们可以使用这个工具来简单的对上面的情况进行一些讲解,首先,我们可以先以上面第2节提到的规则作为一个模板来写一个文法文件,它的后缀名是.fcfg(比如a.fcfg)。nltk在处理的时候会根据你所提供文法文件来装入相应的规则。我们可以进行类似如下的操作
>>> from nltk import load_parser
>>> cp = load_parser('grammars/book_grammars/sql0.fcfg')
>>> query = 'What cities are located in China'
>>> trees = cp.nbest_parse(query.split())
>>> answer = trees[0].node['sem']
>>> q = ' '.join(answer)
>>> print q
SELECT City FROM city_table WHERE Country="china"
注意上面的操作,我们通过load_parser方法装入语法文件,然后再使用nbestparser就可以实现这些操作了。
3 结论
从目前的情况的看,自然语言理解不管在从学术研究到商业市场的各个领域都有比较迫切和强烈的需求,它本身也涵盖了从人工智能,数据挖掘等非常广泛的领域,而且对于理论和技术的要求都比较高。