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. BMP操作_测试

    1.参考网址: http://blog.sina.com.cn/s/blog_678b377a0100mlyb.html http://blog.csdn.net/weiyongtao87/artic ...

  2. Vscode中运行js文件或部分代码 ,在下面cmd输出中显示结果

    重启 vscode,  这个插件  真好用,, 赞个 ....

  3. 力扣(LeetCode) 136. 只出现一次的数字

    给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次.找出那个只出现了一次的元素. 说明: 你的算法应该具有线性时间复杂度. 你可以不使用额外空间来实现吗? 示例 1: 输入: [ ...

  4. yum update软件包冲突

    因升级系统过程中断,重新进入系统继续升级出现如下问题(内容太多,只粘部分内容) # yum update 正在解决依赖关系 --> 正在检查事务 ---> 软件包 alsa-firmwar ...

  5. 电脑用HDMI线分屏后,耳机或音箱没声音之完美解决!

    现今,由于工作需要,很多人都偏爱给自己的电脑进行分屏,两个显示器同时连接在一台电脑上,并进行“扩展这些功能显示”,从而大大提高了工作积极性和工作效率.本人在进行分屏后遇到了耳机没有声音的问题,并进行了 ...

  6. 梯度消失 / 梯度爆炸以及Xavier初始化

    2018-12-06 16:25:08 首先我们先来看一下求解梯度的公式,以下面三层的网络为例: 如果w初始化为大于1的数字,在深层神经网络计算梯度的时候就会出现梯度爆炸的现象: 如果w初始化为小于1 ...

  7. Getting started with Processing 第十三章——延伸(2)

    与 Arduino 联动 在 Processing 中,可以通过:import processing.serial.* Serial port; //声明串口对象port = new Serial(t ...

  8. java学习视频

    随着信息化的发展,IT行业变得越来火,在开发领域,Java语言在是市面上很受欢迎的编程语言,很多初学者不知道从何学起,为了找资源浪费大量时间,而我就将自己的寻找资源分享给大家,让大家能够更加便捷的学习 ...

  9. c# winform 中的坐标系

    从数学角度讲,Point是一个二维矢量,包含两个公共整型属性,属性用大写X和Y(c#中公共属性一般约定以大写字母开头).当坐标不是整数值是float时,用PointF代替Point使用. 常用的Siz ...

  10. 20170906xlVBA_RecursionGetFiles

    Dim Dic As Object Sub GetFileName() Dim FolderPath As String Set Dic = CreateObject("Scripting. ...