1.一元标注器(Unigram Tagging)

一元标注器利用一种简单的统计算法,对每个标注符分配最有可能的标记。例如:它将分配标记JJ给词frequent,因为frequent用作形容词更常见。一元标注器的行为与查找标注器相似,建立一元标注器的技术,称为训练。在下面的代码例子中,“训练”一个一元标注器,用它来标注一个句子,然后进行评估。

 >>> from nltk.corpus import brown
>>> brown_tagged_sents=brown.tagged_sents(categories='news') //‘news’类别下,已经被标记的句子
>>> brown_sents=brown.sents(categories='news') //‘news’类别下,未被标记的句子
>>> import nltk
>>> 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'), ('ty
pe', 'NN'), (',', ','), ('being', 'BEG'), ('on', 'IN'), ('the', 'AT'), ('ground', 'NN'), ('floor', 'NN'), ('so', 'QL'), ('that', 'CS'), ('en
trance', 'NN'), ('is', 'BEZ'), ('direct', 'JJ'), ('.', '.')]
>>> unigram_tagger.evaluate(brown_tagged_sents) //评估标注器的性能
0.9349006503968017
>>>

上面代码中,使用unigram_tagger.tag(brown_sents[2007]) 来标记的是brwon_sents的第2008个句子,因为brown_sents中以句子为单位,每个句子以词list的形式存在,所以必须制定目标标记的句子,而不能一次性标记多个句子。

>>> brown_sents
[['The', 'Fulton', 'County', 'Grand', 'Jury', 'said', 'Friday', 'an', 'investigation', 'of', "Atlanta's", 'recent', 'primary', 'election', '
produced', '``', 'no', 'evidence', "''", 'that', 'any', 'irregularities', 'took', 'place', '.'], ['The', 'jury', 'further', 'said', 'in', 't
erm-end', 'presentments', 'that', 'the', 'City', 'Executive', 'Committee', ',', 'which', 'had', 'over-all', 'charge', 'of', 'the', 'election
', ',', '``', 'deserves', 'the', 'praise', 'and', 'thanks', 'of', 'the', 'City', 'of', 'Atlanta', "''", 'for', 'the', 'manner', 'in', 'which
', 'the', 'election', 'was', 'conducted', '.'], ...]
>>>

通过在初始化标注器时指定已标注的句子数据作为参数来训练一元标注器。训练过程中涉及检查每个词的标记,将所有词的最可能标记存储在一个字典里面,这个字典存储在标注器内部。

2.分离训练和测试数据

在一些数据上训练标注器,必须注意不要在相同的数据上测试。如果一个标注器只是单纯地去记忆它的训练数据,而不试图建立一般的模型,测试结果会更好,但在标注新的文本时不起作用。相反,我们应该分割数据,90%为训练数据,其余10%为测试数据。

 >>> 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.8124190172430977
>>>

显然得分更糟糕了,但是对这种标注器是无用的情况有了更好的了解。

3.一般的N-gram的标注

  当基于unigrams处理语言 处理任务时,可使用上下文中的项目。标注时,只考虑当前的标识符,而不考虑其他上下文。给定一个模型,最好是为每个词标注其先验的最可能的标记。这意味着将使用相同的标记标注词。n-gram标注器是ungram标注器的一般化,它的上下文是当前词和它前面n-1个标识符的词性标记。

  1-gram标注器(unigram tagger)是一元标注器的另一个名称:即用于标注上下文是标识符本身的标识符。2-gram标注器也称为二元标注器(bigram taggers), 3-gram标注器也称为三元标注器(trigram taggers).

  NgramTagger 类使用一个已标注的训练语料库来确定每个上下文中哪个词性标记最有可能。下面的例子中,我们看到n-gram标注器的一个特殊情况,即bigram标注器,首先训练它,然后用它来标注未标注的句子。

 >>> 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'), ('ty
pe', 'NN'), (',', ','), ('being', 'BEG'), ('on', 'IN'), ('the', 'AT'), ('ground', 'NN'), ('floor', 'NN'), ('so', 'CS'), ('that', 'CS'), ('en
trance', '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), ('', None), ('separate', No
ne), ('dialects', None), ('.', None)]
>>> bigram_tagger.evaluate(test_sents)
0.10276088906608193
>>>

  注意,bigram标注器能够标注训练中它看到过的句子中的所有词,但对一个没见过的句子却不行。只要遇到一个新词就无法给它分配标记。它不能标注下面的词,即使在训练过程中看到过的,因为在训练过程中从来没有见过他前面有None标记的词。因此,标注器也无法标注句子的其余部分。它的整体准确度得分非常低,从上面运行结果来看只有0.1左右。

  当n 越大时,上下文的特异性就会增加,要标注的数据中包含训练数据中不存在的上下文的几率也增大。这被称为数据稀疏问题,在NLP中是相当普遍的。因此,研究结果的精度和覆盖范围之间需要有一个权衡。

  N-gram标注器不应该考虑跨越句子边界的上下文,因此,nltk的标注器被涉及用于句子链表,一个句子是一个词链表。在一个句子的开始,tn-1和前面的标记被设置为None。

