我正在使用来自 nltk 的 pos_tag 来标记一组(未标记的)技术文档中的文本并获得良好的结果,但它总是将诸如“已验证”之类的词标记为动词,有时它可以用作形容词。换句话说,简单地更改标签不会每次都起作用。
有没有一种好方法可以覆盖或更正考虑上下文的标记结果?
不幸的是,您的问题归结为“如何改进我的标记?”。答案是,您需要构建一个更好的标记器。所有重要的标记器都会考虑上下文,因此这不仅仅是增加上下文敏感性的问题;它已经存在,只是在某些情况下失败了。
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'), ('.', '.') ] ]
标记器t2
(您将使用的那个)将构建一个二元模型;如果它看到未知的输入,它将回退到t1
,它使用一元模型;如果这也失败了,它将遵循t0
(它只是标记所有内容'N')。
您可以添加一个特殊用途的重新标记器来改进默认标记,但当然您必须首先弄清楚它要做什么——这当然是您首先要求的。
如果 nltk 标注器不断地犯同样类型的错误,你可以整理一个更正的语料库,并在此基础上训练一个重新标注器。您需要多少数据取决于错误的一致性。我从未尝试过,但 Brill 标记器通过连续应用重新标记规则来工作,所以它也许是正确的工具。
另一种方法是尝试构建自己的特定领域标记语料库:使用 nltk 标记器标记训练集,手动或半自动更正它,然后在其上训练标记器并尝试在新数据上获得比使用默认 nltk 标记器(可能通过将两个标记器链接在一起)。