您的位置:首页 > 编程语言 > Python开发

【语言处理与Python】5.5N-gram标注

2013-05-26 15:50 309 查看
一元标注(Unigram Tagging)

一元标注基于简单的统计算法,对每个标识符分配这个独特的标识符最有可能的标记。

>>>from nltk.corpusimport brown
>>>brown_tagged_sents= brown.tagged_sents(categories='news')
>>>brown_sents= brown.sents(categories='news')
>>>unigram_tagger = nltk.UnigramTagger(brown_tagged_sents)
>>>unigram_tagger.tag(brown_sents[2007])
[('Various', 'JJ'), ('of', 'IN'), ('the', 'AT'), ('apartments', 'NNS'),
('are', 'BER'), ('of', 'IN'), ('the', 'AT'), ('terrace', 'NN'), ('type', 'NN'),
(',', ','), ('being', 'BEG'), ('on', 'IN'), ('the', 'AT'), ('ground', 'NN'),
('floor', 'NN'), ('so', 'QL'), ('that', 'CS'), ('entrance', 'NN'), ('is', 'BEZ'),
('direct', 'JJ'), ('.', '.')]
>>>unigram_tagger.evaluate(brown_tagged_sents)
0.9349006503968017


分离训练和测试数据

为了能够更客观的分离训练和测试数据,一般我们的训练和测试数据不使用相同的。

>>>size = int(len(brown_tagged_sents) *0.9)
>>>size
4160
>>>train_sents = brown_tagged_sents[:size]
>>>test_sents = brown_tagged_sents[size:]
>>>unigram_tagger = nltk.UnigramTagger(train_sents)
>>>unigram_tagger.evaluate(test_sents)
0.81202033290142528


一般的N-gram的标注

在标注的时候,会考虑在这个词之前的n-1个词汇进行标注。

#一个bigram tagger的例子
>>>bigram_tagger = nltk.BigramTagger(train_sents)
>>>bigram_tagger.tag(brown_sents[2007])
[('Various', 'JJ'), ('of', 'IN'), ('the', 'AT'), ('apartments', 'NNS'),
('are', 'BER'), ('of', 'IN'), ('the', 'AT'), ('terrace', 'NN'),
('type', 'NN'), (',', ','), ('being', 'BEG'), ('on', 'IN'), ('the', 'AT'),
('ground', 'NN'), ('floor', 'NN'), ('so', 'CS'), ('that', 'CS'),
('entrance', 'NN'), ('is', 'BEZ'), ('direct', 'JJ'), ('.', '.')]
>>>unseen_sent = brown_sents[4203]
>>>bigram_tagger.tag(unseen_sent)
[('The', 'AT'), ('population', 'NN'), ('of', 'IN'), ('the', 'AT'), ('Congo', 'NP'),
('is', 'BEZ'), ('13.5', None),('million', None),(',', None),('divided', None),
('into', None),('at', None),('least', None),('seven', None),('major', None),
('``', None),('culture', None),('clusters', None),("''", None),('and', None),
('innumerable', None),('tribes', None),('speaking', None),('400', None),
('separate', None),('dialects', None),('.', None)]
#bigram标注器对于看到过的句子的词标注的很好,但是没有见过的,就会非常差。
>>>bigram_tagger.evaluate(test_sents)
0.10276088906608193


组合标注器

为了解决精度和覆盖范围之间的权衡的一个办法是,尽可能的使用更精确的算法。

在下面举了一个组合标注器的例子,提高的评价得分。

1. 尝试使用bigram标注器标注标识符。

2. 如果bigram标注器无法找到一个标记,尝试unigram标注器。

3. 如果unigram标注器也无法找到一个标记,使用默认标注器。

>>>t0 =nltk.DefaultTagger('NN')
>>>t1 =nltk.UnigramTagger(train_sents,backoff=t0)
>>>t2 =nltk.BigramTagger(train_sents,backoff=t1)
>>>t2.evaluate(test_sents)
0.84491179108940495


我们也可以指定一个标注器需要看到一个上下文的多少个实例才能保留它。

nltk.BigramTagger(sents,cutoff=2,backoff=t1)


标注生词

在遇到生词时,不同的标注器标注的结果可能是不一样的。

存储标注器

将训练好的标注器保存起来,然后再重复使用。

>>>from cPickle import dump
>>>output= open('t2.pkl', 'wb')
>>>dump(t2,output,-1)
>>>output.close()

>>>from cPickle import load
>>>input = open('t2.pkl', 'rb')
>>>tagger = load(input)
>>>input.close()


跨句子边界标注(句子层面的N-gram标注)

brown_tagged_sents= brown.tagged_sents(categories='news')
brown_sents= brown.sents(categories='news')
size = int(len(brown_tagged_sents) *0.9)
train_sents = brown_tagged_sents[:size]
test_sents = brown_tagged_sents[size:]
t0 = nltk.DefaultTagger('NN')
t1 = nltk.UnigramTagger(train_sents,backoff=t0)
t2 = nltk.BigramTagger(train_sents, backoff=t1)
>>>t2.evaluate(test_sents)
0.84491179108940495
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: