2016-08-28 3 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, который он также расширяет с тем же правилом ... и так далее до бесконечности, или, вернее, до превышения лимитов питона.

Чтобы устранить проблему с грамматикой вы предоставляете, просто реорганизовать свои первые два 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''. Когда unspe работа по кодированию правил, это изящно. Когда необходима сверхоценка, обычно это «взлом», P – alvas

+0

Это не обязательно, и это неправильно. Ваше изменение превратило рекурсивную грамматику в конечную: у вас больше не может быть двух «PP's в NP», например. Потратьте некоторое время на размышления о том, что CFG выражает, и играть с ним бумагой и карандашом. – alexis

+0

@ Alexis Я уважаю вашу точку зрения. Мне нужно глубоко изучить CFG, прежде чем приступать к решениям смены сдвига, что в этом случае является встречным продуктом для рекурсивной причины. –

 Смежные вопросы

  • Нет связанных вопросов^_^