之前大家也肯定学过名字、动词、形容词、副词之间的差异,这些词类不是闲置的,而是对许多语言处理任务都有用的分类,正如我们将看到的,这些分类源于对文本中词的分布的简单的分析。
将词汇按照他们的词性(POS)分类以及相应的标注它们的过程被称作为词性标注(POS tagging),简称为标注。词性也被称为词类或词汇范畴。用于特定任务的标记的集合被称为一个标记集,我们本章的重点是利用标记和自动标注文本。
使用词性标注器:
import nltk
text=nltk.word_tokenize("customer found there are abnormal issue")
print(nltk.pos_tag(text))
然后。。报错了
需要再运行nltk.download进行下载,并将文件拷贝到前面错误提示的搜索路径中去。
lang time:
输出结果:[(‘customer’, ‘NN’), (‘found’, ‘VBD’), (‘there’, ‘EX’), (‘are’, ‘VBP’), (‘abnormal’, ‘JJ’), (‘issue’, ‘NN’)]
在这里得到了每个词以及每个词的词性。下表是一个简化的词性标记集
标注语料库
表示已经标注的标识符:nltk.tag.str2tuple('word/类型')
按照NKTL的约定,一个已标注的biao标识符使用一个由标识符和标记组成的元祖来表示,我们可以使用函数 str2tuple()从表示一个已标注的标识符的标准字符串创建一个这样的特殊元祖:
tagged_token = nltk.tag.str2tuple('fly/NN')
print(tagged_token)
输出为 (‘fly’, ‘NN’)
我们可以从一个字符串构造一个已标注的标识符的链表,第一步是对字符串分词以便能访问单独的词/标记字符串,然后将每一个转换成一个元祖(使用str2tuple())
设:sent = “” xxxxxxx…xxxxxxxxxxxxxx “”
print([nltk.tag.str2tulpe(t) for t in sent.split()])
.
.
读取已经标记的语料库
NLTK语料库提供了统一接口,可以不必理会不同的文件格式。
格式: 语料库.tagged_word()/tagged_sents()
。参数可以指定categories和fields
print(nltk.corpus.brown.tagged_words())
输出:[(‘The’, ‘AT’), (‘Fulton’, ‘NP-TL’), …]
.
.
简化的词性标记集
已标注的语料库使用许多不同的标记集约定来标注词汇。为了帮助我们开始,我们将看到一个一个简化的标记集。
那我们来看下这些标记中那些是布朗语料库的新闻中常见的:
brown_news_tagged = nltk.corpus.brown.tagged_words()
tag_fd = nltk.FreqDist(tag for (word,tag) in brown_news_tagged)
print(tag_fd.keys())
输出: dict_keys([‘AT’, ‘NP-TL’, ‘NN-TL’, ‘JJ-TL’, ‘VBD’,…‘PN+HVD’, ‘FW-UH-TL’])
.
.
名词、动词、形容词等
再啰嗦一下,
名词一般指的是人,地点,事情或者是概念,例如:女人,苏格兰,图书,情报等。名称可能出现在限定词和形容词之后,可以是动词或者是主语或宾语。
动词是用来描述事件和形容的词。
形容词修饰名词,可以作为修饰符或者谓语。
副词修饰动词,指定时间方式地点或动词描述的时件的方向。
这里以名词为例:
from nltk.corpus import brown
import nltk
word_tag = nltk.FreqDist(brown.tagged_words(categories="news"))
print([word+'/'+tag for (word,tag)in word_tag if tag.startswith('V')])
#下面是查找money的不同标注
wsj = brown.tagged_words(categories="news")
cfd = nltk.ConditionalFreqDist(wsj)
print(cfd['money'].keys())
尝试找出每个名词类型中最频繁的名词
def findtag(tag_prefix,tagged_text):
cfd = nltk.ConditionalFreqDist((tag,word) for (word,tag) in tagged_text if tag.startswith(tag_prefix))
return dict((tag,list(cfd[tag].keys())[:5]) for tag in cfd.conditions())#数据类型必须转换为list才能进行切片操作
tagdict = findtag('NN',nltk.corpus.brown.tagged_words(categories="news"))
for tag in sorted(tagdict):
print(tag,tagdict[tag])
探索已经标注的语料库
需要nltk.bigrams()和nltk.trigrams(),分别对应2-gram模型和3-gram模型。
brown_tagged = brown.tagged_words(categories="learned")
tags = [b[1] for (a,b) in nltk.bigrams(brown_tagged) if a[0]=="often"]
fd = nltk.FreqDist(tags)
fd.tabulate()
自动标注
最简单的标注器是为每个标识符分配统一标记。下面就是一个将所有词都变成NN的标注器。并且用evaluate()进行检验。当很多词语是名词时候,它有利于第一次分析并提高稳定性。
raw = 'I do not like eggs and ham, I do not like them Sam I am'
tokens = nltk.word_tokenize(raw)
default_tagger = nltk.DefaultTagger('NN')#创建标注器
print(default_tagger.tag(tokens)) # 调用tag()方法进行标注
print(default_tagger.evaluate(brown_tagged_sents))
正则表达式标注器
注意这里规则是固定(由自己决定)。当规则越来越完善的时候,精确度越高。
patterns = [
(r'.*ing$','VBG'),
(r'.*ed$','VBD'),
(r'.*es$','VBZ'),
(r'.*','NN')#为了方便,只有少量规则]
regexp_tagger = nltk.RegexpTagger(patterns)
regexp_tagger.evaluate(brown_tagged_sents)
查询标注器
查询标注器就是存储最有可能的标记,并且可以设置backoff参数,不能标记的情况下,就使用这个标注器(这个过程是回退)
fd = nltk.FreqDist(brown.words(categories="news"))
cfd = nltk.ConditionalFreqDist(brown.tagged_words(categories="news"))
most_freq_words = fd.most_common(100)
likely_tags = dict((word,cfd[word].max()) for (word,times) in most_freq_words)
baseline_tagger = nltk.UnigramTagger(model=likely_tags,backoff=nltk.DefaultTagger('NN'))