python自然语言处理-读书笔记8

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zlp_zky/article/details/83106246
#N-Gram Tagging N元语法标注
#一元标注(Unigram  Tagging)一元标注器基于一个简单的统计算法:对每个标识符分配这个独特的标识符最有可能的 标记。例如:它将分配标记 JJ 给词 frequent 的所有出现,因为frequent 用作一个形容词(例 如:a frequent word)比用作一个动词(例如:I frequent this cafe)更常见。
#训练一个一元标注器,用它来标注一个句子,然后评估:
brown_tagged_sents = brown.tagged_sents(categories='news')
brown_sents = brown.sents(categories='news')
unigram_tagger = nltk.UnigramTagger(brown_tagged_sents)
print(unigram_tagger.tag(brown_sents[2007]))
print(unigram_tagger.evaluate(brown_tagged_sents))
#分离训练和测试数据
size = int(len(brown_tagged_sents) * 0.9)
print(size)
train_sents = brown_tagged_sents[:size]
test_sents = brown_tagged_sents[size:]
# unigram_tagger = nltk.UnigramTagger(train_sents)
# print(unigram_tagger.evaluate(test_sents))

#一般的 N-gram 的标注 一个n-gram 标注器是一个 unigram 标注器的一般化,它的上下文是当前词和它前面n-1个标识符的词性标记
#NgramTagger 类使用一个已标注的训练语料库来确定对每个上下文哪个词性标记最 有可能。在这里,我们看到一个n-gram标注器的特殊情况,即一个 bigram 标注器。首先, 我们训练它,然后用它来标注未标注的句子:
# bigram_tagger = nltk.BigramTagger(train_sents)#训练
# print(bigram_tagger.tag(brown_sents[2007]))#标注
# unseen_sent = brown_sents[4203]  #请注意,bigram 标注器能够标注训练中它看到过的句子中的所有词,但对一个没见过 的句子表现很差。只要遇到一个新词(如13.5),就无法给它分配标记。它不能标注下面的 词(如:million),即使是在训练过程中看到过的,只是因为在训练过程中从来没有见过它 前面有一个None 标记的词。因此,标注器标注句子的其余部分也失败了。它的整体准确度 得分非常低:
# print(bigram_tagger.tag(unseen_sent))
# print(bigram_tagger.evaluate(test_sents))
#当n 越大,上下文的特异性就会增加,我们要标注的数据中包含训练数据中不存在的上 下文的几率也增大。这被称为数据稀疏问题,在NLP 中是相当普遍的。因此,我们的研究 结果的精度和覆盖范围之间需要有一个权衡
# 组合标注器
# 我们可以按如下方式组合 bigram 标注器、uni gram标注器和一个默认标注器:
# 1. 尝试使用 bigram 标注器标注标识符。
# 2. 如果 bigram 标注器无法找到一个标记,尝试unigram 标注器。
# 3. 如果 unigram 标注器也无法找到一个标记,使用默认标注器。
# 大多数NLTK 标注器允许指定一个回退标注器。回退标注器自身可能也有一个回退标注器:
t0 = nltk.DefaultTagger('NN')
t1 = nltk.UnigramTagger(train_sents, backoff=t0)
t2 = nltk.BigramTagger(train_sents, backoff=t1)
t3 = nltk.TrigramTagger(train_sents, backoff=t2)
# print(t3.evaluate(test_sents)) #我们可 以进一步指定一个标注器需要看到一个上下文的多个实例才能保留它。例如:nltk.Bigram Tagger(sents, cutoff=2, backoff=t1)将会丢弃那些只看到一次或两次的上下文。
#标注生词
#一个有用的基于上下文标注生词的方法是限制一个标注器的词汇表为最频繁的n 个词,

#存储标注器
#在大语料库上训练一个标注器可能需要大量的时间。没有必要在每次我们需要的时候训 练一个标注器,很容易将一个训练好的标注器保存到一个文件以后重复使用。让我们保存我 们的标注器t2到文件 t2.pkl:
# from pickle import dump
# output = open('t2.pkl', 'wb')
# dump(t2, output, -1)
# output.close()
# # 现在,我们可以在一个单独的Python 进程中载入我们保存的标注器:
# from pickle import load
# input = open('t2.pkl', 'rb')
# tagger = load(input)
# input.close()
# #现在,让我们的检查它是否可以用来标注
# text = """The board's action shows what free enterprise is up against in our complex maze of regulatory laws ."""
# tokens = text.split()
# print(tagger.tag(tokens))

#性能限制
#。给定当前单词及其前两个标记,根据训练数据,在 5%的情况中,有一个以上的标记可能合理地分配给当前词。假设我们总是挑选在这种含糊 不清的上下文中最有可能的标记,可以得出trigram 标注器性能的一个下界。
# cfd = nltk.ConditionalFreqDist( ((x[1], y[1], z[0]), z[1])  for sent in brown_tagged_sents  for x, y, z in nltk.trigrams(sent))
# ambiguous_contexts = [c for c in cfd.conditions() if len(cfd[c]) > 1]
# print(sum(cfd[c].N() for c in ambiguous_contexts) / cfd.N())
# #调查标注器性能的另一种方法是研究它的错误。有些标记可能会比别的更难分配,可能 需要专门对这些数据进行预处理或后处理。一个方便的方式查看标注错误是混淆矩阵。它用 图表表示期望的标记(黄金标准)与实际由标注器产生的标记:
# test_tags = [tag for sent in brown.sents(categories='editorial') for (word, tag) in t2.tag(sent)]
# gold_tags = [tag for (word, tag) in brown.tagged_words(categories='editorial')]
# print(nltk.ConfusionMatrix(gold_tags, test_tags))

#跨句子边界标注
#一个n-gram标注器使用最近的标记作为为当前的词选择标记的指导。当标记一个句子 的第一个词时,trigram 标注器将使用前面两个标识符的词性标记,这通常会是前面句子的 最后一个词和句子结尾的标点符号。然而,在前一句结尾的词的类别与下一句的开头的通常 没有关系。
#为了应对这种情况,我们可以使用已标注句子的链表来训练、运行和评估标注器
# 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)
# print( t2.evaluate(test_sents))

#基于转换的标注
# n-gram标注器的一个潜在的问题是它们的n-gram表的大小(或语言模型)。如果使用各 种语言技术的标注器部署在移动计算设备上,在模型大小和标注器性能之间取得平衡是很重 要的。
#第二个问题是关于上下文的。n-gram标注器从前面的上下文中获得的唯一的信息是标 记,虽然词本身可能是一个有用的信息源。n-gram模型使用上下文中的词的其他特征为条 件是不切实际的
#Brill 标注是一种基于转换的学习 ,以它的发明者命名。一般的想法很简单:猜每个词 的标记,然后返回和修复错误的。在这种方式中,Brill 标注器陆续将一个不良标注的文本 转换成一个更好的。与n-gram标注一样,这是有监督的学习方法,因为我们需要已标注的 训练数据来评估标注器的猜测是否是一个错误。
#然而,不像n-gram标注,它不计数观察结 果,只编制一个转换修正规则链表。Brill 标注使用了的想法:以大笔画开始,然后修复细节,一点点的细致的改变。


#在一般情况下,语言学家使用形态学、句法和语义线索确定一个词的类别。

猜你喜欢

转载自blog.csdn.net/zlp_zky/article/details/83106246