【问题标题】:Combine two regexp grammars in nltk在 nltk 中结合两个正则表达式语法
【发布时间】:2022-01-27 15:10:16
【问题描述】:

我正在使用nltk 中的语法定义名词短语。 nltk提供的例子是:

grammar = "NP: {<DT>?<NNP>*<NN>}"

那么如果我有一个类似的句子:show me the Paris hospitals,库可以检测到名词短语:

>>> s
'show me the Paris hospitals'
>>> grammar = "NP: {<DT>?<NNP>*<NNS>}"
>>> nltk.RegexpParser(grammar).parse(nltk.pos_tag(nltk.word_tokenize(s)))
Tree('S', [('show', 'VB'), ('me', 'PRP'), Tree('NP', [('the', 'DT'), ('Paris', 'NNP'), ('hospitals', 'NNS')])])

现在,句子可以写成另一种方式:show me the hospitals of Paris,因此我需要将语法更改为:

>>> grammar = "NP: {<DT>?<NNS><IN><NNP>}"
>>> s = "show me the hospitals in Paris"
>>> nltk.RegexpParser(grammar).parse(nltk.pos_tag(nltk.word_tokenize(s)))
Tree('S', [('show', 'VB'), ('me', 'PRP'), Tree('NP', [('the', 'DT'), ('hospitals', 'NNS'), ('in', 'IN'), ('Paris', 'NNP')])])

如何将这两种语法组合成一个独特的语法?我无法弄清楚这两个语法的 OR 条件。

【问题讨论】:

    标签: python nlp nltk grammar


    【解决方案1】:

    你可以在一个语法中定义两个 NP 规则:

    grammar = """
    NP: {<DT>?<NNP>*<NNS>}
    NP: {<DT>?<NNS><IN><NNP>}
    """
    

    或使用| 作为想要的OR 条件:

    grammar = "NP: {<DT>?<NNP>*<NNS>|<DT>?<NNS><IN><NNP>}"
    

    完整示例:

    import nltk
    
    sentence_1 = 'show me the Paris hospitals'
    sentence_2 = "show me the hospitals in Paris"
    
    grammar_1 = """
    NP: {<DT>?<NNP>*<NNS>}
    NP: {<DT>?<NNS><IN><NNP>}
    """
    parser_1 = nltk.RegexpParser(grammar_1)
    
    grammar_2 = "NP: {<DT>?<NNP>*<NNS>|<DT>?<NNS><IN><NNP>}"
    parser_2 = nltk.RegexpParser(grammar_2)
    
    for s in sentence_1, sentence_2:
        tokens = nltk.word_tokenize(s)
        pos_tags = nltk.pos_tag(tokens)
        print(parser_1.parse(pos_tags))
        print(parser_2.parse(pos_tags))
    
    # outputs the same for both parsers:
    # (S show/VB me/PRP (NP the/DT Paris/NNP hospitals/NNS))
    # (S show/VB me/PRP (NP the/DT Paris/NNP hospitals/NNS))
    # (S show/VB me/PRP (NP the/DT hospitals/NNS) in/IN Paris/NNP)
    # (S show/VB me/PRP (NP the/DT hospitals/NNS) in/IN Paris/NNP)
    

    (link to the documentation)

    【讨论】:

    • 感谢您的回答。当我将组合语法的结果与NP: {&lt;DT&gt;?&lt;NNS&gt;&lt;IN&gt;&lt;NNP&gt;} 进行比较时,我发现了不同之处。具体来说,上述语法(组合语法的一部分)产生:(S show/VB me/PRP (NP the/DT hospitals/NNS in/IN Paris/NNP))。这里树NP包含Paris,而组合语法的NP不包含Paris。有办法克服吗?
    • "子句的模式是按顺序执行的。" (ff.,见linked documentation)。您可以切换规则的顺序以获得相同的结果。 FWIW:解析器还有trace flag。也许这也能有所帮助。例如。 parser.parse(pos_tags, trace=2).
    • 切换订单对我有用。我接受了答案。
    猜你喜欢
    • 2015-01-14
    • 1970-01-01
    • 1970-01-01
    • 2012-03-14
    • 2016-10-23
    • 1970-01-01
    相关资源
    最近更新 更多