python自然语言处理 | 分析句子结构
- 本章解決的問題
這里寫目錄標(biāo)題
- 1 一些語法困境
- 1.1 語言數(shù)據(jù)和無限可能性
- 1.2 普遍存在的歧義
- 2 文法有什么用?
- 2.1 超越 n-grams
- 3 上下文無關(guān)文法
- 3.1 一種簡單的文法
- 3.2 寫你自己的文法
- 3.3 句法結(jié)構(gòu)中的遞歸
- 4 上下文無關(guān)文法分析
- 4.2 4.2 移進(jìn)-歸約分析
- 4.3 左角落分析器
- 4.4 符合語句規(guī)則的子串表 WFST
- 5 依存關(guān)系和依存文法
- 5.1 配價(jià)與詞匯
- 5.2 擴(kuò)大規(guī)模
- 6 文法開發(fā)
- 6.1 樹庫和文法
- 6.2 有害的歧義
- 6.3 加權(quán)文法
- 7 小結(jié)
1 一些語法困境
1.1 語言數(shù)據(jù)和無限可能性
1.2 普遍存在的歧義
#讓我們仔細(xì)看看短語 I shot an elephant in my pajamas 中的歧義。 #首先,我們需要定義一個(gè)簡單的文法: import nltk groucho_grammar = nltk.CFG.fromstring("""S -> NP VPPP -> P NPNP -> Det N | Det N PP | 'I'VP -> V NP | VP PPDet -> 'an' | 'my'N -> 'elephant' | 'pajamas'V -> 'shot'P -> 'in'""") #這個(gè)文法允許以兩種方式分析句子,取決于介詞短語 in my pajamas 是描述大象還是槍擊事件。 sent = ['I', 'shot', 'an', 'elephant', 'in', 'my', 'pajamas'] parser = nltk.ChartParser(groucho_grammar) for tree in parser.parse(sent):print(tree)tree.draw()""" (S(NP I)(VP(VP (V shot) (NP (Det an) (N elephant)))(PP (P in) (NP (Det my) (N pajamas))))) (S(NP I)(VP(V shot)(NP (Det an) (N elephant) (PP (P in) (NP (Det my) (N pajamas))))))"""本章介紹文法和分析,以形式化可計(jì)算的方法調(diào)查和建模我們一直在討論的語言現(xiàn)象正如我們所看到的,詞序列中符合語法規(guī)則的和不符合語法規(guī)則的模式相對于短語結(jié)構(gòu)和依賴是可以被理解的。我們可以開發(fā)使用文法和分析的這些結(jié)構(gòu)的形式化模型。與以前一樣,一個(gè)重要的動(dòng)機(jī)是自然語言理解。當(dāng)我們能可靠地識(shí)別一個(gè)文本所包含的語言結(jié)構(gòu)時(shí),我們從中可以獲得多少文本的含義?
2 文法有什么用?
2.1 超越 n-grams
- 成分結(jié)構(gòu)基于對詞與其他詞結(jié)合在一起形成單元的觀察。一個(gè)詞序列形成這樣一個(gè)單元的證據(jù)是它是可替代的——也就是說,在一個(gè)符合語法規(guī)則的句子中的詞序列可以被一個(gè)更小的序列替代而不會(huì)導(dǎo)致句子不符合語法規(guī)則。
3 上下文無關(guān)文法
3.1 一種簡單的文法
""" #首先,讓我們看一個(gè)簡單的上下文無關(guān)文法 # 按照慣例, 第一條生產(chǎn)式的左端是文法的開始符號(hào),通常是 S(句子),所有符合語法規(guī)則的樹都必須有這個(gè)符 號(hào)作為它們的根標(biāo)簽。 # NLTK中,上下文無關(guān)文法定義在 nltk.grammar 模塊。 """#上下文無關(guān)文法 grammar1 = 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(grammar1) for tree in rd_parser.parse(sent):print(tree)tree.draw()文法組成部分的不同提取方式會(huì)產(chǎn)生不一樣的意思:
3.2 寫你自己的文法
import nltkdef yours_grammar(gram):sent = "Mary saw Bob".split()rd_parser = nltk.RecursiveDescentParser(gram)for tree in rd_parser.parse(sent):print(tree)tree.draw()grammar1 =nltk.data.load('file:mygrammar.cfg') # #確保你的文件名后綴為.cfg,并且字符串'file:mygrammar.cfg中'間沒有空格符 print(yours_grammar(grammar1))3.3 句法結(jié)構(gòu)中的遞歸
#一個(gè)文法被認(rèn)為是遞歸的,如果文法類型出現(xiàn)在產(chǎn)生式左側(cè)也出現(xiàn)在右側(cè), #如例 8-2 所 示。產(chǎn)生式 Nom -> Adj Nom(其中 Nom 是名詞性的類別)包含 Nom 類型的直接遞歸, #而 S 上的間接遞歸來自于兩個(gè)產(chǎn)生式的組合:S -> NP VP 與 VP -> V S。#例. 遞歸的上下文無關(guān)文法。 grammar2 = nltk.CFG.fromstring("""S -> NP VPNP -> Det Nom | PropNNom -> Adj Nom | NVP -> V Adj | V NP | V S | V NP PPPP -> P NPPropN -> 'Buster' | 'Chatterer' | 'Joe'| 'Today'Det -> 'the' | 'a'N -> 'bear' | 'squirrel' | 'tree' | 'fish' | 'log' | 'Sunday' Adj -> 'angry' | 'frightened' | 'little' | 'tall' | 'sunny'V -> 'chased' | 'saw' | 'said' | 'thought' | 'was' | 'put' | 'is'P -> 'on'""") def yours_grammar(sent, gram):rd_parser = nltk.RecursiveDescentParser(gram)for tree in rd_parser.parse(sent):print(tree)tree.draw() sent1 = "the angry bear chased the frightened little squirrel".split() sent2 = "Chatterer said Buster thought the tree was tall".split() sent3 = "Today is sunny".split() print("sent1: ") print(yours_grammar(sent1, grammar2)) print("sent2: ") print(yours_grammar(sent2, grammar2)) print("sent3: ") print(yours_grammar(sent3, grammar2)) # 不添加會(huì)報(bào)錯(cuò) Grammar does not cover some of the input words: "'Today', 'is', 'Sunday'".4 上下文無關(guān)文法分析
4.2 4.2 移進(jìn)-歸約分析
簡單的自下而上分析器是移進(jìn)-歸約分析器。
移進(jìn)-規(guī)約分析器缺點(diǎn)可能會(huì)到達(dá)一個(gè)死胡同,而不能找到任何解析,即使輸入的句子是符合語法的。這種情況發(fā)生時(shí),沒有剩余的輸入,而堆棧包含不能被規(guī)約到一個(gè)S的項(xiàng)目。
問題出現(xiàn)的原因是:較早前做出的選擇不能被分析器撤銷(雖然圖形演示中用戶可以撤消它們的選擇)。
分析器可以做兩種選擇:(a)當(dāng)有多種規(guī)約可能時(shí)選擇哪個(gè)規(guī)約,(b)當(dāng)移進(jìn)和規(guī)約都可以時(shí)選擇哪個(gè)動(dòng)作。
移進(jìn)-規(guī)約分析器可以改進(jìn)執(zhí)行策略來解決這些沖突。例如:它可以通過只有在不能規(guī)約時(shí)才移進(jìn),解決移進(jìn)-規(guī)約沖突;它可以通過優(yōu)先執(zhí)行規(guī)約操作,解決規(guī)約-規(guī)約沖突;它可以從堆棧移除更多的項(xiàng)目。(一個(gè)通用的移進(jìn)-規(guī)約分析器,是一個(gè)“超前LR分析器”,普遍使用在編程語言編譯器中。)
移進(jìn)-規(guī)約分析器相比遞歸下降分析器的好處是,它們只建立與輸入中的詞對應(yīng)的結(jié)構(gòu)。此外,每個(gè)結(jié)構(gòu)它們只建立一次。例如:NP(Det(the),N(man))只建立和壓入棧一次,不管以后VP -> V NPPP規(guī)約或者NP ->NPPP規(guī)約會(huì)不會(huì)用到。
4.3 左角落分析器
4.4 符合語句規(guī)則的子串表 WFST
""" #運(yùn)用動(dòng)態(tài) 規(guī)劃算法設(shè)計(jì)技術(shù)分析問題 #動(dòng)態(tài)規(guī)劃存儲(chǔ)中間結(jié)果,并在 適當(dāng)?shù)臅r(shí)候重用它們,能顯著提高效率。#這種技術(shù)可以應(yīng)用到句法分析,使我們能夠存儲(chǔ)分析任務(wù)的部分解決方案, #然后在必要的時(shí)候查找它們,直到達(dá)到最終解決方案。這種分析方法被稱為圖表分析。#動(dòng)態(tài)規(guī)劃使我們能夠只建立一次 PP in my pajamas。 #第一次我們建立時(shí)就把它存入一 個(gè)表格中,然后在我們需要作為對象 NP 或更高的 VP 的組成部分用到它時(shí)我們就查找表格。 #這個(gè)表格被稱為符合語法規(guī)則的子串表 或簡稱為 WFST。 """#使用符合語句規(guī)則的子串表的接收器。 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 wfstdef 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 + spanfor 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 wfstdef display(wfst, tokens):print('\nWFST ' + ' '.join(("%-4d" % i) for i in range(1, len(wfst))))for i in range(len(wfst)-1):print("%d " % i, end=" ")for j in range(1, len(wfst)):print("%-4s" % (wfst[i][j] or '.'), end=" ")print() tokens = "I shot an elephant in my pajamas".split() wfst0 = init_wfst(tokens, groucho_grammar) display(wfst0, tokens) wfst1 = complete_wfst(wfst0, tokens, groucho_grammar) display(wfst1, tokens) wfst1 = complete_wfst(wfst0, tokens, groucho_grammar, trace=True) # 找出過程 設(shè)置參數(shù)trace5 依存關(guān)系和依存文法
5.1 配價(jià)與詞匯
-
動(dòng)詞和它們的依賴
-
依賴 ADJ、NP、PP 和 S 通常被稱為各自動(dòng)詞的補(bǔ)語,什么動(dòng)詞可以和什么補(bǔ)語一起出現(xiàn) 具有很強(qiáng)的約束。
-
在依存文法的傳統(tǒng)中,在表 8-3 中的動(dòng)詞被認(rèn)為具有不同的配價(jià)。配價(jià)限制不僅適用于 動(dòng)詞,也適用于其他類的中心詞。
-
介詞短語、形容詞和副詞通常充當(dāng)修飾語。與補(bǔ)充不同修飾語是可選的,經(jīng)常可以進(jìn)行 迭代,不會(huì)像補(bǔ)語那樣被中心詞選擇。
5.2 擴(kuò)大規(guī)模
到目前為止,我們只考慮了“玩具文法”,演示分析的關(guān)鍵環(huán)節(jié)的少量的文法,但有一個(gè)明顯的問題就是這種做法是否可以擴(kuò)大到覆蓋自然語言的大型語料庫。
很難將文法模塊化,每部分文法可以獨(dú)立開發(fā)。反過來這意味著,在一個(gè)語言學(xué)家團(tuán)隊(duì)中分配編寫文法的任 務(wù)是很困難的。
另一個(gè)困難是當(dāng)文法擴(kuò)展到包括更加廣泛的成分時(shí),適用于任何一個(gè)句子的分析的數(shù)量也相應(yīng)增加。 換句話說,歧義隨著覆蓋而增加。
6 文法開發(fā)
分析器根據(jù)短語結(jié)構(gòu)文法在句子上建立樹。現(xiàn)在,我們上面給出的所有例子只涉及玩具文法包含少數(shù)的產(chǎn)生式。如果我們嘗試擴(kuò)大這種方法的規(guī)模來處理現(xiàn)實(shí)的語言語料庫會(huì)發(fā)生什么?在本節(jié)中,我們將看到如何訪問樹庫,并看看開發(fā)廣泛覆蓋的文法的挑戰(zhàn)。
6.1 樹庫和文法
# corpus 模塊定義了樹庫語料的閱讀器,其中包含了賓州樹庫語料的 10%的樣本。 from nltk.corpus import treebank t = treebank.parsed_sents('wsj_0001.mrg')[0] print(t) #我們可以利用這些數(shù)據(jù)來幫助開發(fā)一個(gè)文法。 #搜索樹庫找出句子的補(bǔ)語。 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) from nltk.corpus import treebank print([subtree for tree in treebank.parsed_sents() for subtree in tree.subtrees(filter)][1]) #NLTK 語料庫也收集了中央研究院樹庫語料,包括 10000 句已分析的句子,來自現(xiàn)代漢 語中央研究院平衡語料庫。 #讓我們加載并顯示這個(gè)語料庫中的一棵樹。 print(nltk.corpus.sinica_treebank.parsed_sents()[3449].draw())6.2 有害的歧義
不幸的是,隨著文法覆蓋范圍的增加和輸入句子長度的增長,分析樹的數(shù)量也迅速增長事實(shí)上,它以天文數(shù)字的速度增長。
grammar = nltk.CFG.fromstring("""S -> NP V NPNP -> NP SbarSbar -> NP VNP -> 'fish'V -> 'fish'""") tokens = ['fish'] * 5 cp = nltk.ChartParser(grammar) for tree in cp.parse(tokens):print(tree) #隨著句子長度增加到(3,5,7,...),我們得到的分析樹的數(shù)量是:1; 2; 5; 14; 42; 132; 429; 1,430; 4,862; 16,796; 58,786; 208,012; ....6.3 加權(quán)文法
- 概率上下文無關(guān)文法(probabilistic context-free grammar,PCFG)
7 小結(jié)
總結(jié)
以上是生活随笔為你收集整理的python自然语言处理 | 分析句子结构的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电信4G物联网卡、流量卡资费,13位物联
- 下一篇: LaTeX入门学习9(tikz基础-01