自定义词性标记,回退到 nltk 内部 pos



在我的业务领域,这两个词的组合:">门卫建筑"应始终标记为(门卫:"JJ"((建筑:"NN">(。 NLTK内部标记器将其标记为:

nltk.pos_tag(["doorman", "building"]) -> [('doorman', 'NN'), ('building', 'NN')]

我的方法是创建一个BigramTagger,并用这个句子来训练它:

train_sents = [
[('doorman', 'JJ'), ('building', 'NN')]
]

并在所有其他情况下使用 NLTK 内部标记器将其退缩。

default_tagger = nltk.data.load("../nltk_data/taggers/maxent_treebank_pos_tagger/english.pickle")
bigram_tagger = nltk.BigramTagger(train_sents, backoff=default_tagger)

但是,当我尝试像这样使用它时:

bigram_tagger.tag(nltk.word_tokenize("Elegant doorman building with gym"))`

似乎没有应用BigramTaager,我得到:

[('Elegant', 'NNP'), ('doorman', 'NN'), ('building', 'NN'), ('with', 'IN'), ('gym', 'NN')]

但这似乎确实有效:

bigram_tagger.tag(nltk.word_tokenize("doorman building")) -> [('doorman', 'JJ'), ('building', 'NN')]

显然,我在使用这些组件的方式上缺少一些东西, 拥有 NLTK 内部 POS 标记器,同时在与特定业务域相关的某些特定情况下"覆盖"它,这是一个很好的策略吗?

首先,nltk 标记器在语法上是正确的:"门卫建筑"是一个名词-名词复合体。但为了回答技术问题,BigramTagger根据先前的上下文一次标记一个单词。您的自定义标记器在"优雅"之后无法标记"门卫",因此它会委托给默认值,并且在您进入"构建"之前

最终会得到("doorman", "JJ")

。如果你确定要走这条路(我猜它可能弊大于利(,我建议在标记器完成工作后通过后处理来应用你的更正。像你给出的例子不需要完整的标记器,你可以只匹配单词的顺序,并对标记的版本应用替换。

最新更新