} } }

    NLTK-Chapter8.4中合适语句规矩的字串表-动态规划算法的申明

    添加时间:2013-5-17 点击量:

    一些前提数据:



    tokens = [Ishotanelephantinmypajamas]



    • tokens为将要研究的一句英词句子。



    index={(DeT, N): NP,
    
    (Det, N, PP): NP,
    (NP, VP): S,
    (P, NP): PP,
    (V, NP): VP,
    (VP, PP): VP,
    I,): NP,
    an,): Det,
    elephant,): N,
    in,): P,
    my,): Det,
    pajamas,): N,
    shot,): V}



    • index为文法的描述。

    • numtokens=7(len(tokens))为句子中单词的数量



    图8.6中为图表的数据布局


    在这个算法傍边,有一个代表图表数据布局的二维表,我们把他定名为WFST。


    经过下面的初始化函数,对WFST进行初始化:



    def init_wfst(tokens,grammar):
    
    numtokens
    =len(tokens)
    wfst
    =[
    [None
    for i in range(numtokens+1)] for j in range(numtokens+1
    ]
    for i in range(numtokens):
    productions
    =grammar.productions(rhs=tokens[i])
    wfst[i][i
    +1]=productions[0].lhs()
    return wfst


    经过初始化之后,我们可以打印WFST,发明已经变成了下面这种景象:



    [[None, NP, None, None, None, None, None, None],
    
    [None, None, V, None, None, None, None, None],
    [None, None, None, Det, None, None, None, None],
    [None, None, None, None, N, None, None, None],
    [None, None, None, None, None, P, None, None],
    [None, None, None, None, None, None, Det, None],
    [None, None, None, None, None, None, None, N],
    [None, None, None, None, None, None, None, None]]



    WFST1 2 3 4 5 6 7
    
    0 NP . . . . . .
    1 . V . . . . .
    2 . . Det . . . .
    3 . . . N . . .
    4 . . . . P . .
    5 . . . . . Det .
    6 . . . . . . N


    上方两个是等价的,只不过下面的这个图更直观,好懂得。每相邻两个节点之间是一个词,他们都有本身的词性。


    然则这些还远远不敷,为了可以或许更好的表现文法,还须要归约操纵,将一开端的图表变成如下如许的情势:



    就须要我们有一种算法,去遍历我们如今有的图表布局,来完成这个操纵。


    书中已经给出了算法的实现,我们须要重视的是,这是一个三角矩阵,不须要每个处所都遍历,同时,算法的难点是,要实现不合的单词数量的跨度,去完成图表WFST的赋值。


    书中给出的算法代码为:



    def complete_wfst(wfst,tokens, grammar,trace=False):
    
    index
    = dict((p.rhs(),p.lhs()) for p in grammar.productions())
    numtokens
    = len(tokens)
    for span in range(2, numtokens+1):
    for start in range(numtokens+1-span):
    end
    = start + span
    for mid in range(start+1, end):
    nt1,nt2
    = wfst[start][mid],wfst[mid][end]
    if nt1 and nt2 and (nt1,nt2) in index:
    wfst[start][end]
    = index[(nt1,nt2)]
    if trace:
    print [%s] %3s[%s] %3s[%s] ==>[%s] %3s[%s](start, nt1, mid,nt2,end, start, index[(nt1,nt2)], end)
    return wfst


    嵌套了很多的轮回,其实经过细心解析,此算法并不难懂得。为了更好的懂得,可以本身手动演示一下就能懂得算法的内涵,若是各位读者看着很难懂得,本身走一下法度的步调就很轻易懂得了:



    span=2:#当值为2的时辰,搜检两个词之间有没有关系
    
    range(numtokens+1-span=6)(0~5)
    start=0:
    end
    =start+span=0+2=2
    range(start+1,end)(0+1,2)
    mid=1:
    nt1
    =wfst[0][1],nt2=[1][2]
    start
    =1:
    start
    =2:
    end
    =start+span=2+2=4
    range(start+1,end)(3,4)
    mid=3:
    nt1
    =wfst[2][3],nt2=[3][4]
    start
    =3:
    start
    =4:
    start
    =5:
    span
    =3:
    range(numtokens+1-span=5)(0~4)
    start=0:
    end
    =start+span=0+3=3
    range(start+1,end)(0+1,3)
    mid=1:
    nt1
    =wfst[0][1],nt2=wfst[1][3]
    mid
    =2:
    nt1
    =wfst[0][2],nt2=wfst[2][3]
    start
    =1:
    start
    =2:
    start
    =3:
    span
    =4:
    span
    =5:
    span
    =6:
    span
    =7:




    我们永远不要期待别人的拯救,只有自己才能升华自己。自己已准备好了多少容量,方能吸引对等的人与我们相遇,否则再美好的人出现、再动人的事情降临身边,我们也没有能量去理解与珍惜,终将擦肩而过。—— 姚谦《品味》
    分享到: