【问题标题】:How to override the POS tags assigned to a text by nltk's pos_tag?如何覆盖 nltk 的 pos_tag 分配给文本的 POS 标签?
【发布时间】:2012-10-19 22:54:29
【问题描述】:

我正在使用来自 nltk 的 pos_tag 来标记一组(未标记的)技术文档中的文本并获得良好的结果,但它总是将诸如“已验证”之类的词标记为动词,有时它可以用作形容词。换句话说,不是每次都简单地更改标签。

有没有一种好方法可以覆盖或更正考虑上下文的​​标记结果?

【问题讨论】:

  • 你有可以用来训练你自己的 PoS 标注器的标记语料库吗?
  • 不,我没有。如果我有一个(手动)标记的语料库,我会用它来训练标记器。
  • 约束语法可以帮助您根据上下文从多个标签中选择正确的一个。我对nltk 不够熟悉,无法判断这是否直接有用。 jaytaylor.com/blog/2010/04/03/… 似乎有一些相关的东西。
  • Jacob,我在发帖之前就看到了。您的回答清楚地说明了如何覆盖被视为单个标记的单词上的标签,而不是如何处理标签随上下文变化的单词。

标签: python nltk


【解决方案1】:

很遗憾,您的问题归结为“如何改进我的标记?”。答案是,您需要构建一个更好的标记器。所有重要的标记器都会考虑上下文,因此这不仅仅是增加上下文敏感性的问题;它已经存在,只是在某些情况下失败了。

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 标记器(也许通过将两个标记器链接在一起)。

【讨论】:

  • Alexis,你能添加一些代码让我接受这个作为答案吗?
  • 你想要什么样的代码?我添加了一个如何将标记器链接在一起的示例。恐怕你没有提供足够的细节让我适应你的问题。
  • 我认为您的原始描述不足以让其他人看到他们应该做什么。代码示例很好..我可以编辑答案以显示如何在 unigram 案例中重新训练?
猜你喜欢
  • 1970-01-01
  • 2012-11-26
  • 1970-01-01
  • 2018-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-18
相关资源
最近更新 更多