Python NLTK学习6(创建词性标注器)

发表于: 2017年1月5日  阅读: 6487

除特别注明外,本站所有文章均为小杰Code原创

本系列博客为学习《用Python进行自然语言处理》一书的学习笔记。

默认标注器

默认标注器为每个单词分配同样的标记,尽管很平庸,但它也是有作用的,先看示例:

import nltk

raw = "You are a good man, but i don't love you!"

tokens = nltk.word_tokenize(raw)

default_tagger = nltk.DefaultTagger('NN')

tagged_words = default_tagger.tag(tokens)

print(tagged_words)

结果为:

[('You', 'NN'), ('are', 'NN'), ('a', 'NN'), ('good', 'NN'), ('man', 'NN'), (',', 'NN'), ('but', 'NN'), ('i', 'NN'), ('do', 'NN'), ("n't", 'NN'), ('love', 'NN'), ('you', 'NN'), ('!', 'NN')]

DefaultTagger的构造函数接受一个标记字符串作为参数,生成一个默认标注器对象,从结果可以看到默认标注器把所有的词都标记为NN。

DefaultTagger::tag(tokens):对指定的单词列表进行标记,返回被标记后的单词列表。

DefaultTagger::evaluete(tagged_sents):使用已经被标记的句子评价标注器,返回正确率0~1.0。

from nltk.corpus import brown

tagged_sents = brown.tagged_sents(categories='news')

print(default_tagger.evaluate(tagged_sents))

结果为:

0.13089484257215028

我们可以看到我们自己创建的默认标注器正确率仅为0.13。

查询标注器

默认标注器对所有单词使用同一个标记,准确率太低,我们可以考虑指定不同的单词为不同的标记,先看一个示例:

# 对新闻文本进行频率分布,找出新闻文本最常用的100个单词

fd = nltk.FreqDist(brown.words(categories='news'))

most_common_pairs = fd.most_common(100)

most_common_words = [i[0] for i in most_common_pairs]

# 对标记后的新闻文本进行条件频率分布,这样我们就可以找到指定单词最多的标记是哪一个

cfd = nltk.ConditionalFreqDist(brown.tagged_words(categories='news'))

# 找出最常用的100个单词的最多标记

likely_tags = dict((word, cfd[word].max()) for word in most_common_words)

# 使用(单词-标记)字典作为模型,生成查询标注器

baseline_tagger = nltk.UnigramTagger(model=likely_tags)

tagged_sents = brown.tagged_sents(categories='news')

print(baseline_tagger.evaluate(tagged_sents))

结果为:

0.45578495136941344

这次我们创建的标注器的正确率为0.45,比我们的默认标注器要好很多。UnigramTagger类的构造函数接受一个(单词-标记)字典作为模型,可以直接生成一个标注器。事实上UnigramTagger和DefaultTagger类都继承自TaggerI,TaggerI具有tag和evaluete方法,所以UnigramTagger也具有tag和evaluete方法。

因为我们只指定了100个单词的标记,我们来看看我们创建的标注器对未指定的单词是如何标记的。

raw = "You are a good man, but i don't love you!"

tokens = nltk.word_tokenize(raw)

print(baseline_tagger.tag(tokens))

结果为:

[('You', None), ('are', 'BER'), ('a', 'AT'), ('good', None), ('man', None), (',', ','), ('but', 'CC'), ('i', None), ('do', None), ("n't", None), ('love', None), ('you', None), ('!', None)]

许多词被分配为None标签,这是因为它们不包含在100单词中。针对这种情况,我们可以给它们一个默认标记。换句话说我们要先使用查找表,如果它不能指定一个标记就使用默认标注器,这个过程叫做回退。

# 使用默认标注器作为回退

baseline_tagger2 = nltk.UnigramTagger(model=likely_tags, backoff=nltk.DefaultTagger('NN'))

tagged_sents = brown.tagged_sents(categories='news')

print(baseline_tagger2.evaluate(tagged_sents))

结果为:

0.5817769556656125

我们可以看到正确率提升了

如果我们增大单词数量,则正确率还会提升。

# 对新闻文本进行频率分布,找出新闻文本最常用的500个单词

fd = nltk.FreqDist(brown.words(categories='news'))

most_common_pairs = fd.most_common(500)

most_common_words = [i[0] for i in most_common_pairs]

# 对标记后的新闻文本进行条件频率分布,这样我们就可以找到指定单词最多的标记是哪一个

cfd = nltk.ConditionalFreqDist(brown.tagged_words(categories='news'))

# 找出最常用的500个单词的最多标记

likely_tags = dict((word, cfd[word].max()) for word in most_common_words)

# 使用(单词-标记)字典作为模型,生成查询标注器

baseline_tagger = nltk.UnigramTagger(model=likely_tags, backoff=nltk.DefaultTagger('NN'))

tagged_sents = brown.tagged_sents(categories='news')

