词性标注

作者: 青椒rose炒饭 | 来源:发表于2019-07-02 15:54 被阅读0次

三个标注器:默认标注器、正则表达式标注器和查询标注器。前面先进行简单介绍,后面再贴代码吧。

默认标注器

通过已经标注的文本获取其中出现最多的标签,然后待标注的文本都标注为这个标签。标注的结果什么样的都行。最好字典吧{单词:属性}
可以先自己尝试一下,获取已经标注过的句子brown.tagged_sents(categories='news')获取布朗语料库中已经标注的句子,分类是新闻类。
标注器对象:nltk.DefaultTagger(tag),调用该对象的tag( )方法对单词进行标注,所有的单词都会标注成tag。

正则表达式标注器

在一定单词知识的基础之上,识别单词,如以 ‘s 结尾的单词为名词所有格,以ed结尾的都看做过去式等等之类的。将所有正则表达式都组合成模式串,作为正则表达式标注器的参数。

patterns = [
    (r'.*ing$',"VBG"),
    (r'.*ed$',"VBD"),
    (r'.*es$',"VBZ"),
    (r'.*ould$',"MD"),
    (r'.*\'s$',"NN"),
    (r'.*s$',"NNS"),
    (r'^-?[0-9]+(.[0-9]+)?$',"CD"),
    (r'.*',"NN")  #匹配所有单词,默认标注为NN
]

调用正则标注器 nltk.RegexpTagger(模式串),创建一个标注对象,调用该对象的tag()方法对单词进行标注,单词必须切分好。

查询标注器

通过已经标注的语料,使用频率分布得到出现频率高的单词,然后通过条件频率分布获得该单词最多的词性标注,构建这些单词和标签的字典作为参数新建查询标注器。构建查询标注器:nltk.UnigramTagger(model=likely_tags),此方法还有一个比较重要的参数:backoff值可以是前面两种标注器的对象,当查询标注器遇到没有在model字典的单词,如果backoff咩有值就标注为None,如果有值(模型),就调用这个标注器进行标注,能够提高很多正确率。


下面是这三个模型代码:

import nltk
from nltk.corpus import brown
brown_tagged_sents = brown.tagged_sents(categories='news')
brown_sents = brown.sents(categories='news')

print("布朗语料库中已经标注的句子",brown_tagged_sents)
print("没有标注的句子",brown_sents)
#******************************************************************************
#默认标注器
#获取文章中所有的标记
tags = [tag for (word,tag) in brown.tagged_words(categories='news')]
tag_fd = nltk.FreqDist(tags)
max_tag = tag_fd.max()
print("出现最多的标记:",max_tag)
#标注之前可以将大部分的单词都初始化为使用最多的标记
#简要标注一个文本,标注的形式就是字典
default_tagger = nltk.DefaultTagger(max_tag)
words = "hello world hello python".split()
word_tagged = default_tagger.tag(words)
print("默认标注器标注效果",word_tagged)
#标注的效果并不是很好,大部分都是错误的
#********************************************************************************

#正则表达式标注器
#正则表达式模式串
patterns = [
    (r'.*ing$',"VBG"),
    (r'.*ed$',"VBD"),
    (r'.*es$',"VBZ"),
    (r'.*ould$',"MD"),
    (r'.*\'s$',"NN"),
    (r'.*s$',"NNS"),
    (r'^-?[0-9]+(.[0-9]+)?$',"CD"),
    (r'.*',"NN")
]
#我自己来编造一个和正则表达式差不多的文本吧
words = "I heated Tom's oranges it is't interesting ".split()
#创建一个正则表达式的标注器
reg_tagger = nltk.RegexpTagger(patterns)
word_tagged = reg_tagger.tag(words)
print("正则表达式标注器标注效果",word_tagged)

#新的标注器比上一个好一些了,但是需要编写的正则表达式也变多了

