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. L1-044. 稳赢

    这种题不是考思维,就是考你细心程度还有基础知识的,代码如下: #include <iostream> #include <string> using namespace std ...

  2. node启动服务报错Node.js Error: Cannot find module express

    在node文件夹中(M:\express-test),执行 npm install express 在使用npm安装express时,报npm WARN saveError ENOENT: no su ...

  3. 剖析Hadoop和Spark的Shuffle过程差异

    一.前言 对于基于MapReduce编程范式的分布式计算来说,本质上而言,就是在计算数据的交.并.差.聚合.排序等过程.而分布式计算分而治之的思想,让每个节点只计算部分数据,也就是只处理一个分片,那么 ...

  4. 力扣(LeetCode)67. 二进制求和

    给定两个二进制字符串,返回他们的和(用二进制表示). 输入为非空字符串且只包含数字 1 和 0. 示例 1: 输入: a = "11", b = "1" 输出: ...

  5. win10新系统修改onedrive目录,提示找不到OneDrive目录

    win10不知更新了什么,x1c非常卡一跳一跳的,很多年没见过了-_-!!( 原因排查:http://www.cnblogs.com/xuanmanstein/p/8878180.html). 于是重 ...

  6. centos 7 安装TensorFlow

    查看linux版本 uname -a 查看磁盘大小 准备好python 2.7 查看python版本  import sysprint sys.version print sys.version_in ...

  7. Java Config for WebProject

    1.Java EE vs Java SE They are just official SDK,when using IDE,it's ok to just install jdk/jre. &quo ...

  8. 数据结构(C语言版)-第6章 图

    6.1 图的定义和基本术语 图:Graph=(V,E)  V:顶点(数据元素)的有穷非空集合:  E:边的有穷集合. 无向图:每条边都是无方向的 有向图:每条边都是有方向的 完全图:任意两个点都有一条 ...

  9. springboot---->错误: 找不到或无法加载主类

    刚开始是往上面箭头指出的方向去找问题的原因,但是试了各种方法后问题还是没有解决,于是乎我把焦点转去查看eclipsede控制台处: 主要的错误提示如下: Archive for required li ...

  10. English trip EM2-PE-6A Family Relationship Teacher:Taylor

    课上内容(Lesson) What's your name? Where is your hometown?  你的家乡是哪里? Where do you come from?    你从哪里来?  ...