9 构建基于特征的语法
英文文档 http://www.nltk.org/book/
中文文档 https://www.bookstack.cn/read/nlp-py-2e-zh/0.md
以下编号按个人习惯
Building Feature Based Grammars
1 Grammatical Features(语法特征)
探讨特征在建立基于规则的语法中的作用。
以下以句子Kim chased Lee为例,找到其动词的施事角色和主语,受事角色和宾语
def lex2fs(word):
# 以下两个对象中,不同的面向语义的特征被称为特征结构(特征+特征值)。特征结构包含各种有关语法实体的信息
kim = {'CAT': 'NP', 'ORTH': 'Kim', 'REF': 'k'}
chase = {'CAT': 'V', 'ORTH': 'chased', 'REL': 'chase'}
lee = {'CAT': 'NP', 'ORTH': 'Lee', 'REF': 'l'}
# chase为例,其主语(subject)扮演‘施事’(agent)的角色。宾语(object)扮演‘受事’(patient)的角色
chase['AGT'] = 'sbj'
chase['PAT'] = 'obj'
# fs 分别为kim,lee,chase循环
for fs in [kim, lee, chase]:
if fs['ORTH'] == word:
return fs
# 语法特征
def grammatical_features():
# 找到动词的施事角色和主语,受事角色和宾语。假设动词左右的NP分别是主语和宾语。
sent = "Kim chased Lee"
tokens = sent.split()
subj, verb, obj = lex2fs(tokens[0]), lex2fs(tokens[1]), lex2fs(tokens[2])
verb['AGT'] = subj['REF']
verb['PAT'] = obj['REF']
for k in ['ORTH', 'REL', 'AGT', 'PAT']:
print("%-5s => %s" % (k, verb[k]))
- 句法协议
动词的形态属性同主语名词短语的语法属性一起变化,此过程成为协议。例如单复数。
查看基于示例特性的语法,如下:
nltk.data.show_cfg('grammars/book_grammars/feat0.fcfg')
基于特征的语法图标解析的操作。如下,输入分词之后,导入load_parser函数,以语法文件名为输入,返回一个图表分析器cp。调用分析器的parse()方法将迭代生成的分析树。
# 基于特征跟踪的图表解析器
tokens = 'Kim likes children'.split()
# 图标分析器
cp = load_parser('grammars/book_grammars/feat0.fcfg', trace=2)
for tree in cp.parse(tokens):
print(tree)
像sg,pl这样简单的特征值成为原子,原子值的特殊情况是布尔值。
2 Processing Feature Structures(处理特征结构)
如何在NLTK中构建和操作特征结构。
使用构造函数FeatStruct()构造特征结构,像字典一样使用它。
# 特征结构构造器
fs1 = nltk.FeatStruct(PER=3, NUM='p1', GND='fem')
print(fs1['GND'])
fs1['CASE'] = 'acc'
print(fs1)
# 更复杂的特征结构
fs2 = nltk.FeatStruct(POS='N', AGR=fs1)
print(fs2)
print(fs2['AGR'])
# 使用feature=value格式的特征-值对的方括号扩起的字符串
fs3 = nltk.FeatStruct("[POS='N', AGR=[PER=3, NUM='pl', GND='fem']]")
print(fs3)
特征结构也可以看做一个有向无环图(DAG),如下,
- 要素名称在弧上显示为标签,要素值在弧所指的节点上显示为标签。
- 特征路径是从根节点遵循圆弧的序列,用元组表示,例如(‘ADDRESS’,‘STREET’),值为‘Rue Pascal’的节点。
- 当结构中存在相同的信息时,可以在不同弧之间共享相同的子图,例如(‘address’,‘street’)和(‘spouse’,‘address’,‘street’)共享了地址信息。这种情况是结构共享或可重入性。
在代码中为了指示可重入性,在共享特征结构的首次出现时在括号中添加一个整数,之后对该结构的引用使用括号加数字。这种引用可以有任意数目个。
fs4 = nltk.FeatStruct("[NAME='Lee', ADDRESS=(1)[NUMBER=74, STREET='rue Pascal'],SPOUSE=[NAME='Kim', ADDRESS->(1)]]")
统一:合并两个特征结构,unify()函数实现。如果fs0和fs1的特征结构共享一个路径目录,那么fs0和fs1的统一就会失败,但是fs0中的value和fs1中的value是完全不同的。这是通过将统一的结果设置为None来实现的。
fs1 = nltk.FeatStruct(NUMBER=74, STREET='rue Pascal')
fs2 = nltk.FeatStruct(CITY='Paris')
print(fs1.unify(fs2))
当针对上面结构共享中,修改某个变量时,被引用的地方也会被修改。
3 Extending a Feature based Grammar(扩展基于特征的语法)
广义短语结构文法,通过允许词汇类别支持SUBCAT特征。设SUBCAT特征表明该项目所属的子类别。
因为可以无限的加深句子补语的递归,所以在整个句子中缺口可以无限远的被填充。无限制依赖成分:填充词-缺口依赖,即填充词和缺口之间的距离没有上界。
tokens = 'who do you claim that you like'.split()
cp = load_parser('grammars/book_grammars/feat1.fcfg')
for tree in cp.parse(tokens):
print(tree)