2016-08-28 87 views
0
import nltk 
from nltk.parse.generate import generate,demo_grammar 
from nltk import CFG 
grammar = CFG.fromstring(""" 
ROOT -> S 
S -> NP VP 
NP -> NP PP 
NP -> DT NN 
DT -> 'The' 
NN -> 'work' 
PP -> IN NP 
IN -> 'of' 
NP -> DT NN 
DT -> 'the' 
NN -> 'painter' 
VP -> VBZ ADJP 
VBZ -> 'is' 
ADJP -> JJ 
JJ -> 'good' 
""")  
print(grammar) 
for sentence in generate(grammar, n=100): 
    print(' '.join(sentence)) 

給出了一個錯誤NLTK CFG遞歸深度誤差

RuntimeError: maximum recursion depth exceeded while calling a Python object 

試圖改變在functools.py隱蔽功能,還是同樣的問題。

+0

查看https://github.com/nltk/nltk/issues/7 – alvas

+0

看過帖子。所以問題一直持續到日期,是嗎? –

+0

這不是圖書館的問題。這是你如何定義語法的一個問題。你看到語法中出現無限循環的部分嗎? – alvas

回答

3

函數generate作爲其文檔字符串狀態「生成CFG中所有句子的迭代器」。顯然,它通過按文件中列出的順序選擇替代擴展來實現。所以,第一次看到一個NP,它用規則NP -> NP PP擴展它。它現在有另一個NP擴大,它也擴大與相同的規則......等等無限期,或者直到超過python的限制。

要解決與您提供的語法問題,只需重新排序前兩個NP規則,使遞歸規則不是第一個遇到的:

grammar = CFG.fromstring(""" 
ROOT -> S 
S -> NP VP 
NP -> DT NN 
NP -> NP PP 
DT -> 'The' 
... 
""") 

做這樣的信號發生器將產生大量的完整的句子供你審查。請注意,正確的語法仍然是遞歸的,因此是無限的;如果您生成足夠多的句子,您最終將達到相同的遞歸深度限制。

+0

感謝您的澄清。爲什麼不發生NP ... N ...獲取編號,似乎也解決了這個問題 –

+0

你是什麼意思,「編號」?任何立即避免無限遞歸的規則將「解決」這個問題,我展示瞭如何在不改變語法規則的情況下做到這一點。修正後的語法仍然會產生一個無限生成器;它只是首先返回有限長度的句子) – alexis

-1

我試圖對NP NN DT等重複出現的次數進行編號。似乎解決了由於唯一標識(我假設)所導致的問題。令我感到奇怪的是,本來應該是這樣的,即拋出的樹木應該已經連續化了詞類。

import nltk 
from nltk.parse.generate import generate,demo_grammar 
from nltk import CFG 
grammar = CFG.fromstring(""" 
ROOT -> S 
S -> NP VP 
NP -> NP1 PP 
NP1 -> DT1 NN1 
DT1 -> 'The' 
NN1 -> 'work' 
PP -> IN NP2 
IN -> 'of' 
NP2 -> DT2 NN2 
DT2 -> 'the' 
NN2 -> 'painter' 
VP -> VBZ ADJP 
VBZ -> 'is' 
ADJP -> JJ 
JJ -> 'good' 
""")  
print(grammar) 
for sentence in generate(grammar, n=100): 
    print(' '.join(sentence)) 
+0

在語言學上,你是過分指定規則,例如DT1和DT2似乎沒有好動機,爲什麼不是'DT - >' '|'the''。當不確定合規規則起作用,它很優雅。如果需要過分規定,通常是「黑客」; P – alvas

+0

這不是必要的,也不正確。你的改變將遞歸語法變成了一個有限的語法:例如,你不能再在NP中擁有兩個「PP」。花一些時間思考CFG表達什麼,並用紙和鉛筆玩耍。 – alexis

+0

@亞歷克西斯我尊重你的觀點。在進行換班解決方案之前,我需要深入研究CFG,在這種情況下,這對於遞歸原因是相反的。 –