使用 NLTK 进行复杂分块

数据挖掘 Python nlp nltk
2021-10-09 12:53:53

我正在尝试按照 NLTK book 的第 7 章来弄清楚如何使用 NLTK 的级联分块器不幸的是,我在执行重要的分块措施时遇到了一些问题。

让我们从这句话开始:

"adventure movies between 2000 and 2015 featuring performances by daniel craig"

当我使用以下语法时,我能够找到所有相关的 NP:

grammar = "NP: {<DT>?<JJ>*<NN.*>+}"

但是,我不确定如何使用 NLTK 构建嵌套结构。这本书给出了以下格式,但显然缺少一些东西(例如,一个人实际上如何指定多个规则?):

grammar = r"""
  NP: {<DT|JJ|NN.*>+}          # Chunk sequences of DT, JJ, NN
  PP: {<IN><NP>}               # Chunk prepositions followed by NP
  VP: {<VB.*><NP|PP|CLAUSE>+$} # Chunk verbs and their arguments
  CLAUSE: {<NP><VP>}           # Chunk NP, VP
  """

就我而言,我想做以下事情:

grammar = "MEDIA: {<DT>?<JJ>*<NN.*>+}
           RELATION: {<V.*>}{<DT>?<JJ>*<NN.*>+}
           ENTITY: {<NN.*>}"

我突然想到,CFG 可能更适合这个,但我大约 5 分钟前才意识到 NLTK 对这个功能的支持(来自这个问题),而且似乎没有太多关于该功能的文档存在。

所以,假设我想为我的任务使用级联块,我需要使用什么语法?此外,我是否可以在使用分块器时指定特定的词(例如“导演”或“表演”)?

1个回答

你的语法是正确的!

grammar = """MEDIA: {<DT>?<JJ>*<NN.*>+}
           RELATION: {<V.*>}
                     {<DT>?<JJ>*<NN.*>+}
           ENTITY: {<NN.*>}"""

通过指定

RELATION: {<V.*>}
          {<DT>?<JJ>*<NN.*>+}

您表示有两种方法可以生成RELATION块,{<V.*>}{<DT>?<JJ>*<NN.*>+}

所以

grammar = """MEDIA: {<DT>?<JJ>*<NN.*>+}
               RELATION: {<V.*>}
                         {<DT>?<JJ>*<NN.*>+}
               ENTITY: {<NN.*>}"""
    chunkParser = nltk.RegexpParser(grammar)
    tagged = nltk.pos_tag(nltk.word_tokenize("adventure movies between 2000 and 2015 featuring performances by daniel craig"))

    tree = chunkParser.parse(tagged)

    for subtree in tree.subtrees():
        if subtree.label() == "RELATION": 
            print("RELATION: "+str(subtree.leaves()))

RELATION: [('featuring', 'VBG')]