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. eclipse maven maven-compiler-plugin 报错 完全解决

    报错如下: Maven install失败 Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:comp ...

  2. vim的简单使用

    vim的学习曲线相当的大(参看各种文本编辑器的学习曲线),所以,如果你一开始看到的是一大堆VIM的命令分类,你一定会对这个编辑器失去兴趣的.下面的文章翻译自<Learn Vim Progress ...

  3. C# txt文件的读取与写入

    C#创建记事本方法一://创建对象 FileStream stream = new FileStream(@"d:\aa.txt",FileMode.Create);//fileM ...

  4. VS2010_DLL_共享数据段

    1.问题:写了一个DLL,自己一直测试不成功(程序A设置了 数值之后,程序B 始终读不到 读出来的都是初始化时的数值...) 具体过程: (1).DLL当初没想要用 共享数据段,测试使用 一直都是OK ...

  5. RestTemplate学习

    在学习spring cloud的时候,用到了RestTemplate,找到一篇博客,写的很好,学习转载! 文章转载自:https://blog.csdn.net/itguangit/article/d ...

  6. Golang的session管理器

    对于一些需要对用户进行管理(比如验证操作的权限等)的站点来说,session管理器是必不可少的.下面实现了一个线程安全的简单session管理类.生产环境:golang1.4.2+win7x64gol ...

  7. Linux中apt与apt-get命令的区别与解释

    2019-01-15 14:35:39 随着 apt install package 命令的使用频率和普遍性逐步超过 apt-get install package,越来越多的其它 Linux 发行版 ...

  8. php中文件操作常用函数有哪些

    php中文件操作常用函数有哪些 一.总结 一句话总结:读写文件函数 判断文件或者目录是否存在函数 创建目录函数 file_exists() mkdir() file_get_content() fil ...

  9. php单例模式的使用场景,使用方法

    一个类只有一个对象实例 1.含义 作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统全局地提供这个实例.它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用. 2 ...

  10. 宽度优先搜索BFS(Breadth-First-Search)

    Breadth-First-Search 1. 与DFS的异同 相同点:搜索所有可能的状态. 不同点:搜索顺序. 2. BFS总是先搜索距离初始状态近的状态,它是按照:开始状态->只需一次转移就 ...