print(baseline_tagger.evaluate(tagged_sents))

结果为:

0.6789983491457326

一元标注器

一元标注器基于一个简单的统计算法:对每个单词分配这个单词最有可能的标记。一元标注器的行为就像一个查询标注器,但是它不需要我们提供model,我们只需要提供训练样本也就是被标记的句子列表,标注器会使用这些样本进行训练,将所有词的最可能标记存储在一个字典里,例子如下:

import nltk

from nltk.corpus import brown

tagged_sents = brown.tagged_sents(categories='news')

# 生成一元标注器

unigram_tagger = nltk.UnigramTagger(train=tagged_sents)

print(unigram_tagger.evaluate(tagged_sents))

结果为:

0.9349006503968017

这个结果比我们前面的查询标注器要好很多,并且一元标注器不需要我们自己去统计每个单词最有可能的标记。

然而使用同一个数据集作为训练集和测试集不是一个好的做法,如果我们训练出来的标注器过拟合我们也不能知道,接下来我们要分离训练集和测试集,我们把数据集的90%作为训练集,10%作为测试集。

tagged_sents = brown.tagged_sents(categories='news')

size = int(len(tagged_sents) * 0.9)

train_sets = tagged_sents[:size]

test_sets = tagged_sents[size:]

# 生成一元标注器

unigram_tagger = nltk.UnigramTagger(train=train_sets)

print(unigram_tagger.evaluate(train_sets))

print(unigram_tagger.evaluate(test_sets))

结果为:

0.9353630649241612

0.8115219774743347

我们可以看到一元标注器在测试集上的正确率为0.81

二元标注器

尽管我们对每个单词分配了这个标识符最有可能的标记,但是在不同的上下文环境中,单词是有可能是其他的标记的。所以一个单词的标记不仅仅和它自身有关系,还可能和它的前一个单词或者更前面的单词有关系。二元标注器就是一个可以考虑单词自身以及前一个单词的标注器。

tagged_sents = brown.tagged_sents(categories='news')

size = int(len(tagged_sents) * 0.9)

train_sets = tagged_sents[:size]

test_sets = tagged_sents[size:]

# 生成二元标注器

bigram_tagger = nltk.BigramTagger(train=train_sets)

print(bigram_tagger.evaluate(train_sets))

print(bigram_tagger.evaluate(test_sets))

结果为:

0.7890434263872471

0.10186384929731884

二元标注器会考查一个单词本身和它前一个单词的标记,如果遇到一个新词,那么二元标注器就没法标记它,并且还会导致接下来的单词都没法标记,所以我们会看到二元标注器在测试集上正确率很低。

组合标注器

前面我们对查询标注器设置了一个回退标注器(默认标注器),事实上大部分的NLTK标注器都可以设置回退标注器,这样我们就可以把二元标注器、一元标注器、默认标注器组合起来得到一个组合标注器,例如我们可以按照下列方式组合:

尝试使用bigram标注器标注单词。

如果bigram标注器无法找到一个标记,尝试unigram标注器。

如果unigram标注器无法找到一个标记,使用默认标注器。

代码如下:

import nltk

from nltk.corpus import brown

# 划分训练集和测试集

tagged_sents = brown.tagged_sents(categories='news')

size = int(len(tagged_sents) * 0.9)

train_sets = tagged_sents[:size]

test_sets = tagged_sents[size:]

# 训练标注器,并把它们组合起来

t0 = nltk.DefaultTagger('NN')

t1 = nltk.UnigramTagger(train=train_sets, backoff=t0)

t2 = nltk.BigramTagger(train=train_sets, backoff=t1)

# 查看标注器性能

print(t2.evaluate(train_sets))

print(t2.evaluate(test_sets))

结果为:

0.9735641453364413

0.8459085019435861

从结果我们可以看到相比于一元标注器,我们的组合标注器还是有提高的。

总结

TaggerI::tag(tokens):对指定的单词列表进行标记,返回被标记后的单词列表

TaggerI::evaluete(tagged_sents):使用已经被标记的句子评价标注器,返回正确率0~1.0

DefaultTagger, UnigramTagger, BigramTagger都继承至TaggerI

DefaultTagger

默认标注器的构造函数接受一个标记作为参数,生成标注器

UnigramTagger

一元标注器接受被标记的句子列表作为参数,生成标注器

BigramTagger

二元标注器接受被标记的句子列表作为参数,生成标注器

其他章节链接

Python NLTK学习6(创建词性标注器)

