10 分析句子的意思
英文文档 http://www.nltk.org/book/
中文文档 https://www.bookstack.cn/read/nlp-py-2e-zh/0.md
以下编号按个人习惯
Analyzing the Meaning of Sentences
1 自然语言理解
1.1 查询数据库
利用语法,将自然语言解析成SQL,并执行SQL,查询结果。
# 加载分析器
cp = load_parser('grammars/book_grammars/sql0.fcfg', trace=3)
query = 'What cities are located in China'
trees = list(cp.parse(query.split()))
answer = trees[0].label()['SEM']
answer = [s for s in answer if s]
q = ' '.join(answer)
print(q)
# 在city.db中执行q语句,返回结果
rows = chat80.sql_query('corpora/city_database/city.db', q)
# rows中每一项是一个元组
for r in rows:
print(r[0], end=" ")
1.2 自然语言,语义学和逻辑学
上述中虽然将自然语言转换为SQL来查询,但这并不能保证翻译的正确性。
语义上有两个基本概念:
- 陈述性句子在某些情况下是对还是错
- 定名词短语和专有名词指的是世界上的事物
广义上来说,基于逻辑的自然语言语义学方法,侧重于自然语言的方面能够指导我们对一致性和不一致的判断。
2 命题逻辑
查看操作符。 nltk中的Expression对象能够将逻辑表达式,处理成Expression的子类。逻辑证明通过nltk的推理模块进行。
# 命题逻辑
def propositional_logic():
# 操作符
nltk.boolean_ops()
# nltk中的Expression对象能够将逻辑表达式,处理成Expression的子类。
read_expr = nltk.sem.Expression.fromstring
result_1 = read_expr('-(P & Q)')
# print(result_1)
# 逻辑证明通过nltk的推理模块进行。例如通过第三方定理证明程序prover9的接口。
# 并且推理机制的输入必须首先转换为逻辑表达式
SnF = read_expr('SnF')
NotFns = read_expr('-FnS')
R = read_expr('SnF -> -FnS')
prover = nltk.Prover9()
result_2 = prover.prove(NotFns, [SnF, R])
print(result_2)
初始化valuation。并初始化一个模型,并用其确定逻辑表达式真值情况。
# Valuation :从逻辑的基本符号映射到他们的值。
# 链表初始化Valuation 。可以像字典一样访问
val = nltk.Valuation([('P', True), ('Q', True), ('R', False)])
dom = set()
g = nltk.Assignment(dom)
# 用val初始化模型m
m = nltk.Model(dom, val)
# 使用evaluate()可确定逻辑表达式的真值情况
result_3 = m.evaluate('(P & Q)', g)
3 一阶逻辑
检查一阶逻辑表达式的语法结构通常采用为表达式分配类型。有两种基本类型:e是实体类型,t是公式类型。e、t也是一元谓词。
read_expr = nltk.sem.Expression.fromstring
expr = read_expr('walk(angus)', type_check=True)
print(expr.argument) # angus
print(expr.argument.type) # e
print(expr.function) # walk
print(expr.function.type) # <e,?>
Expression对象中带有free()方法,该方法返回expr中空闲的变量集。
read_expr = nltk.sem.Expression.fromstring
result_1 = read_expr('dog(cyril)').free()
print(result_1) # set()
函数Valuation.fromstring(),可以将symbol => value 形式的字符串序列转换成一个Valuation对象。
# 将symbol => value 形式的字符串序列转换成一个Valuation对象。
v = """
bertie => b
olive => o
cyril => c
boy => {b}
girl => {o}
dog => {c}
walk => {o, c}
see => {(b, o), (c, b), (o, c)}
"""
val = nltk.Valuation.fromstring(v)
print(val)
3.1 独立变量和赋值
为独立变量赋值,是从独立变量到域中实体的映射。使用的是构造函数Assignment,以(变量,值)的形式来绑定。
dom = {'b', 'o', 'c'}
g = nltk.Assignment(dom, [('x', 'o'), ('y', 'c')])
print(g) # g[c/y][o/x]
在下边的为一阶逻辑的原子公式估值中,创建模型,并使用evaluate()方法计算真值。为原子公式估值过程如下:
当解释函数遇到变量y时,不是检查val中的值,而是在变量赋值g中查询这个变量的值,使用该值替换y变量,再去val中检查,得到真值结果。
dom = {'b', 'o', 'c'}
g = nltk.Assignment(dom, [('x', 'o'), ('y', 'c')])
print(g) # g[c/y][o/x]
v = """
bertie => b
olive => o
cyril => c
boy => {b}
girl => {o}
dog => {c}
walk => {o, c}
see => {(b, o), (c, b), (o, c)}
"""
val = nltk.Valuation.fromstring(v)
# 创建模型
m = nltk.Model(dom, val)
# 计算真值
true_value = m.evaluate('see(olive, y)', g)
print(true_value) # True
true_value_2 = m.evaluate('see(y,x)', g)
print(true_value_2) # False
可以评估复杂的公式。确定模型中公式的真假成为模型检查
true_value_4 = m.evaluate('see(bertie, olive) & boy(bertie) & -walk(bertie)', g)
print(true_value_4)
当g中没有对应变量的值是,结果显示Undefined
# 清除g中内容
g.purge()
true_value_3 = m.evaluate('see(olive, y)', g)
print(true_value_3) # Undefined
3.2 量化
现代逻辑的关键特征之一就是变量满足的概念,可以用来解释量化的公式。
satisfiers()方法,能够返回满足开放公式的所有个体的集合。其参数是一个已分析的公式、一个变量、一个赋值。
dom = {'b', 'o', 'c'}
g = nltk.Assignment(dom, [('x', 'o'), ('y', 'c')])
read_expr = nltk.sem.Expression.fromstring
fmla1 = read_expr('girl(x)|boy(x)')
# satisfiers()方法,能够返回满足开放公式的所有个体的集合。其参数是一个已分析的公式、一个变量、一个赋值
result_1 = m.satisfiers(fmla1, 'x', g)
print(result_1) # {'b', 'o'}
# A->B可以等价于-A|B
fmla2 = read_expr('girl(x)->walk(x)')
result_2 = m.satisfiers(fmla2, 'x', g)
print(result_2) # {'c', 'o', 'b'}
# 全称量化公式。判断g中是否所有成员都满足
result_4 = m.evaluate('all x.(girl(x) -> walk(x))', g)
print(result_4) # True
3.3 量词范围歧义
针对“Everybody admires someone.”这句话的一阶逻辑表达式有两种,分别进行匹配。
# 固定估值
v2 = """
bruce => b
elspeth => e
julia => j
matthew => m
person => {b, e, j, m}
admire => {(j, b), (b, b), (m, e), (e, m)}
"""
val2 = nltk.Valuation.fromstring(v2)
read_expr = nltk.sem.Expression.fromstring
dom2 = val2.domain
m2 = nltk.Model(dom2, val2)
g2 = nltk.Assignment(dom2)
fmla4 = read_expr('(person(x) -> exists y.(person(y) & admire(x, y)))')
result_1 = m2.satisfiers(fmla4, 'x', g2)
print(result_1) # {'e', 'j', 'm', 'b'}
# result_2的结果为空,即没有大家都钦佩的人。
fmla5 = read_expr('(person(y) & all x.(person(x) -> admire(x, y)))')
result_2 = m2.satisfiers(fmla5,'y',g2)
print(result_2) # set()
4 英语句子的语义
组合原则:整体的含义是部分的含义与它们的句法结合方式的函数