【语言处理与Python】5.4自动标注

在这里有不同的方式来给文本自动添加词性标记。

一个词的标记,要依赖于这个词和它在句子中的上下文。

所以:我们将处理句子层次而不是词汇层次的数据。

下面的所有代码示例中都以这些代码为基础:

>>>from nltk.corpusimport brown
>>>brown_tagged_sents= brown.tagged_sents(categories='news')
>>>brown_sents= brown.sents(categories='news')

默认标注器

#把最有可能的标记进行标注

tags=[tag for (word,tag) in brown.tagged_words(categories=’news’)]

nltk.FreqDist(tags).max()

‘NN’

#现在使用将所有词都标注成NN的标注器
>>>raw = 'I donot like greeneggs and ham,I donot like them SamI am!'
>>>tokens = nltk.word_tokenize(raw)
>>>default_tagger =nltk.DefaultTagger('NN')
>>>default_tagger.tag(tokens)
[('I', 'NN'), ('do', 'NN'), ('not', 'NN'), ('like', 'NN'), ('green', 'NN'),
('eggs', 'NN'), ('and', 'NN'), ('ham', 'NN'), (',', 'NN'), ('I', 'NN'),
('do', 'NN'), ('not', 'NN'), ('like', 'NN'), ('them', 'NN'), ('Sam', 'NN'),
('I', 'NN'), ('am', 'NN'), ('!', 'NN')]

其实,大家也有感觉,这种方式并不会很好,可以通过下面这个函数,测评一下标注的结果。

>>>default_tagger.evaluate(brown_tagged_sents)
0.13089484257215028

正则表达式标注器

>>>patterns= [
... (r'.*ing$', 'VBG'), #gerunds
... (r'.*ed$', 'VBD'), #simple past
... (r'.*es$', 'VBZ'), #3rdsingular present
... (r'.*ould$', 'MD'), #modals
... (r'.*\'s$', 'NN$'), #possessivenouns
... (r'.*s$', 'NNS'), #plural nouns
... (r'^-?[0-9]+(.[0-9]+)?$', 'CD'), #cardinal numbers
... (r'.*', 'NN') #nouns(default)
... ]
#不过要注意,正则表达式是按顺序匹配的,匹配上第一个后面的就不会在匹配
>>>regexp_tagger = nltk.RegexpTagger(patterns)
>>>regexp_tagger.tag(brown_sents[3])
[('``', 'NN'), ('Only', 'NN'), ('a', 'NN'), ('relative', 'NN'), ('handful', 'NN'),
('of', 'NN'), ('such', 'NN'), ('reports', 'NNS'), ('was', 'NNS'), ('received', 'VBD'),
("''", 'NN'), (',', 'NN'), ('the', 'NN'), ('jury', 'NN'), ('said', 'NN'), (',', 'NN'),
('``', 'NN'), ('considering', 'VBG'), ('the', 'NN'), ('widespread', 'NN'), ...]
#通过检测,这种方式正确率提高了
>>>regexp_tagger.evaluate(brown_tagged_sents)
0.20326391789486245

查询标注器

#找出100个最频繁的词,存储他们最有可能的标记。

#然后使用这些信息作为查询标注器的模型

fd=nltk.FreqDist(brown.words(categories='news'))
cfd=nltk.ConditionalFreqDist(brown.tagged_words(categories='news'))
most_freq_words=fd.keys()[:100]
likely_tags=dict((word,word,cfd[word].max()) for word in most_freq_words)
baseline_tagger=nltk.UnigramTagger(model=likely_tags)
baseline_tagger.evaluate(brown_tagged_sents)

通过对这个标注器进行评价,可以看到评价的结果,正确率又提升了:0.45578495136941344

如果我们拿这个标注器在一些未标注的文本上进行标注,会出现一些None的标签,这是因为它们不再100个最频繁的词汇当中。

#在这样的情况下,我们可以使用 回退,当查询标注器无法工作的时候,回退到另一个标注器进行工作。
>>>baseline_tagger =nltk.UnigramTagger(model=likely_tags,
...                     backoff=nltk.DefaultTagger('NN'))
posted @ 2013-05-26 11:00  createMoMo  阅读(989)  评论(0)    收藏  举报