NLTK学习笔记(八):文法--词关系研究的工具
目錄
- 文法
- 自定義文法
- 文法用途
- 開發(fā)文法
- 分析文法的算法
- 遞歸下降解析器
- 移進(jìn)-歸約解析器
- 基于特征的文法
- 屬性和約束
- 處理特征結(jié)構(gòu)
- 包含和統(tǒng)一
- 總結(jié)
對于一門語言來說,一句話有無限可能。問題是我們只能通過有限的程序來分析結(jié)構(gòu)和含義。嘗試將“語言”理解為:僅僅是所有合乎文法的句子的大集合。在這個思路的基礎(chǔ)上,類似于 word -> word and/or/... word 就成立,這種式子叫做遞歸產(chǎn)生式。理論上,句子可以無限擴(kuò)充。
文法
自定義文法
寫法上與上一篇博文的分類規(guī)則思路基本一致,并且更簡單、更直觀,可以和之前的對比著看。
import nltk from nltk import CFGgrammar = nltk.CFG.fromstring("""S -> NP VPVP -> V NP | V NP PPPP -> P NPV -> "saw" | "ate" | "walked"NP -> "John" | "Mary" | "Bob" | Det N | Det N PPDet -> "a" | "an" | "the" | "my"N -> "man" | "dog" | "cat" | "telescope" | "park"P -> "in" | "on" | "by" | "with"""") sent = 'Mary saw Bob'.split() rd_parser = nltk.RecursiveDescentParser(grammar) for i in rd_parser.parse(sent):print(i)在定義文法的時候,NP->'New York'應(yīng)該寫成 NP->'New_York',連接作用的空格應(yīng)該用_代替。
文法用途
語言基本可以說是由修飾結(jié)構(gòu)和并列結(jié)構(gòu)拼接而成(不喜勿噴)。比如下面這樣不斷的擴(kuò)充:
顯然正常的句子是第四句,如果將上述過程倒過來從4->1。最終就可以得到兩個元素。也就是說:再復(fù)合語法規(guī)則句子中的詞序列可以被一個更小的且不會導(dǎo)致句子不符合語法規(guī)則的序列代替。下面兩張圖,第一張代表詞序列的替換。第二張是根據(jù)文法規(guī)則畫出的圖。(附截圖*2)
開發(fā)文法
下面程序展示了利用簡單的過濾器,找出帶句子補(bǔ)語的動詞
from nltk.corpus import treebank t = treebank.parsed_sents('wsj_0001.mrg')[0] print(t) #查看封裝好的文法def filter(tree):child_nodes = [child.label() for child in tree if isinstance(child,nltk.Tree)]return (tree.label() == 'VP') and ('S' in child_nodes)#找出帶句子補(bǔ)語的動詞[subtree for tree in treebank.parsed_sents() \for subtree in tree.subtrees(filter)]分析文法的算法
以下是前兩種分析算法對應(yīng)的解析器。
遞歸下降解析器
三個主要缺點(diǎn):
- 左遞歸產(chǎn)生式:NP-> NP PP 會陷入死循環(huán)
- 處理不符合句子的詞和結(jié)構(gòu)時候浪費(fèi)時間
- 回溯過程過重會丟掉計算過的分析,重新計算
可以調(diào)用nltk.app.rdparser()來查看分析過程
移進(jìn)-歸約解析器
此解析器反復(fù)將下個輸入詞push進(jìn)堆棧,成為移位操作。如果堆棧前n項,匹配表達(dá)式右側(cè)的n個項目,彈出棧,并且將產(chǎn)生式左邊項目壓如棧,稱為歸約操作。
兩個缺點(diǎn):
- 由于堆棧的特殊性,只能找到一種解析
- 不能保證一定能找到解析
基于特征的文法
怎么對文法進(jìn)行更細(xì)微的控制,用什么結(jié)構(gòu)來表示?可以將標(biāo)簽分解為類似字典的結(jié)構(gòu),提取一系列的值作為特征。
屬性和約束
首先看一個例子,通過nltk.data.show_cfg('grammars/book_grammars/feat0.fcfg') :
% start S # ################### # Grammar Productions # ################### # S expansion productions S -> NP[NUM=?n] VP[NUM=?n] # NP expansion 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] # VP expansion productions VP[TENSE=?t, NUM=?n] -> IV[TENSE=?t, NUM=?n] VP[TENSE=?t, NUM=?n] -> TV[TENSE=?t, NUM=?n] NP # ################### # Lexical Productions # ################### 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'類似于字典的規(guī)則,NUM,TENSE等就是屬性,press,sg,pl就是約束。這樣我們就能顯示指明'the some dogs'這樣的句子,而不是'the some dog'。
其中,sg代表單數(shù),pl代表復(fù)數(shù),?n代表不確定(皆可)。類似sg,pl這樣的特征值稱為原子,原子也可以是bool值,并且用+aux 和 -aux分別表示True 和 False。
處理特征結(jié)構(gòu)
NLTK的特征結(jié)構(gòu)使用構(gòu)造函數(shù)FeatStuct()來進(jìn)行聲明,原子特征值可以是字符串或者整數(shù)。簡單示例:
fs1 = nltk.FeatStruct("[TENSE = 'past',NUM = 'sg',AGR=[NUM='pl',GND = 'fem']]") print(fs1) print(fs1['NUM'])#可以像字典那樣進(jìn)行訪問打印出來發(fā)現(xiàn)是矩陣形式。為了在矩陣中表示重入,可以在共享特征結(jié)構(gòu)的地方加一個括號包圍的數(shù)字前綴,例如(1)。以后對任意這個結(jié)構(gòu)的引用都使用(1)
print(nltk.FeatStruct("""[NAME = 'Lee',ADDRESS=(1)[NUMBER=74,STREET='rue Pascal'],SPOUSE =[NAME='Kim',ADDRESS->(1)]]"""))結(jié)果如下:
[ ADDRESS = (1) [ NUMBER = 74 ] ]
[ [ STREET = 'rue Pascal' ] ]
[ ]
[ NAME = 'Lee' ]
[ ]
[ SPOUSE = [ ADDRESS -> (1) ] ]
[ [ NAME = 'Kim' ] ]
結(jié)果可以看成一個圖結(jié)構(gòu),如果沒有這種(num),就是有向無環(huán)圖;有的話,就有環(huán)了。(附截圖)
包含和統(tǒng)一
如果有兩種結(jié)構(gòu):
a.[num = 74] b.[num = 74][street = 'BeiJing']那么b包含a。類似于集合運(yùn)算,這個順序稱為包含。
統(tǒng)一就是合并兩個結(jié)構(gòu),但是如果相同的屬性有不同的值,那么會返回None類型。
fs1 = nltk.FeatStruct(NUMBER = 74) fs2 = nltk.FeatStruct(City = 'BeiJint') #fs2 = nltk.FeatStruct(NUMBER= 45)#返回None print(fs2.unify(fs1))總結(jié)
在NLP中中,簡單的說:文法=語法=詞法+句法。
???它是語言學(xué)的一個分支,研究按確定用法來運(yùn)用的"詞類"、"詞"的曲折變化或表示相互關(guān)系的其他手段以及詞在句中的功能和關(guān)系。包含詞的構(gòu)詞、構(gòu)形的規(guī)則和組詞成句的規(guī)則。
???由于,不同的文法框架在寫法上也有差異,所以在構(gòu)造的時候需要具體查看相關(guān)文檔和庫的要求。這方面的編程,更多的是在規(guī)則的基礎(chǔ)上對詞和詞類的關(guān)系進(jìn)行研究,并且不斷完善文法規(guī)則。
歡迎進(jìn)一步交流本博文相關(guān)內(nèi)容:
博客園地址 : http://www.cnblogs.com/AsuraDong/
CSDN地址 : http://blog.csdn.net/asuradong
也可以致信進(jìn)行交流 : xiaochiyijiu@163.com
歡迎轉(zhuǎn)載 , 但請指明出處 ?:??)
轉(zhuǎn)載于:https://www.cnblogs.com/AsuraDong/p/7055213.html
總結(jié)
以上是生活随笔為你收集整理的NLTK学习笔记(八):文法--词关系研究的工具的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python多线程参考资料
- 下一篇: maven目录介绍