繁体   English   中英

使用python NLTK:如何提高POS标记器的准确性?

[英]Working with the python NLTK: How can I improve the accuracy of the POS tagger?

我一直在使用NLTK的POS标记器:

...
nltk.pos_tag(nltk.word_tokenize(tfile[i]))
...

但是有时我得到的结果不准确(当我应该获得JJ时为NN,依此类推。我要标记的文本在相当特定的业务领域内……我不太愿意在这里说出哪个领域)。 诚然,我不是Python或NLTK的专家(但是正在研究),但我想知道是否有某种方法可以提高标记器的准确性。

我想我了解标记器通过将提供给它的文本与带有预标记文本的语料库进行比较来工作。 我的自然倾向是尝试向该语料库添加一组我自己的自标记句子...但是我不知道该怎么做。

我非常感谢您提供关于如何将自己的文本添加到语料库的建议(或者我希望添加到现有的而不是完全开始一个新的建议),或者如果有人有其他建议来提高标记器的准确性,我将不胜感激为了我的目的,我很想听听。

谢谢!

您可能已经在nltk上看过GoogleCode书 我一直非常缓慢地自行处理它,虽然还没有解决POS标记问题,但是当我足够熟练地使用该工具时,这是我最终想要做的事情之一。 无论如何,在第5章第2节中,您会获得以下文本和示例,以了解如何制作自己的标记令牌集(对所有人表示歉意,但我直接从文本中进行了复制):

>>> tagged_token = nltk.tag.str2tuple('fly/NN')
>>> tagged_token
('fly', 'NN')
>>> tagged_token[0]
'fly'
>>> tagged_token[1]
'NN'

从5.2继续:

我们可以直接从字符串构造标记标记的列表。 第一步是标记字符串以访问各个单词/标记字符串,然后将每个字符串转换为元组(使用str2tuple())。

>>> sent = '''
... The/AT grand/JJ jury/NN commented/VBD on/IN a/AT number/NN of/IN
... other/AP topics/NNS ,/, AMONG/IN them/PPO the/AT Atlanta/NP and/CC
... Fulton/NP-tl County/NN-tl purchasing/VBG departments/NNS which/WDT it/PPS
... said/VBD ``/`` ARE/BER well/QL operated/VBN and/CC follow/VB generally/RB
... accepted/VBN practices/NNS which/WDT inure/VB to/IN the/AT best/JJT
... interest/NN of/IN both/ABX governments/NNS ''/'' ./.
... '''
>>> [nltk.tag.str2tuple(t) for t in sent.split()]
[('The', 'AT'), ('grand', 'JJ'), ('jury', 'NN'), ('commented', 'VBD'), ('on', 'IN'), ('a', 'AT'), ('number', 'NN'), ... ('.', '.')]

上方的“已发送”变量实际上就是原始标记文本的样子,已确认到我自己计算机上的nltk_data目录,并查看corpora / brown /中的任何内容,因此您可以使用以下格式来编写自己的标记文本:然后使用它构建您自己的标记令牌集。

一旦设置了自己的标记令牌,您就应该能够基于标记的令牌(从5.5开始)设置自己的unigram标记器:

>>>unigram_tagger = nltk.UnigramTagger(YOUR_OWN_TAGGED_TOKENS)

最后,由于您标记的文本可能只是一个很小的样本(因此不准确),因此您可以列出一个后备标记器,以便当失败时,可以使用后备标记:

>>> t0 = nltk.UnigramTagger(a_bigger_set_of_tagged_tokens)
>>> t1 = nltk.UnigramTagger(your_own_tagged_tokens, backoff=t0)

最后,您应该研究前面第5章中介绍的n-gram差异,bigram,unigram等。

无论如何,如果您继续阅读第5章,将会看到几种标记文本的方式(包括我最喜欢的regex标记器!)。 有很多方法可以做到,而且太复杂了,无法在这样的小文章中充分介绍。

注意:我还没有尝试所有这些代码,因此我以自己目前正在尝试的解决方案作为解决方案。 如果我犯了错误,请帮助我纠正它们。

“如何改进NLTK标记器”是一个受欢迎的问题:-)我绝对不建议您手工制作语料库来训练标记器。 标线需要大量数据才能在新文本上正常工作。

如果您想尽力而为, 可以做的事情就是“引导”语料库:使用NLTK标记器在您的域中标记一堆文本,手动更正子集中的错误(如果可以预见,则更容易),使用结果来训练更好的标记器。 您甚至可以重复此过程,以便可以手动清洁大量自己的材料。 您的新标记仍将基于少量文本,因此您可以将默认标记添加为回退,如@erewok所示。 另请参阅此问题 ,它询问相同的问题。

正如@erewok指出的那样,使用退避标记器是一种改进的好方法。 从最准确的开始。 如果无法标记,或者计算出的概率低于设置的阈值,请尝试下一种(精度较低)的方法。 甚至最后的“假设它是一个名词”步骤也可以做出可衡量的改进。

诸如unigram和bigram标记器之类的东西通常不那么准确。 我建议先从一个朴素的贝叶斯(Naive Bayes)标记器开始(O'Reilly的书中介绍了这些标记器)。 这可以使用Unigram标记器或Wordnet标记器(在Wordnet中查找单词,并使用最常见的示例)作为后备标记器。

然后,您可以转到MaxEnt(最大熵)标记器,该标记器由于其对相关功能的支持而被认为比Naive Bayes更为准确。 但是,它速度较慢,需要更多的精力来实施-最终结果可能不值得。 NLTK版本也可能很难使用。

为了训练这些标记器,NLTK附带了各种语料库。 我对您的域名一无所知,我不知道它们的用处,但它们包括Penn Treebank的子集,某些特定领域的语料库,各种语言等。 看一看。

除了O'Reilly的书,我还会推荐Jacob Perkins的Python Text Processing NLTK Cookbook ,其中包括此类事情的实际示例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM