NLTK RegEx Chunker 不使用通配符捕获定义的语法模式
NLTK RegEx Chunker not capturing defined grammar patterns with wildcards
我正在尝试使用 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'),
('allowed', 'VBN'),
('the', 'DT'),
('device', 'NN'),
('to', 'TO'),
('start,', 'NNP'),
('and', 'CC'),
('I', 'PRP'),
('then', 'RB'),
('see', 'VB'),
('glitches', 'NNS'),
('which', 'WDT'),
('is', 'VBZ'),
('not', 'RB'),
('nice.', 'NNP')]
在最终输出中,只有匹配第二条规则的状语短语('then see')被捕获。
我希望口头短语('允许设备')与第一条规则匹配并被捕获,但事实并非如此。
actphrases Out[8]: Tree('S', [('This', 'DT'), ('has', 'VBZ'),
('allowed', 'VBN'), ('the', 'DT'), ('device', '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)
任何帮助或建议将不胜感激。
提前致谢,
巴拉.
关闭但对您的正则表达式进行微小的更改将使您获得所需的输出。当你想使用 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.*>}
"""
我正在尝试使用 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'), ('allowed', 'VBN'), ('the', 'DT'), ('device', 'NN'), ('to', 'TO'), ('start,', 'NNP'), ('and', 'CC'), ('I', 'PRP'), ('then', 'RB'), ('see', 'VB'), ('glitches', 'NNS'), ('which', 'WDT'), ('is', 'VBZ'), ('not', 'RB'), ('nice.', 'NNP')]
在最终输出中,只有匹配第二条规则的状语短语('then see')被捕获。 我希望口头短语('允许设备')与第一条规则匹配并被捕获,但事实并非如此。
actphrases Out[8]: Tree('S', [('This', 'DT'), ('has', 'VBZ'), ('allowed', 'VBN'), ('the', 'DT'), ('device', '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) 任何帮助或建议将不胜感激。
提前致谢,
巴拉.
关闭但对您的正则表达式进行微小的更改将使您获得所需的输出。当你想使用 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.*>}
"""