#********************************************************************************
#查询标注器 --- 据说是能够正确标注一半左右
#找出100个最频繁的词,存储他们的标记,然后使用这个信息作为查找标注器的模型
#获取未标注单词的频率
fd = nltk.FreqDist(brown.words(categories='news'))
#获取已经标注的单词的频率分布
cfd = nltk.ConditionalFreqDist(brown.tagged_words(categories="news"))
most_freq_words = list(fd.keys())[:100]
#下面这句在最高频率单词的情况下,获取该单词使用最多的词性
likely_tags = dict((word,cfd[word].max()) for word in most_freq_words)
baseline_tagger = nltk.UnigramTagger(model=likely_tags)
print("正确率评估",baseline_tagger.evaluate(brown_tagged_sents))
#上面这个只能标注在100个高频词里面的词,其他的词会被分配一个None标签
#我们需要在它不能标注的时候使用正则表达式标注
print("联合标记",baseline_tagger.tag(words))
baseline_tagger = nltk.UnigramTagger(model=likely_tags,backoff=reg_tagger)
print("联合标记回退使用了正则标记:",baseline_tagger.tag(words))
print("正确率评估",baseline_tagger.evaluate(brown_tagged_sents))
运行结果

查询标注模型性能的评估

import nltk
from nltk.corpus import brown
def performance(cfd,wordlist):
    lt = dict((word,cfd[word].max()) for word in wordlist)
    basline_tagger = nltk.UnigramTagger(model=lt,backoff=nltk.DefaultTagger("NN"))
    return basline_tagger.evaluate(brown.tagged_sents(categories="news"))

def display():
    import pylab
    word_by_freq = list(nltk.FreqDist(brown.words(categories="news")))
    cfd = nltk.ConditionalFreqDist(brown.tagged_words(categories="news"))
    sizes = [2 ** i for i in range(15)]
    perfs = [performance(cfd,word_by_freq[:size]) for size in sizes]
    pylab.plot(sizes,perfs,'-bo')
    pylab.show()

display()
准确率随高频样本集的变化

随着高频率样本集的增多,标注的准确率也得到了很大提高,主要原因是,后面继续增加的词在文本中的频率越来越小。所以曲线增式变缓,由于前面的高频部分将一词多种词性这种情况标注为出现次数最多的频率,所以准确率是不可能等于1的。

相关文章

  • 自然语言处理——7.8 词性标注方法

    · 基于规则的词性标注方法· 基于统计模型的词性标注方法· 规则和统计方法相结合的词性标注方法· 基于有限状态变换...

  • 词性标注

    词性标注,用jieba.possege做带有词性分类的分词,并用pandas做数据结构化展示 导入库 import...

  • 词性标注

    关于词性标注歧义问题,对Brown语料库进行统计,按歧义程度排列的词型数目(The number of word ...

  • 词性标注

    三个标注器:默认标注器、正则表达式标注器和查询标注器。前面先进行简单介绍,后面再贴代码吧。 默认标注器 通过已经标...

  • NLTK之词性(POS)标注

    词性(POS),目前最先进的词性标注算法在预测给定单词的词性上已经有了较高的精确度(约97%),但词性标注领域中仍...

  • NLP 的词性标注技术 Jieba

    本文主要来介绍 NLP 中的词性标注。词性是词汇基本的语法属性,通常也称为词类。词性标注是在给定句子中,判定每个词...

  • 自然语言处理之词性标注

    什么是词性标注 在介绍词性标注前,首先需要先了解一下什么是词性。 我们知道,词类的划分其实是具有层次性的。如在汉语...

  • 词性标注调研

    原文引用 http://heshenghuan.github.io/2016/03/23/词性标注调研/ 定义 词...

  • nltk词性标注中的词性

    nltk是一个高效的python构建的平台,用来处理人类自然语言数据。它提供了易于使用的接口,通过这些接口可以访问...

  • 使用词性标注器

    一个词性标注器处理一个词序列,为每个词增加一个词性标注(part-of-speech tagger 或者 POS ...

网友评论

    本文标题:词性标注

    本文链接:https://www.haomeiwen.com/subject/hapzcctx.html