2 处理特征结构
在本节中,我们将展示如何在 NLTK 中构建和操作特征结构。我们还将讨论统一的基本操作,这使我们能够结合两个不同的特征结构中的信息。
NLTK 中的特征结构使用构造函数FeatStruct()
声明。原子特征值可以是字符串或整数。
>>> fs1 = nltk.FeatStruct(TENSE='past', NUM='sg')
>>> print(fs1)
[ NUM = 'sg' ]
[ TENSE = 'past' ]
一个特征结构实际上只是一种字典,所以我们可以平常的方式通过索引访问它的值。我们可以用我们熟悉的方式 赋 值给特征:
>>> fs1 = nltk.FeatStruct(PER=3, NUM='pl', GND='fem')
>>> print(fs1['GND'])
fem
>>> fs1['CASE'] = 'acc'
我们还可以为特征结构定义更复杂的值,如前面所讨论的。
>>> fs2 = nltk.FeatStruct(POS='N', AGR=fs1)
>>> print(fs2)
[ [ CASE = 'acc' ] ]
[ AGR = [ GND = 'fem' ] ]
[ [ NUM = 'pl' ] ]
[ [ PER = 3 ] ]
[ ]
[ POS = 'N' ]
>>> print(fs2['AGR'])
[ CASE = 'acc' ]
[ GND = 'fem' ]
[ NUM = 'pl' ]
[ PER = 3 ]
>>> print(fs2['AGR']['PER'])
3
指定特征结构的另一种方法是使用包含feature=value
格式的特征-值对的方括号括起的字符串,其中值本身可能是特征结构:
>>> print(nltk.FeatStruct("[POS='N', AGR=[PER=3, NUM='pl', GND='fem']]"))
[ [ GND = 'fem' ] ]
[ AGR = [ NUM = 'pl' ] ]
[ [ PER = 3 ] ]
[ ]
[ POS = 'N' ]
特征结构本身并不依赖于语言对象;它们是表示知识的通用目的的结构。例如,我们可以将一个人的信息用特征结构编码:
>>> print(nltk.FeatStruct(NAME='Lee', TELNO='01 27 86 42 96', AGE=33))
[ AGE = 33 ]
[ NAME = 'Lee' ]
[ TELNO = '01 27 86 42 96' ]
在接下来的几页中,我们会使用这样的例子来探讨特征结构的标准操作。这将使我们暂时从自然语言处理转移,因为在我们回来谈论语法之前需要打下基础。坚持!
将特征结构作为图来查看往往是有用的;更具体的,作为有向无环图(DAG)。(19)等同于上面的 AVM。
>>> print(nltk.FeatStruct("""[NAME='Lee', ADDRESS=(1)[NUMBER=74, STREET='rue Pascal'],
... SPOUSE=[NAME='Kim', ADDRESS->(1)]]"""))
[ ADDRESS = (1) [ NUMBER = 74 ] ]
[ [ STREET = 'rue Pascal' ] ]
[ ]
[ NAME = 'Lee' ]
[ ]
[ SPOUSE = [ ADDRESS -> (1) ] ]
[ [ NAME = 'Kim' ] ]
括号内的整数有时也被称为标记或同指标志。整数的选择并不重要。可以有任意数目的标记在一个单独的特征结构中。
>>> print(nltk.FeatStruct("[A='a', B=(1)[C='c'], D->(1), E->(1)]"))
[ A = 'a' ]
[ ]
[ B = (1) [ C = 'c' ] ]
[ ]
[ D -> (1) ]
[ E -> (1) ]