NLTK RegEx Chunker не захватывает определенные грамматические шаблоны с подстановочными знаками
Я пытаюсь разделить предложение, используя теги POS NLTK в качестве регулярных выражений. 2 правила определены для определения фраз, основываясь на тегах слов в предложении.
В основном, я хотел захватить кусок одного или нескольких глаголов, за которым следует необязательный определитель, а затем одно или несколько существительных в конце. Это первое правило в определении. Но это не захватывается как Фраза Чанк.
import nltk
## Defining the POS tagger
tagger = nltk.data.load(nltk.tag._POS_TAGGER)
## A Single sentence - input text value
textv="This has allowed the device to start, and I then see glitches which is not nice."
tagged_text = tagger.tag(textv.split())
## Defining Grammar rules for Phrases
actphgrammar = r"""
Ph: {<VB*>+<DT>?<NN*>+} # verbal phrase - one or more verbs followed by optional determiner, and one or more nouns at the end
{<RB*><VB*|JJ*|NN*\$>} # Adverbial phrase - Adverb followed by adjective / Noun or Verb
"""
### Parsing the defined grammar for phrases
actp = nltk.RegexpParser(actphgrammar)
actphrases = actp.parse(tagged_text)
Входные данные для чанкера tagged_text указаны ниже.
tagged_text Out [7]: [('This', 'DT'), ('has', 'VBZ'), ('позволено', 'VBN'), ('the', 'DT'), ('устройство ', 'NN'), ('to', 'TO'), ('start,', 'NNP'), ('and', 'CC'), ('I', 'PRP'), (' затем ', 'RB'), ('see', 'VB'), ('glitches', 'NNS'), ('which', 'WDT'), ('is', 'VBZ'), (' не ',' RB '), (' приятно.', 'NNP')]
В конечном выводе фиксируется только наречная фраза ("тогда посмотри"), которая соответствует второму правилу. Я ожидал, что словесная фраза ("позволил устройству") совпадет с первым правилом и будет зафиксирована, но это не так.
выход [8]: Дерево ('S', [('This', 'DT'), ('has', 'VBZ'), ('позволено', 'VBN'), ('the', 'DT '), (' устройство ',' NN '), (' to ',' TO '), (' start, ',' NNP '), (' and ',' CC '), (' I ',' PRP '), Tree (' Ph ', [(' then ',' RB '), (' 'see', 'VB')]), ('glitches', 'NNS'), ('which', 'WDT '), (' is ',' VBZ '), (' not ',' RB '), (' nice.', 'NNP')]))
Используемая версия NLTK - 2.0.5 (Python 2.7). Любая помощь или предложение будут с благодарностью.
Заранее спасибо,
Бал.
1 ответ
Близко, но небольшие изменения в вашем регулярном выражении получат желаемый результат. Когда вы хотите получить подстановочный знак, используя RegexpParser
грамматика, вы должны использовать .*
вместо *
например, VB.*
вместо VB*
:
>>> from nltk import word_tokenize, pos_tag, RegexpParser
>>> text = "This has allowed the device to start, and I then see glitches which is not nice."
>>> tagged_text = pos_tag(word_tokenize(text))
>>> g = r"""
... VP: {<VB.*><DT><NN.*>}
... """
>>> p = RegexpParser(g); p.parse(tagged_text)
Tree('S', [('This', 'DT'), ('has', 'VBZ'), Tree('VP', [('allowed', 'VBN'), ('the', 'DT'), ('device', 'NN')]), ('to', 'TO'), ('start', 'VB'), (',', ','), ('and', 'CC'), ('I', 'PRP'), ('then', 'RB'), ('see', 'VBP'), ('glitches', 'NNS'), ('which', 'WDT'), ('is', 'VBZ'), ('not', 'RB'), ('nice', 'JJ'), ('.', '.')])
Обратите внимание, что вы ловите Tree(AdvP, [('then', 'RB'), ('see', 'VB')])
потому что теги точно RB
а также VB
, Таким образом, подстановочный знак в вашей грамматике (т. Е. `"""AdvP: {}""") в этом сценарии игнорируется.
Кроме того, если это два разных типа фраз, более целесообразно использовать 2 метки, а не одну. И (я думаю) конец строки после подстановочного знака является излишним, поэтому лучше:
g = r"""
VP:{<VB.*><DT><NN.*>}
AdvP: {<RB.*><VB.*|JJ.*|NN.*>}
"""