很遗憾,您的问题归结为“如何改进我的标记?”。答案是,您需要构建一个更好的标记器。所有重要的标记器都会考虑上下文,因此这不仅仅是增加上下文敏感性的问题;它已经存在,只是在某些情况下失败了。
NLTK 标记模型允许您“链接”标记器,以便每个标记器都可以从另一个停止的地方开始(例如,ngram 标记器回退到未知单词的正则表达式标记器)。它的工作原理是这样的:
t0 = nltk.DefaultTagger('N')
t1 = nltk.UnigramTagger(traindata, backoff=t0)
t2 = nltk.BigramTagger(traindata, backoff=t1)
traindata 这里是标准 NLTK 形式中已标记句子的列表:每个句子都是 (word, tag) 形式的元组列表。 (如果你有理由,你可以为每个标注器使用不同的训练语料库;你肯定想要使用一致的标签集)。例如,这是一个两句长的训练语料库:
traindata = [ [ ('His', 'PRO'), ('petition', 'N'), ('charged', 'VD'),
('mental', 'ADJ'), ('cruelty', 'N'), ('.', '.') ],
[ ('Two', 'NUM'), ('tax', 'N'), ('revision', 'N'), ('bills', 'N'),
('were', 'V'), ('passed', 'VN'), ('.', '.') ] ]
Tagger t2(您将使用的那个)将构建一个二元模型;如果它看到未知的输入,它将回退到t1,它使用一元模型;如果这也失败了,它将遵循t0(它只是标记所有内容'N')。
您可以添加一个特殊用途的重新标记器来改进默认标记,但当然您必须首先弄清楚它的作用——这当然是您最初提出的要求。
如果 nltk 标注器不断地犯相同类型的错误,您可以汇总一个更正语料库并在此基础上训练重新标注器。您需要多少数据取决于错误的一致性。我从未尝试过,但 Brill 标记器通过连续应用重新标记规则来工作,所以也许它是正确的工具。
另一种方法是尝试构建自己的特定领域标记语料库:使用 nltk 标记器标记训练集,手动或半自动更正它,然后在其上训练标记器并尝试在新数据上获得更好的性能比使用默认的 nltk 标记器(也许通过将两个标记器链接在一起)。