【词性标注】词性标注器设计

写在前面:本文用基于nltk库Brown语料库进行演示:

from nltk.corpus import brown
import nltk

sent = brown.sents(categories = 'news')[0]                # Brown语料库中取一个句子,一会儿我们可对其进行词性标注
tagged_sents = brown.tagged_sents(categories = 'news')    # Brown语料库提供的人工的正确标注,一会儿我们用它来评估我们设计的标注器

 
 
 

默认标注器

核心思想:我们取一个极端的情况(没有办法的办法),用一个语料中出现最多的词性,来标注所有的词

tags = [tag for (word, tag) in brown.tagged_words(categories = 'news')]
w = nltk.FreqDist(tags).max()	
# 得到w为“NN”,即名词————英文中出现最多是名词NN,中文可不是哦>_<!						

default_tagger = nltk.DefaultTagger('NN')						 # 设计标注器
print("【默认标注器】:", default_tagger.evaluate(tagged_sents))    # 评估
>>>【默认标注器】:0.13089484257215028

 

正则标注器

核心思想:正则标注器是依赖于形态变化的,比如-ing是动名词,ed是过去式…

patterns = [
(r'.*ing$', 'VBG'),                 # gerunds 动名词
(r'.*ed$', 'VBD'),                  # simple past 过去式
(r'.*es$', 'VBZ'),                  # 3rd singular present 第三人称现在式
(r'.*ould$', 'MD'),                 # modals 情态动词
(r'.*\'s$', 'NN$'),                 # possessive nouns 名词所有格
(r'.*s$', 'NNS'),                   # plural nouns 复数名词
(r'^-?[0-9]+(.[0-9]+)?$', 'CD'),    # cardinal numbers 基数词
(r'.*', 'NN')]                      # nouns(default) 名词(默认)

regex_tagger = nltk.RegexpTagger(patterns)
print("【正则标注器】:", regex_tagger.evaluate(tagged_sents))
>>>【默认标注器】:0.20326391789486245

 

查询标注器

核心思想:高频词(多是虚词和代词)可以占到全部词次的50%,我们仅仅对这些高频词进行专门的标注,会发现效果出奇地不错!

fd = nltk.FreqDist(brown.words(categories = 'news'))
cfd = nltk.ConditionalFreqDist(brown.tagged_words(categories = 'news'))
most_frequent_words = [w for (w, n) in fd.most_common(100)]
most_frequent_words_tags = dict((w, cfd[w].max()) for w in most_frequent_words)
# 上面几行代码是对最高频的100词进行了专门标注

baseline_tagger = nltk.UnigramTagger(model = most_frequent_words_tags)
print("【查询标注器】:", baseline_tagger.evaluate(tagged_sents))
>>>【查询标注器】:0.45578495136941344

 
 
 

从这里开始,下面的标注器都需要用正确的标注来进行训练

 

Unigram标注器

核心思想:只利用词本身的特性,没有考虑上下文,即“一元标注”

unigram_tagger = nltk.UnigramTagger(train_sents)
print("【Unigram标注器】:", unigram_tagger.evaluate(test_sents))
>>>【Unigram标注器】:0.7878104465976167

 

Bigram标注器

核心思想:N-gram标注器就是依据前n-1个词的词性,判断当前词的词性——即考虑到上下文。你会发现它的评估得分非常非常低,这是因为语料中有很多新词,这会导致一小片的词性无法正确标注——这种现象称为数据稀疏,显然N越大,这种现象越严重

bigram_tagger = nltk.BigramTagger(train_sents)
print("【Bigram标注器】:", bigram_tagger.evaluate(test_sents))
>>>【Bigram标注器】:0.0878438578906337

 

组合标注器

核心思想:顾名思义——当Bigram标注器无法找到一个标记,则尝试使用Unigram标注器;当Unigram标注器也无法正确标注,则老老实实地使用默认标注器

tagger0 = nltk.DefaultTagger('NN')
tagger1 = nltk.UnigramTagger(train_sents, backoff=tagger0)
tagger2 = nltk.BigramTagger(train_sents, backoff=tagger1)

print("【组合标注器】:", tagger2.evaluate(test_sents))
>>>【组合标注器】:0.8257601069161377

 
 
 
 
 
 
 
 

注:实际运行效果对比
在这里插入图片描述

 
 
 
 
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值