python学到哪知道baseline_Python NLTK学习6(创建词性标注器)相关推荐

  1. python学什么方向就业好_学习python就业方向都有哪些?

    谢邀 我在学习的过程中,深深的觉得对于成人或者进入职场的人来说,学习一门新的知识,目的不在于积累,而在于解决问题. 所以这就要求我想明白3个问题: 1).学习python,要解决什么问题? 2).要学 ...

  2. python学了真的很有用吗-学习Python真的有必要参加培训吗?老男孩Python学习机构...

    零基础学习Python真的能学会吗?我想很多人都具有这样的疑问吧.其实Python是非常适合初学者入门学习的编程语言,相比较其他主流的编程语言来说,可读性高,上手容易.而且Python具有非常丰富的库 ...

  3. python学哪个版本-我现在应该学习哪个版本的Python?哪个方向更好?

    Python是一种非常高级的编程语言. 该语言适合基于初学者的学习. 这也是初学者的首选. 现在无论是从事人工智能还是爬行动物Python,它都具有非常重要的作用,并且现在已经成为非常重要的编程. 语 ...

  4. python学了基础之后方向_学习了解python基础后,该进去哪一个方向呢?

    想利用Python赚一点外快,首先就要了解的是Python在什么地方可以赚到钱.可以先看下文,题主根据自己想做的事情,再深入的学习Python相关知识. Python自由职业可以做什么: 1.爬虫 首 ...

  5. NLTK学习笔记(五):分类和标注词汇

    目录 词性标注器 标注语料库 表示已经标注的标识符:nltk.tag.str2tuple('word/类型') 读取已经标注的语料库 名词.动词.形容词等 尝试找出每个名词类型中最频繁的名词 探索已经 ...

  6. 编程入门python语言是多大孩子学的-我的孩子需要学习Python吗?几岁开始学?有什么书籍推荐?...

    原标题:我的孩子需要学习Python吗?几岁开始学?有什么书籍推荐? 最近有一些家长问我,需不需要让孩子学习Python,孩子学习Python有什么作用? 最近确实有看到不少的机构在宣传Python, ...

  7. python学起来难吗-Python入门学习难吗,新手如何学习

    无论是学习什么,要入门学习,肯定是需要经过一番努力的,更何况还是一种编程语言呢. 其实,我认为在学习python编程的中,可能最重要的就是兴趣,这是持续学习的原始动力,而只有持续学习才能真正学会pyt ...

  8. 小白学python买什么书-小白如何高效率学习python?真心建议(附教程)

    IT 行业的变化快是众人皆知的,需要持续去学习新的知识内容.但是,往往我们工作之后,经常发现学习的东西很少了,学习效率非常低,感觉自己到了一个瓶颈期,久而久之,就演变成『一年工作经验,重复去用十年』的 ...

  9. 怎么学python知乎_你是怎么学习Python的 ?

    大家不要看到这个文章的题目,就认为这是一篇广告软文.然而并不是,因为我看到了很多同行都被大数据.人工智能的热潮吸引了,开始纷纷学习python.这是好事,但看到了好多人都走了不少弯路,浪费了时间.于是 ...

最新文章

  1. 聊聊spring cloud gateway的PreserveHostHeaderGatewayFilter
  2. python 字符串 数字_Python基础教程:数字、字符串
  3. VS高版本编写C程序的C4996错误
  4. ni软件管理器_NI 技术支持丨我的 NI 硬件设备不能被识别,怎么办?Windows
  5. Net设计模式实例之装饰者模式(Decorator Pattern)(1)
  6. SSE指令集学习之旅(一)
  7. jquery 筛选元素 (3)
  8. vba 窗体单选框怎么传回sub_EXCEL表格VBA中函数的日常使用
  9. 深度学习2.0-18.随机梯度下降之手写数字问题实战(层)
  10. 跨域——vue中的axios.post使用json数据传输,出现请求头字段内容类型是不被允许的情况的解决方案
  11. 多文档文本编辑器(Qt)
  12. 地图开发中用到的比例尺和分辨率
  13. 一步步的教你安装UChome (UChome 安装教程)
  14. 【Git】675- 让你的 commit 更有价值
  15. AutoCAD 系统变量
  16. IOS微信后台运行时候倒计时暂停问题
  17. 求个单片机控制双向可控硅调光电路电压220V
  18. GrabCut算法、物体显著性检测
  19. mod_rewrite htaccess 简单使用
  20. 鸿蒙系统与麒麟os,华为鸿蒙系统改名为麒麟OS

热门文章

  1. 国家计算机科学进展,主动网络安全的研究与进展
  2. python list中的append 与 extended 的区别
  3. jconsole命令 Java Monitoring and Management Console
  4. Hadoop入门进阶步步高(三-配置Hadoop
  5. Python案例:求转置矩阵
  6. php jquery ajax xml,jquery Ajax解析XML数据代码实例
  7. java加载图片白屏,tomcat白屏~
  8. mysql中的lgwr_MySQL Replication和Oracle logical standby的原理对比
  9. 【英语学习】【Level 07】U03 Amazing wonders L4 The Qin Dynasty legacy
  10. 数据结构中为什么输入数据还没输入完全就结束了_我岂能忍!面试官居然用数据结构和算法“羞辱”我...