4.组合标注器

  解决精度和覆盖范围之间权衡的一个办法是尽可能地使用更精确的算法,但却在很多时候却逊于覆盖范围更广的算法。例如:可以按如下方式组合bigram标注器,unigram标注器和一个默认标注器。

  • 尝试使用bigram标注器标注标识符
  •   如果bigram标注器无法找到标记,尝试unigram标注器。
  •   如果unigram标注器也无法找到标记,使用默认标注器。

大多数nltk标注器允许指定回退标注器。回退标注器自身可能也有回退标注器。

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

注意:在标注器初始化时要指定回退标注器,从而训练时才能利用回退标注器。于是,如果在上下文中bigram标注器将分配与它的unigram回退标注器一样的标记,那么bigram标注器丢弃训练实例。这样可以保持尽可能小的bigram标注器模型。可以进一步确定的是标注器需要保存上下文多个实例。例如:nltk.BigramTagger(sents, cutoff=2, backoff=t1)将丢弃那些只出现一次或两次的上下文。

5.标注生词

标注生词的方法是回退到正则表达式标注器或默认标注器。这些都无法利用上下文。因此,如果标注器遇到词blog,但训练过程中没有看到过,它会分配相同的标记,不论这个词出现的上下文是the blog 还是to blog。

基于上下文标注生词的方法是限制标注器的词汇表为最频繁的n个词。训练时,unigram标注器可能会将UNK标注名词。然而,n-gram标注器会检测其他标记的上下文。例如:如果前面的词是to(标注未TO),那么UNK可能会被标注为一个动词。

6.存储标注器

原因:在大语料库中训练标注器可能需要花费大量时间,而且没有必要重复训练标注器。

解决方案:将一个训练好的标注器保存到文件中供以后重复使用。

实例:将标注器t2保存到文件t2.pkl。

7.性能限制

调查标注器性能的方法:

  • 根据经验
  • 研究它的错误

训练数据中的歧义可产生标注器性能的上限。有时更多的上下文能解决这些歧义。然而,在其他情况下,只有参考语法或现实世界的知识才能解决歧义。尽管存在缺陷,但词性标注在利用统计方法进行自然语言处理的发展过程中起到了核心作用。

