10.1自然语言理解

查询数据库

自然语言处理 LLM 自然语言处理 逻辑_数据库

如果有人提出一个问题:

Which country is Athens in?

得到的回答应该是:

Greece.

这个数据可以通过数据库语言得到答案:



SELECT Country FROM city_table WHERE City= 'athens'



这里有一个文法,可以把句子转换成SQL语句:



>>>nltk.data.show_cfg('grammars/book_grammars/sql0.fcfg')
%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='CityFROMcity_table'] -> 'cities'
IV[SEM=''] -> 'are'
A[SEM='']-> 'located'
P[SEM='']-> 'in'
这使我们能够分析SQL查询:
>>>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"



要达到能够从句子到后来的生成的数据库SQL语句,也就是独立于任何的查询语言,我们应该建立一个经典的逻辑的标准解释。

逻辑形式更加的抽象,更加的通用。

自然语言、语义和逻辑

一个句子集W的模型是某种情况的形式化表示,其中w中的所有句子都为真。

看下面这个图:

自然语言处理 LLM 自然语言处理 逻辑_lua_02

段落的域D(我们当前关心的所有实体)是个体的一个集合,而当集合从D建立,关系也被确立。

例如:

域D包括3个孩子,Stefan、Klaus和Evi,分别用s、k和e表示。记为D= {s,k,e}。

表达式boy是包含Stefan和Klaus的集合,表达式girl是包含Evi的集合,表达式is running是包含Stefan和Evi的集合。

10.2命题逻辑

我们要设计一种逻辑语言,使推理更加的明确。



[Klaus chased Evi]and [Evi ran away]

例如这句话,


φ和ψ替代(8)中的两个子句,并用&替代对应的英语词and的逻辑操作:φ&ψ。这就是这句话的逻辑形式。

下面的标重,指定了包含一些运算符的公式为真的条件。iff作为if and only if(当且仅当)的缩写。

自然语言处理 LLM 自然语言处理 逻辑_自然语言处理 LLM_03

注意蕴含这个运算符:

形式(P ->Q)的公式是为假只有当P为真并且Q为假时。如果P为假(比如说,P对应Themoonis madeofgreen cheese)而Q为真(比如说,Q对应Twoplus two equa ls four)那么P -> Q的结果为真。

NLTK中的inference模块通过一个第三方定理证明器Prover9的接口,可以进行逻辑证明。

例如:

SnF表示:Sylvania is to the north of Freedonia。

Fns表示:Freedonia is to the north of Sylvania。



>>>lp =nltk.LogicParser()
>>>SnF= lp.parse('SnF')
>>>NotFnS= lp.parse('-FnS')
>>>R= lp.parse('SnF -> -FnS')
>>>prover= nltk.Prover9()
>>>prover.prove(NotFnS,[SnF, R])
True



一个命题逻辑的模型,需要为每个可能的公式分配值True或False.

我们可以来简单做一个实验:

1、先为每个命题符号分配一个值



>>>val = nltk.Valuation([('P',True),('Q', True),('R', False)])



我们可以查看这个值的:



>>>val['P']
True



2、为了简化实验,我们先忽略dom和g的设置



>>>dom =set([])
>>>g= nltk.Assignment(dom)



3、使用val来初始化模型m


>>>m=nltk.Model(dom, val)

4、每个模型都有一个evaluate()方法,可以确定逻辑表达式。例如:



>>>print m.evaluate('(P&Q)',g)
True
>>>print m.evaluate('-(P&Q)',g)
False
>>>print m.evaluate('(P&R)',g)
False
>>>print m.evaluate('(P| R)',g)
True



现在,我们只是局限在用字母P、Q等表示原子,句子。但是我们需要超越命题逻辑到一个更有表现力的东西,能够看到里面的基本的句子,也就是一阶逻辑。