如何使用 nltk 正则表达式模式来提取特定的短语块?
How to use nltk regex pattern to extract a specific phrase chunk?
我编写了以下正则表达式来标记某些短语模式
pattern = """
P2: {<JJ>+ <RB>? <JJ>* <NN>+ <VB>* <JJ>*}
P1: {<JJ>? <NN>+ <CC>? <NN>* <VB>? <RB>* <JJ>+}
P3: {<NP1><IN><NP2>}
P4: {<NP2><IN><NP1>}
"""
此模式可以正确标记短语,例如:
a = 'The pizza was good but pasta was bad'
并用 2 个短语给出所需的输出:
- 披萨不错
- 意大利面很糟糕
但是,如果我的句子是这样的:
a = 'The pizza was awesome and brilliant'
仅匹配短语:
'pizza was awesome'
而不是所需的:
'pizza was awesome and brilliant'
如何为我的第二个示例合并正则表达式模式?
首先我们来看一下NLTK给出的词性标签:
>>> from nltk import pos_tag
>>> sent = 'The pizza was awesome and brilliant'.split()
>>> pos_tag(sent)
[('The', 'DT'), ('pizza', 'NN'), ('was', 'VBD'), ('awesome', 'JJ'), ('and', 'CC'), ('brilliant', 'JJ')]
>>> sent = 'The pizza was good but pasta was bad'.split()
>>> pos_tag(sent)
[('The', 'DT'), ('pizza', 'NN'), ('was', 'VBD'), ('good', 'JJ'), ('but', 'CC'), ('pasta', 'NN'), ('was', 'VBD'), ('bad', 'JJ')]
(注意:以上是 NLTK v3.1 pos_tag
的输出,旧版本可能有所不同)
你要捕捉的本质是:
- NN VBD JJ CC JJ
- NN VBD JJ
所以让我们用这些模式来捕捉它们:
>>> from nltk import RegexpParser
>>> sent1 = ['The', 'pizza', 'was', 'awesome', 'and', 'brilliant']
>>> sent2 = ['The', 'pizza', 'was', 'good', 'but', 'pasta', 'was', 'bad']
>>> patterns = """
... P: {<NN><VBD><JJ><CC><JJ>}
... {<NN><VBD><JJ>}
... """
>>> PChunker = RegexpParser(patterns)
>>> PChunker.parse(pos_tag(sent1))
Tree('S', [('The', 'DT'), Tree('P', [('pizza', 'NN'), ('was', 'VBD'), ('awesome', 'JJ'), ('and', 'CC'), ('brilliant', 'JJ')])])
>>> PChunker.parse(pos_tag(sent2))
Tree('S', [('The', 'DT'), Tree('P', [('pizza', 'NN'), ('was', 'VBD'), ('good', 'JJ')]), ('but', 'CC'), Tree('P', [('pasta', 'NN'), ('was', 'VBD'), ('bad', 'JJ')])])
所以这是 "cheating" 硬编码!!!
让我们回到 POS 模式:
- NN VBD JJ CC JJ
- NN VBD JJ
可以简化为:
- NN VBD JJ (CC JJ)
因此您可以在正则表达式中使用可选运算符,例如:
>>> patterns = """
... P: {<NN><VBD><JJ>(<CC><JJ>)?}
... """
>>> PChunker = RegexpParser(patterns)
>>> PChunker.parse(pos_tag(sent1))
Tree('S', [('The', 'DT'), Tree('P', [('pizza', 'NN'), ('was', 'VBD'), ('awesome', 'JJ'), ('and', 'CC'), ('brilliant', 'JJ')])])
>>> PChunker.parse(pos_tag(sent2))
Tree('S', [('The', 'DT'), Tree('P', [('pizza', 'NN'), ('was', 'VBD'), ('good', 'JJ')]), ('but', 'CC'), Tree('P', [('pasta', 'NN'), ('was', 'VBD'), ('bad', 'JJ')])])
很可能您使用的是旧标注器,这就是您的模式不同的原因,但我想您已经了解如何使用上面的示例捕获所需的短语。
步骤是:
- 首先,使用
pos_tag
检查 POS 模式是什么
- 然后概括模式并简化它们
- 然后将它们放入
RegexpParser
我编写了以下正则表达式来标记某些短语模式
pattern = """
P2: {<JJ>+ <RB>? <JJ>* <NN>+ <VB>* <JJ>*}
P1: {<JJ>? <NN>+ <CC>? <NN>* <VB>? <RB>* <JJ>+}
P3: {<NP1><IN><NP2>}
P4: {<NP2><IN><NP1>}
"""
此模式可以正确标记短语,例如:
a = 'The pizza was good but pasta was bad'
并用 2 个短语给出所需的输出:
- 披萨不错
- 意大利面很糟糕
但是,如果我的句子是这样的:
a = 'The pizza was awesome and brilliant'
仅匹配短语:
'pizza was awesome'
而不是所需的:
'pizza was awesome and brilliant'
如何为我的第二个示例合并正则表达式模式?
首先我们来看一下NLTK给出的词性标签:
>>> from nltk import pos_tag
>>> sent = 'The pizza was awesome and brilliant'.split()
>>> pos_tag(sent)
[('The', 'DT'), ('pizza', 'NN'), ('was', 'VBD'), ('awesome', 'JJ'), ('and', 'CC'), ('brilliant', 'JJ')]
>>> sent = 'The pizza was good but pasta was bad'.split()
>>> pos_tag(sent)
[('The', 'DT'), ('pizza', 'NN'), ('was', 'VBD'), ('good', 'JJ'), ('but', 'CC'), ('pasta', 'NN'), ('was', 'VBD'), ('bad', 'JJ')]
(注意:以上是 NLTK v3.1 pos_tag
的输出,旧版本可能有所不同)
你要捕捉的本质是:
- NN VBD JJ CC JJ
- NN VBD JJ
所以让我们用这些模式来捕捉它们:
>>> from nltk import RegexpParser
>>> sent1 = ['The', 'pizza', 'was', 'awesome', 'and', 'brilliant']
>>> sent2 = ['The', 'pizza', 'was', 'good', 'but', 'pasta', 'was', 'bad']
>>> patterns = """
... P: {<NN><VBD><JJ><CC><JJ>}
... {<NN><VBD><JJ>}
... """
>>> PChunker = RegexpParser(patterns)
>>> PChunker.parse(pos_tag(sent1))
Tree('S', [('The', 'DT'), Tree('P', [('pizza', 'NN'), ('was', 'VBD'), ('awesome', 'JJ'), ('and', 'CC'), ('brilliant', 'JJ')])])
>>> PChunker.parse(pos_tag(sent2))
Tree('S', [('The', 'DT'), Tree('P', [('pizza', 'NN'), ('was', 'VBD'), ('good', 'JJ')]), ('but', 'CC'), Tree('P', [('pasta', 'NN'), ('was', 'VBD'), ('bad', 'JJ')])])
所以这是 "cheating" 硬编码!!!
让我们回到 POS 模式:
- NN VBD JJ CC JJ
- NN VBD JJ
可以简化为:
- NN VBD JJ (CC JJ)
因此您可以在正则表达式中使用可选运算符,例如:
>>> patterns = """
... P: {<NN><VBD><JJ>(<CC><JJ>)?}
... """
>>> PChunker = RegexpParser(patterns)
>>> PChunker.parse(pos_tag(sent1))
Tree('S', [('The', 'DT'), Tree('P', [('pizza', 'NN'), ('was', 'VBD'), ('awesome', 'JJ'), ('and', 'CC'), ('brilliant', 'JJ')])])
>>> PChunker.parse(pos_tag(sent2))
Tree('S', [('The', 'DT'), Tree('P', [('pizza', 'NN'), ('was', 'VBD'), ('good', 'JJ')]), ('but', 'CC'), Tree('P', [('pasta', 'NN'), ('was', 'VBD'), ('bad', 'JJ')])])
很可能您使用的是旧标注器,这就是您的模式不同的原因,但我想您已经了解如何使用上面的示例捕获所需的短语。
步骤是:
- 首先,使用
pos_tag
检查 POS 模式是什么
- 然后概括模式并简化它们
- 然后将它们放入
RegexpParser