python 自然语言处理(六)____N-gram标注的更多相关文章

  1. Python自然语言处理工具小结

    Python自然语言处理工具小结 作者:白宁超 2016年11月21日21:45:26 目录 [Python NLP]干货!详述Python NLTK下如何使用stanford NLP工具包(1) [ ...

  2. 《Python自然语言处理》

    <Python自然语言处理> 基本信息 作者: (美)Steven Bird    Ewan Klein    Edward Loper 出版社:人民邮电出版社 ISBN:97871153 ...

  3. 转-Python自然语言处理入门

      Python自然语言处理入门 原文链接:http://python.jobbole.com/85094/ 分享到:20 本文由 伯乐在线 - Ree Ray 翻译,renlytime 校稿.未经许 ...

  4. Python自然语言处理(1):初识NLP

    由于我们从美国回来就是想把医学数据和医学人工智能的事认真做起来,所以我们选择了比较扎实的解决方法,想快速出成果的请绕道.我们的一些解决方法是:1.整合公开的所有医学词典,尽可能包含更多的标准医学词汇: ...

  5. 《Python自然语言处理》中文版-纠错【更新中。。。】

    最近在看<Python自然语言处理>中文版这本书,可能由于是从py2.x到py3.x,加上nltk的更新的原因,或者作者的一些笔误,在书中很多代码都运行不能通过,下面我就整理一下一点有问题 ...

  6. python学习第六讲,python中的数据类型,列表,元祖,字典,之列表使用与介绍

    目录 python学习第六讲,python中的数据类型,列表,元祖,字典,之列表使用与介绍. 二丶列表,其它语言称为数组 1.列表的定义,以及语法 2.列表的使用,以及常用方法. 3.列表的常用操作 ...

  7. Python学习笔记六

    Python课堂笔记六 常用模块已经可以在单位实际项目中使用,可以实现运维自动化.无需手工备份文件,数据库,拷贝,压缩. 常用模块 time模块 time.time time.localtime ti ...

  8. Python学习第六课

    Python学习第六课 课前回顾 列表 创建 通过 [] :写在[]里,元素之间用逗号隔开 对应操作: 查 增 append insert 改(重新赋值) 删除(remove del pop(删除后会 ...

  9. Python 自然语言处理笔记(一)

    一. NLTK的几个常用函数 1. Concordance 实例如下: >>> text1.concordance("monstrous") Displaying ...

  10. NLP1 —— Python自然语言处理环境搭建

    最近开始研究自然语言处理了,所以准备好好学习一下,就跟着<Python自然语言处理>这本书,边学边整理吧 安装 Mac里面自带了python2.7,所以直接安装nltk就可以了. 默认执行 ...

随机推荐

  1. Arrays常用方法

    传送:https://blog.csdn.net/u013256816/article/details/50924762

  2. 基于iOS用CoreImage实现人脸识别

    2018-09-04更新: 很久没有更新文章了,工作之余花时间看了之前写的这篇文章并运行了之前写的配套Demo,通过打印人脸特征CIFaceFeature的属性,发现识别的效果并不是很好,具体说明见文 ...

  3. 学习笔记27—python中numpy.ravel() 和 flatten()函数

    简介 首先声明两者所要实现的功能是一致的(将多维数组降位一维).这点从两个单词的意也可以看出来,ravel(散开,解开),flatten(变平).两者的区别在于返回拷贝(copy)还是返回视图(vie ...

  4. Linux 中 MySQL常用命令

    一. 数据库登录mysql -uroot -p二..退出数据库quit 和 exit或ctrl + d三.数据库操作1. 查看所有数据库 show databases;2. 查看当前使用的数据库sel ...

  5. python类中保存非绑定方法作为成员函数

    习惯了函数式,动不动传一个函数.但是直接把函数作为类方法保存,再调用时会报错. 举一个unittest时的例子 class MyTestCase(unittest.TestCase): @classm ...

  6. flex属性的学习

    1.需要记住的属性和值. ------------------------------------------------------------- 方向横和纵 flex-direction: row ...

  7. 下一个更大的数 Next Greater Element

    2018-09-24 21:52:38 一.Next Greater Element I 问题描述: 问题求解: 本题只需要将nums2中元素的下一个更大的数通过map保存下来,然后再遍历一遍nums ...

  8. 最简单的解决Chrome浏览器主页被hao123、360和2345篡改的方法是什么

    最简单的解决Chrome浏览器主页被hao123.360和2345篡改的方法是什么 一.总结 一句话总结:打开chrome的安装目录,将chrome.exe改成chrome1.exe即可,然后发送一个 ...

  9. 如何获取select选中的值

    一:JavaScript原生的方法 1:拿到select对象: var myselect=document.getElementById(“test”); 2.拿到选中项的索引: var index= ...

  10. No address associated with hostname

    java.net.UnknownHostException: Unable to resolve host "www.baidu.com": No address associat ...