如何进行词汇标注呢?首先进行数据预处理,例如如果给定的是句子,先要对句子进行分割;最简单的标注器,可以给定词汇使用得最频繁的词性作为标注器中该词汇的词性,但是由于词汇存在二义性,使得这种标注准确度受限,通过上下文语境,可以在一定程度上解决这个问题,可以采用N-gram标注器,此外,Brill标注器具有修正功能。
为了使python的中文注释正确,必须在开头加上一句代码
# -*- coding: utf-8 -*-
# 这个编码转换必须放在第一行,否则中文注释会报错
将词汇按它们的词性(parts-of-speech,POS)分类以及相应的标注它们的过程被称为词性标注(part-of-speech tagging, POS tagging)。
利用NLTP,可以比较方便地进行词性标注。
为了对词汇进行标注,我们需要把句子进行分割,之后可以使用nltk的词性标注器进行标注。
# 使用词性标注器
text=nltk.word_tokenize("And now for something completely different")
nltk.pos_tag(text)
NLTK中对数据进行预处理
# str2tuple()从表示一个已标注的标识符的标准字符串创建一个这样的特殊元组
tagged_token=nltk.tag.str2tuple('fly/NN')
# text.similar()方法为一个词w 找出所有上下文w1ww2,然后找出所有出现在相同上下文中的词w',即w1w'w2
text=nltk.Text(word.lower() for word in nltk.corpus.brown.words())
text.similar('woman')
# 读取已标注语料库
# 常用语料库 brown, nps_chat, conll2000, treebank,
nltk.corpus.brown.tagged_words()
from nltk.corpus import brown
brown_news_tagged=brown.tagged_words(categories='news')
tag_fd=nltk.FreqDist(tag for (word, tag) in brown_news_tagged)
tag_fd.keys()[:5]
# 找出最频繁的名词标记
def findtags(tag_prefix, tagged_text):
cfd=nltk.ConditionalFreqDist((tag,word) for (word,tag) in tagged_text
if tag.startswith(tag_prefix))
return dict((tag, cfd[tag].keys()[:5]) for tag in cfd.conditions())
# 查看跟在ofen后的词汇
brown_learned_text=nltk.corpus.brown.words(categories='learned')
sorted(set(b for(a,b) in nltk.bigrams(brown_learned_text) if a=='often'))
# 使用POS标记寻找三词短语
from nltk.corpus import brown
def process(sentence):
for (w1,t1),(w2,t2),(w3,t3) in nltk.trigrams(sentence):
if (t1.startswith('V') and t2=='TO' and t3.startswith('V')):
print w1,w2,w3
# 查看标记模糊的词
brown_news_tagged = brown.tagged_words(categories='news')
data=nltk.ConditionalFreqDist((word.lower(),tag) for (word,tag) in brown_news_tagged)
for word in data.conditions():
if len(data[word])>=3:
tags=data[word].keys()
print word,' '.join(tags)
'''
使用Python字典映射词及其属性 pos['键']='值',字典不是序列,键没有固定顺序,
定义字典:pos={'A':'a','B':'b'}或pos=dict(A='a',B='b')
使用for循环遍历字典中的键:for word in sorte(dict)
字典的常用方法。keys(), values(), items(): for key,val in sorted(dict.items()),update(), append()
字典的键必须是不可改变的类型,如字符串或元组
'''
# 递增的更新字典
counts=nltk.defaultdict(int)
from nltk.corpus import brown
for (word,tag) in brown.tagged_words(categories='news'):
counts[tag]+=1
from operator import itemgetter
sorted(counts.items(), key=itemgetter(1),reverse=True) #按照值递减排序
# 如果经常用到反向查找,可以建立一个值到键的字典
标注器 二义性限制了标注器的上限,上下文可以解决歧义问题
N-gram标注 利用了上下文中的词作为特征,有点像开环的,没有反馈
Brill标注 归纳标注法 猜测每个词的标注,然后返回和修复错误,有点像闭环,有返回,不对修正错误
# NLTK数据加载
from nltk.corpus. import brown
brown_tagged_sents=brown.tagged_sents(categories='news') #加载已标注句子
brown_sents=brown.sents(categories='news') #加载句子
# 正则表达式标注器
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')
]
regexp_tagger=nltk.RegexpTagger(patterns)
regexp_tagger.tag(brown_sents[3])
#查询标注器
fd = nltk.FreqDist(brown.words(categories='news')) #词汇的频率统计
cfd = nltk.ConditionalFreqDist(brown.tagged_words(categories='news')) #词汇的条件分布,该词的词性的统计
most_freq_words = fd.keys()[:100] #前100个高频词
likely_tags = dict((word, cfd[word].max()) for word in most_freq_words) #前100个高频词,以及高频词的最可能的词性标注
baseline_tagger = nltk.UnigramTagger(model=likely_tags)
# 回退
baseline_tagger = nltk.UnigramTagger(model=likely_tags, backoff=nltk.DefaultTagger('NN'))
# N-gram标注
from nltk.corpus import brown
brown_tagged_sents = brown.tagged_sents(categories='news')
brown_sents = brown.sents(categories='news')
unigram_tagger = nltk.UnigramTagger(brown_tagged_sents) # 通过已经标注的句子训练一个一元标注器
unigram_tagger.tag(brown_sents[2007]) # 使用这个一元标注器标注未进行标注的句子
bigram_tagger.evaluate(test_sents) # 用于评估
# 组合标注器:解决精度和覆盖范围的一个权衡办法
t0=nltk.DefaultTagger('NN')
t1=nltk.UnigramTagger(train_sents,backoff=t0)
t2=nltk.BigramTagger(train_sents,backoff=t1)
t2.evaluate(test_sents) # 先调用t2的bigram标注器标注,找不到就尝试t1,再不行就用默认标注器t0
nltk.BigramTagger(sents,cutoff=2,backoff=t1) # 丢弃只出现一两次的上下文
# 存储标注器给以后使用
from cPickle import dump
output=open('t2.pkl','wb')
dump(t2,output,-1) #将t2标注器写到output,可以用方法的形式 p=cPickle.dump(t2)
output.close()
from cPickle import load
input=open('t2.pkl','rb')
tagger=load(input)
# brill标注器演示 基于转换的标注学习一系列“改变标记s 为标记t 在上下文c 中”形式的修复规则
nltk.tag.brill.demo()
一直以来都没有写博客的习惯,从今天开始,要改变自己。