NLTK上下文无关语法生成

2024-06-16 13:38:55 发布

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

我正在研究一个使用Unicode字符的非英语解析器。为此,我决定使用NLTK。

但它需要一个预定义的上下文无关语法,如下所示:

  S -> NP VP
  VP -> V NP | V NP PP
  PP -> P NP
  V -> "saw" | "ate" | "walked"
  NP -> "John" | "Mary" | "Bob" | Det N | Det N PP
  Det -> "a" | "an" | "the" | "my"
  N -> "man" | "dog" | "cat" | "telescope" | "park"
  P -> "in" | "on" | "by" | "with" 

在我的应用程序中,我应该使用基于规则的语法来最小化硬编码。 例如,我可以假设任何以-ed-ing结尾的单词都是动词。所以它应该适用于任何给定的上下文。

我怎样才能把这样的语法规则输入NLTK?或者使用有限状态机动态生成它们?


Tags: 解析器规则npunicode语法字符johnpp
3条回答

您可以使用具有decise token正则表达式功能的NLTKRegexTagger。这正是你的案子所需要的。以“ing”结尾的标记将标记为动名词,以“ed”结尾的标记将标记为动词过去。请参阅下面的示例。

patterns = [
    (r'.*ing$', 'VBG'), # gerunds
    (r'.*ed$', 'VBD'), # simple past
    (r'.*es$', 'VBZ'), # 3rd singular present
    (r'.*ould$', 'MD'), # modals
    (r'.*\'s$', 'NN$'), # possessive nouns
    (r'.*s$', 'NNS') # plural nouns
 ]

注意,这些是按顺序处理的,并且应用第一个匹配的。现在 我们可以设置一个标记器并用它来标记一个句子。在这一步之后,关于 第五次。

regexp_tagger = nltk.RegexpTagger(patterns)
regexp_tagger.tag(your_sent)

您可以使用组合标记在一个序列中集体使用多个标记。

如果您正在创建一个解析器,那么您必须在实际的解析之前添加一个pos标记步骤——没有办法成功地在上下文之外确定单词的pos标记。例如,“closed”可以是形容词或动词;POS标记符将从单词的上下文中找出适合您的标记。然后可以使用POS标记器的输出创建CFG。

您可以使用现有的许多POS标记之一。在NLTK中,您可以简单地执行以下操作:

import nltk
input_sentence = "Dogs chase cats"
text = nltk.word_tokenize(input_sentence)
list_of_tokens = nltk.pos_tag(text)
print list_of_tokens

输出为:

[('Dogs', 'NN'), ('chase', 'VB'), ('cats', 'NN')]

它可用于创建语法字符串并将其馈送给nltk.parse_cfg()

也许你在找CFG.fromstring()(以前是parse_cfg())?

从NLTK手册的Chapter 7(更新为NLTK 3.0):

> grammar = nltk.CFG.fromstring("""
 S -> NP VP
 VP -> V NP | V NP PP
 V -> "saw" | "ate"
 NP -> "John" | "Mary" | "Bob" | Det N | Det N PP
 Det -> "a" | "an" | "the" | "my"
 N -> "dog" | "cat" | "cookie" | "park"
 PP -> P NP
 P -> "in" | "on" | "by" | "with"
 """)

> sent = "Mary saw Bob".split()
> rd_parser = nltk.RecursiveDescentParser(grammar)
> for p in rd_parser.parse(sent):
      print p
(S (NP Mary) (VP (V saw) (NP Bob)))

相关问题 更多 >