如何使用nltk正则表达式模式提取特定的短语块?

2024-05-03 12:13:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我编写了以下正则表达式来标记某些短语模式

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'

并用两个短语给出所需的输出:

  1. 披萨很好吃
  2. 意大利面不好吃

但是,如果我的句子是这样的:

a = 'The pizza was awesome and brilliant'

只匹配短语:

'pizza was awesome' 

而不是想要的:

'pizza was awesome and brilliant'

如何为第二个示例合并regex模式?


Tags: andthein标记模式nnawesomevb
1条回答
网友
1楼 · 发布于 2024-05-03 12:13:35

首先,让我们看看NLTK提供的POS标签:

>>> 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,旧版本可能有所不同)

你想要捕捉的本质是:

  • 网络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')])])

这就是硬编码的“作弊”!!!

让我们回到POS模式:

  • 网络VBD JJ CC JJ
  • NN VBD JJ公司

可以简化为:

  • NN VBD JJ(抄送JJ)

因此,您可以在regex中使用可选运算符,例如:

>>> 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')])])

很可能你用的是旧的tagger,这就是为什么你的模式不同,但我想你看到了如何使用上面的例子捕捉你需要的短语。

步骤如下:

  • 首先,使用pos_tag检查POS模式是什么
  • 然后推广模式并简化它们
  • 然后把它们放入RegexpParser

相关问题 更多 >