【问题标题】:Python and NLTK: Baseline taggerPython 和 NLTK:基线标注器
【发布时间】:2014-01-08 10:35:31
【问题描述】:

我正在为基线标记器编写代码。基于布朗语料库,它为单词分配最常见的标签。因此,如果单词“works”被标记为动词 23 次,并且被标记为复数名词 30 次,那么基于用户输入句子中的内容,它将被标记为复数名词。如果在语料库中找不到该词,则默认将其标记为名词。 到目前为止,我的代码会返回单词的每个标签,而不仅仅是最常见的标签。我怎样才能实现它只返回每个单词的频繁标签?

import nltk 
from nltk.corpus import brown

def findtags(userinput, tagged_text):
    uinput = userinput.split()
    fdist = nltk.FreqDist(tagged_text)
    result = []
    for item in fdist.items():
        for u in uinput:
            if u==item[0][0]:
                t = (u,item[0][1])
                result.append(t)
        continue
        t = (u, "NN")
        result.append(t)
    return result

def main():
    tags = findtags("the quick brown fox", brown.tagged_words())
    print tags

if __name__ == '__main__':
    main()

【问题讨论】:

  • 哇哈哈,如果我回答了你所有的 nltk 问题,我很快就会开始要求付款。哈哈,开个玩笑,给我一分钟打字。
  • 抱歉去吃午饭了,下面是你需要的most_frequent_pos_tagger()

标签: python nlp nltk tagging


【解决方案1】:

如果是英文,NLTK 中有一个默认的词性标注器,很多人一直在抱怨,但这是一个很好的快速修复(更像是创可贴而不是扑热息痛),请参阅 POS tagging - NLTK thinks noun is adjective

>>> from nltk.tag import pos_tag
>>> from nltk.tokenize import word_tokenize
>>> sent = "the quick brown fox"
>>> pos_tag(word_tokenize(sent))
[('the', 'DT'), ('quick', 'NN'), ('brown', 'NN'), ('fox', 'NN')]

如果您想从头开始训练基线标注器,我建议您按照这样的示例,但将语料库更改为英文:https://github.com/alvations/spaghetti-tagger

通过像spaghetti-tagger 那样构建 UnigramTagger,您应该自动获得每个单词最常见的标签。

但是,如果你想用非机器学习的方式来做,首先要计算单词:POS,你需要的是某种类型的令牌比率。另见Part-of-speech tag without context using nltk:

from nltk.tag import pos_tag
from nltk.tokenize import word_tokenize
from collections import Counter, defaultdict
from itertools import chain

def type_token_ratio(documentstream):
    ttr = defaultdict(list)
    for token, pos in list(chain(*documentstream)):
        ttr[token].append(pos)  
    return ttr

def most_freq_tag(ttr, word):
    return Counter(ttr[word]).most_common()[0][0]

sent1 = "the quick brown fox quick me with a quick ."
sent2 = "the brown quick fox fox me with a brown ." 
documents = [sent1, sent2]

# Calculates the TTR.
documents_ttr = type_token_ratio([pos_tag(word_tokenize(i)) for i in documents])

# Best tag for the word.
print Counter(documents_ttr['quick']).most_common()[0]

# Best tags for a sentence
print [most_freq_tag(documents_ttr, i) for i in sent1.split()]

注意:文档流可以定义为句子列表,其中每个句子包含带有/out 标签的标记列表。

【讨论】:

    【解决方案2】:

    创建一个名为 word_tags 的字典,其键是单词(未注释),值是按频率降序排列的标签列表(基于您的 fdist。)

    然后:

    for u in uinput:
        result.append(word_tags[u][0])
    

    【讨论】:

      【解决方案3】:

      您可以简单地使用 Counter 来查找列表中重复次数最多的项目:

      Python

      from collections import Counter
      default_tag = Counter(tags).most_common(1)[0][0]
      

      如果您的问题是“一元标记器如何工作?”您可能有兴趣阅读更多 NLTK 源代码: http://nltk.org/_modules/nltk/tag/sequential.html#UnigramTagger

      无论如何,我建议你阅读 NLTK 书籍第 5 章 特别: http://nltk.org/book/ch05.html#the-lookup-tagger

      就像书中的示例一样,您可以有一个条件频率分布,它返回每个给定单词的最佳标签。

      cfd = nltk.ConditionalFreqDist(nltk.corpus.brown.tagged_words())
      

      在这种情况下,cfd["fox"].max() 将根据棕色语料库返回“狐狸”最可能的标签。然后,您可以为句子中的每个单词制作一个最有可能标签的字典:

      likely_tags = dict((word, cfd[word].max()) for word in "the quick brown fox".split())
      

      请注意,对于句子中的新词,这将返回错误。但如果你理解这个想法,你可以制作自己的标记器。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-13
        • 2012-01-01
        • 2021-10-14
        • 2015-02-20
        • 1970-01-01
        • 2016-11-29
        相关资源
        最近更新 更多