zoukankan      html  css  js  c++  java
  • 【语言处理与Python】9.1文法特征

    为了获得更大的灵活性,我们改变我们对待文法类别,如S,NP,V的方式,我们将这些原子标签分解为类似字典的结构,以便可以提取一系列的值作为特征。

    9.1文法特征

    先从一个简单的例子开始,使用字典存储特征和他们的值。

    >>>kim = {'CAT':'NP', 'ORTH': 'Kim', 'REF': 'k'}
    >>>chase = {'CAT':'V', 'ORTH': 'chased', 'REL': 'chase'}

    CAT:文法类别;ORTH:拼写;REF:给出指示物或者关系。在基于规则的文法上下文中,这样的特征和特征值对被称为特征结构。

    根据需要,我们还可以添加特征

    >>>chase['AGT'] = 'sbj'
    >>>chase['PAT'] = 'obj'

    AGT :施事的角色,PAT:受事的角色,在这里是宾语。

    例如,我们现在要处理句子:Kim chased Lee.

    >>>sent = "Kim chased Lee"
    >>>tokens = sent.split()
    >>>lee = {'CAT':'NP', 'ORTH': 'Lee', 'REF': 'l'}
    >>>def lex2fs(word):
        ... for fs in [kim, lee, chase]:
    ...         if fs['ORTH'] ==word:
    ...             return fs
    >>>subj, verb, obj = lex2fs(tokens[0]), lex2fs(tokens[1]), lex2fs(tokens[2])
    >>>verb['AGT'] = subj['REF'] #agent of 'chase' is Kim
    >>>verb['PAT'] =obj['REF'] #patient of 'chase' is Lee
    >>>for kin ['ORTH', 'REL', 'AGT', 'PAT']: #checkfeatstruct of'chase'
    ... print "%-5s =>%s"%(k, verb[k])
    ORTH =>chased
    REL =>chase
    AGT =>k
    PAT =>l

    同样的方法可以适用不同的动词,可以添加更多的特征,例如:

    >>>surprise = {'CAT':'V', 'ORTH': 'surprised', 'REL': 'surprise',
    ... 'SRC': 'sbj', 'EXP': 'obj'}

    句法协议

    动词的形态属性与主语名词短语的属性一起变化,这种变化被成为协议(agreement)。

    例如:

    a. the dog runs
    b.*the dog run
    a. the dogs run
    b.*the dogs runs

    我们可以使用改进文法的方式,来处理这种情况,下面是一个例子,但是需要注意,这种方法是非常麻烦的。

    改进之前的文法:

    (7) S -> NPVP
    NP -> DetN
    VP -> V
    Det -> 'this'
    N -> 'dog'
    V -> 'runs'

    改进之后的文法:

    (8) S -> NP_SGVP_SG
    S -> NP_PLVP_PL
    NP_SG-> Det_SGN_SG
    NP_PL-> Det_PLN_PL
    VP_SG-> V_SG
    VP_PL-> V_PL
    Det_SG-> 'this'
    Det_PL-> 'these'
    N_SG-> 'dog'
    N_PL-> 'dogs'
    V_SG-> 'runs'
    V_PL-> 'run'

    为了避免这种爆炸式的增加,我们可以使用属性和约束。

    使用属性和约束

    Det[NUM=sg]-> 'this'
    Det[NUM=pl]-> 'these'
    N[NUM=sg]-> 'dog'
    N[NUM=pl]-> 'dogs'
    V[NUM=sg]-> 'runs'
    V[NUM=pl]-> 'run'

    我们可以使用?n来改进:

    S -> NP[NUM=?n]VP[NUM=?n]
    NP[NUM=?n]-> Det[NUM=?n]N[NUM=?n]
    VP[NUM=?n]-> V[NUM=?n]

    但是有些词是对单复数没有挑剔的,有两种表示方法,很显然,第二种,是比第一种要简单明了的。

    第一种:

    Det[NUM=sg]-> 'the' | 'some' | 'several'
    Det[NUM=pl]-> 'the' | 'some' | 'several'

    第二种:

    Det[NUM=?n]-> 'the' | 'some' | 'several'

    下面的代码演示了到目前为止在本章中介绍过的大多数想法:

    >>>nltk.data.show_cfg('grammars/book_grammars/feat0.fcfg')
    %start S
    ####################
    #GrammarProductions
    ####################
    #S expansion productions
    S -> NP[NUM=?n]VP[NUM=?n]
    #NPexpansion productions
    NP[NUM=?n]-> N[NUM=?n]
    NP[NUM=?n]-> PropN[NUM=?n]
    NP[NUM=?n]-> Det[NUM=?n]N[NUM=?n]
    NP[NUM=pl]-> N[NUM=pl]
    #VPexpansion productions
    VP[TENSE=?t,NUM=?n]-> IV[TENSE=?t, NUM=?n]
    VP[TENSE=?t,NUM=?n]-> TV[TENSE=?t,NUM=?n]NP
    ####################
    #LexicalProductions
    ####################
    Det[NUM=sg]-> 'this' | 'every'
    Det[NUM=pl]-> 'these' | 'all'
    Det-> 'the' | 'some' | 'several'
    PropN[NUM=sg]->'Kim' | 'Jody'
    N[NUM=sg]-> 'dog' | 'girl' | 'car' | 'child'
    N[NUM=pl]-> 'dogs' | 'girls' | 'cars' | 'children'
    IV[TENSE=pres, NUM=sg]-> 'disappears' | 'walks'
    TV[TENSE=pres,NUM=sg]-> 'sees' | 'likes'
    IV[TENSE=pres, NUM=pl]-> 'disappear' | 'walk'
    TV[TENSE=pres,NUM=pl]-> 'see' | 'like'
    IV[TENSE=past] -> 'disappeared' | 'walked'
    TV[TENSE=past]-> 'saw' | 'liked'

    下面的代码展示了,如何解析一句话:

    如果文法无法分析输入,trees将为空,否则会包含一个或多个分析树。取决于舒服是否有句法歧义。

    >>>tokens = 'Kim likes children'.split()
    >>>from nltk import load_parser �
    >>>cp = load_parser('grammars/book_grammars/feat0.fcfg', trace=2) �
    >>>trees = cp.nbest_parse(tokens)
    |.Kim .like.chil.|
    |[----] . .| PropN[NUM='sg']-> 'Kim' *
    |[----] . .| NP[NUM='sg']-> PropN[NUM='sg']*
    |[----> . .| S[]-> NP[NUM=?n]*VP[NUM=?n]{?n: 'sg'}
    |. [----] .| TV[NUM='sg',TENSE='pres']-> 'likes' *
    |. [----> .| VP[NUM=?n,TENSE=?t]-> TV[NUM=?n,TENSE=?t]*NP[]
    {?n: 'sg', ?t: 'pres'}
    |. . [----]| N[NUM='pl']-> 'children' *
    |. . [----]| NP[NUM='pl']-> N[NUM='pl']*
    |. . [---->| S[]-> NP[NUM=?n]*VP[NUM=?n]{?n: 'pl'}
    |. [---------]| VP[NUM='sg',TENSE='pres']
    -> TV[NUM='sg',TENSE='pres']NP[]*
    |[==============]| S[]-> NP[NUM='sg']VP[NUM='sg']*

    最后,可以检查分析树:

    >>>for tree in trees: print tree
    (S[]
    (NP[NUM='sg'] (PropN[NUM='sg'] Kim))
    (VP[NUM='sg', TENSE='pres']
    (TV[NUM='sg', TENSE='pres']likes)
    (NP[NUM='pl'] (N[NUM='pl'] children))))

    术语

    像sg,pl这样的简单的值通常被成为原子。原子值的一种特殊情况是布尔值,仅仅指定一个属性是真还是假。

    例如AUX代表助动词。

    V[TENSE=pres,aux=+]->'can'

    有的时候,我们可以将协议特征组合在一起,作为一个类别的不同部分,表示AGR的值。

    属性值矩阵:AVM

    [POS = N ]
    [                  ]
    [AGR = [PER = 3 ]]
    [ [NUM = pl ]]
    [ [GND = fem ]]

    当有复杂的属性时,可以重构文法:

    S -> NP[AGR=?n]VP[AGR=?n]
    NP[AGR=?n]-> PropN[AGR=?n]
    VP[TENSE=?t,AGR=?n]-> Cop[TENSE=?t,AGR=?n]Adj
    Cop[TENSE=pres, AGR=[NUM=sg,PER=3]]-> 'is'
    PropN[AGR=[NUM=sg,PER=3]]-> 'Kim'
    Adj-> 'happy'
  • 相关阅读:
    Android集成科大讯飞SDK语音听写及语音合成功能实现
    Android开发中一些常见的问题解决方案
    Android混淆配置文件规范
    android第三方分享之友盟社会化组件
    android一些常用的代码2(收藏)
    svn
    ubuntu 解决中文zip乱码问题
    android优秀Github源码整理
    linux清理内存
    cocos2d-x图层相关 锚点
  • 原文地址:https://www.cnblogs.com/createMoMo/p/3114266.html
Copyright © 2011-2022 走看看