2.2条件频率分布
条件频率分布是频率分布的集合,每个频率分布有一个不同的条件。这个条件通常是文本的类别。当预料分为几类时,可以计算每个类别独立的领率分布。就可以研究类别之间的系统性差异。
2.2.1按照文本计数词汇
import nltk
from nltk.corpus import brown
cfd = nltk.ConditionalFreqDist(
(genre,word)
for genre in brown.categories()
for word in brown.words(categories = genre)
)
#对于每个问题,遍历文体中的每个词以产生文体与词的配对
genre_word = [(genre,word)
for genre in ['news','romance']
for word in brown.words(categories = genre)]
print(len(genre_word)) #一共产生了多少配对
print(genre_word[:4]) #news与word的配对
print(genre_word[-4:]) #romance与word的配对
cfd = nltk.ConditionalFreqDist(genre_word)
print(cfd) #确认有两个条件
print(cfd.conditions()) #输出具体的两个条件是什么
print(cfd['news'])
print(cfd['romance'])
print(list(cfd['romance']))
print(cfd['romance']['could'])
2.2.2绘制分布图和分布表
ConditionalFreqDist除了提供组合两个或两个以上的频率分布及更容易初始化功能之外,还提供了制表和绘图的功能
例1:绘制分布图
import nltk
form nltk.corpus import inaugural
cfd = nttk.ConditionalFreqDist(
(target,fileid[:4])
for fileid in inaugural.fileids()
for w in inaugural.words(fileid)
for target in ['america','citizen']
if w.lower().startswith(target)
)
cfd.plot
例2:绘制分布表
import nltk
from nltk.corpus import udhr
languages = ['Chickasaw','English','German_Deutsch',
'Greenlandic_Inuktikut','Hungarian_Magyar','Ibibio_Efik']
cfd = nltk.ConditionalFreqDist(
(lang,len(word))
for lang in languages
for word in udhr.words(lang + '-Latin1')
)
cfd.tabulate(conditions = ['English','German_Deutsch'],
samples = range(10),cumulative = True)
2.2.3使用双连词生成随机文本
sent = ['In','the','beginning','God','created','the','heaven','and','the','earth','.']
print(nltk.bigrams(sent)) #建立了一个连续的词对链表
例3:产生随机文本:将每个词作为一个条件,对于每个词都有效的依据后续词的创建频率分布
generate_model()函数包含简单的循环以生成文本
import nltk
def generate_model(cfdist,word,num=15):
for i in range(num):
print(word)
word = cfdist[word].max() #重新设置word为上下文中最可能的标识符
text = nltk.corpus.genesis.words('english-kjv.txt')
bigrams = nltk.bigrams(text) # 计算该text中的双连词
cfd = nltk.ConditonalFreqDist(bigrams)
print(cfd['living']) #输出living上下文最可能出现单词的频率
print(generate_model(cfd,'living')) #输出living最可能出现的上下文的一句话
2.3代码重用
2.3.1文本编辑器
2.3.2Python函数
函数是指带命名的代码块,可执行一些明确的任务。
函数通常使用称为参数的变量进行输入,并且可能会生成一些结果,也称为返回值。
例1:
from nltk.book import*
def lexical_diversity(text):
return(len(text)/len(set(text)))
print(lexical_diversity(text1))
例2:以下函数试图生成任意英语名词的复数形式。
def plural(word):
if word.endswith('y'):
return word[:-1] +'ies'
elif word[-1] in 'sx' or word[-2:] in ['sh','ch']:
return word +'es'
elif word.endswith('an'):
return word[:-2] + 'en'
else:
return word + 's'
print(plural('fairy'))
print(plural('woman'))
2.3.3模块
一个文件中的变量和函数定义的集合被称为Python模块。相关模块的集合称为包。处理布朗语料库的NLTK代码是模块,处理各种不同语料库的代码的集合是包。NLTK的本身是包的集合,有时被称为库。
2.4词典资源
词典或者词典资源是一个词和/或短语及其相关信息的集合。
2.4.1.词汇列表语料库
仅仅包含列表的语料库。词汇预料库是UNIX中的/usr/dict/words文件,被一些拼写检查程序所使用,我们可以用它来寻找文本语料中不常见的或拼写错误的词汇。
例1:过滤文本:计算文本的词汇表,然后删除所有在现有的词汇列表中出现的元素,只留下罕见的或拼写错误的词汇
import nltk
from nltk.corpus import gutenberg
def unusual_words(text):
text_vocab = set(w.lower() for w in text if w.isalpha())
english_vocab = set(w.lower() for w in nltk.corpus.words.words())
unusual = text_vocab.difference(english_vocab) #差集,相当于text_vocab-english_vocab
return sorted(unusual)
print(unusual_words(nltk.corpus.gutenberg.words('austen-sense.txt')))
print(unuaual_words(nltk.corpus.nps_chat.words()))
2.4.2停用词语料库
import nltk
from nltk.corpus import stopwords
print(stopwords.words('english'))
例1:定义一个函数来计算文本中不包含在停用词列表中的词所占的比例
import nltk
form nltk.corpus import stopwords
def content_fraction_fraction(text):
stopwords = nltk.corpus.stopwords.words('english')
content = [w for w in text if w.lower() not in stopwords]
return len(content)/len(text)
print(content_fraction(nltk.corpus.reuters.words()))
例子2:猜字谜
import nltk
puzzle_letters =nltk.FreqDist('egivrvonl')
obligatory = 'r'
wordlist = nltk.corpus.words.words()
print([w for w n wordlist if len(w) > = 6
and obligatory in w
and nltk.FreqDist(w) <= puzzle_letters])
例子3:名字语料库
import nltk
names = nltk.corpus.names
print(names.fileids())
male_names = names.wprds('male.txt')
female_names = names.words('female.txt')
print([ w for w in male_names if w in female_names]) #即存在男性名字的语料库中又存在女性名字的语料库中
cfd =nltk.ConditionalFreqDist(
(fileid,name[-1])
for fileid in names.fileids()
for name in names.words(fileid))
cfd.plot() #男性或女性的名字的最后一个字母的差异情况
2.4.3发音的词典
表格(或电子表格)是一种略微丰富的词典资源,在每一行中含有一个词及其一些性质。nltk中包含美国英语的CMU发音词典,它是语音合成器而设计的。
import nltk
entries = nltk.corpus.cmudict.entries()
print(len(entries))
for entry in entries[39943:39951]:
print(entry)
每个条目由两部分,所以用两个变量名word和pron替换了entry。
import nltk
entries = nltk.corpus.cmudict.entries()
for word,pron in entries:
if len(pron) == 3:
ph1,ph2,ph3 = pron
if ph1 == 'P' and ph3 == 'T':
print(word,ph2)
例1:定义函数提取重音数字
主重音(1) 次重音(2) 无重音(0)
import nltk
entries = nltk.corpus.cmudict.entries()
def stress(pron):
return [char for phone in pron for char in phone if char.isdigit()]
print([w for w,pron in entries if stress(pron) == ['0','1','0','2','0']])
例2:寻找相应词汇的最小对比集,找到所有p开头的三音素词,并按照他们的第一个和最后一个因素来分组。
import nltk
entries = nltk.corpus.cmudict.entries()
p3 = [(pron[0]+'-'+pron[2],word) #要找第一个因素和第三个因素的单词
for(word,pron) in entries
if pron[0] == 'P' and len(pron) == 3] #第一个因素为p且该词的长度为3
cfd = nltk.ConditionalFreqDist(p3)
for template in cfd.conditions():
if len(cfd[template]) > 10:
words = cfd[template].keys()
wordlist = ' '.join(words)
print(template,wordlist[:70]+'....')
例3:通过字典的名字以及后面带方括号的关键字来查词典
prondict = nltk.corpus.cmudict.dict()
print(prondict[‘fire’])
print(prondict[‘blog’])
prondict[‘blog’] = [[‘B’,‘L’,‘AA1’,‘G’]]
ptint(prondict[‘blog’])
2.4.5比较词表
from nltk.corpus import swadesh
print(swadesh.fileids())
print(swadesh.words('en'))
fr2en = swadesh.entries(['fr','en']) # entries()指定一个语言链表来访问多语言中的同源词
print(fr2en)
translate = dict(fr2en)
print(translate['chien'])
print(translate['jeter'])
2.4.6词汇工具:Toolbox和Shoebox
Toolbox文件由一些条目的集合组成,其中每个条目由一个或多个字段组成。大多数字段都是可选的或重复的,这意味着这个词汇资源不能作为一个表格或者电子表格来处理。
from nltk.corpus import toolbox
print(toolbox.entries('rotokas.dic'))
2.5 wordnet
2.5.1意义与同义词
from nltk.corpus import wordnet as wn
print(wn.synsets('motorcar')) # car的第一个名词意义
res1 = wn.synset('car.n.01').definition() #car的含义
print(res1)
res2 = wn.synset('car.n.01').examples() #car的例句
print(res2)
res3 = wn.synset('car.n.01').lemmas() # 得到指定同义词集的所有词条。
print(res3)
res = wn.lemma('car.n.01.automobile')
print(res)
res4 = wn.lemma('car.n.01.automobile').synset()
print(res4)
res5 = wn.lemma('car.n.01.automobile').name()
print(res5)
2.5.2wordnet 的层次结构
下位词
motorcar = wn.synset('car.n.01')
types_of_motorcar = motorcar.hyponyms()
res = sorted([lemma.name() for synset in types_of_motorcar for lemma in synset.lemmas()])
print(res)
上位词
print(motorcar.hypernyms())
paths = motorcar.hypernym_paths()
print(len(paths))
print([synset.name for synset in paths[0]])
print([synset.name() for synset in paths[0]])
print([synset.name() for synset in paths[1]])
print(motorcar.root_hypernyms())
member_holonyms() 从条目到它们的部件(部分)或到包含他们的东西(整体)
例如,一棵树可以成树干、树冠等部分,这些都是part_meronyms(),一棵树的实质是由心材和边材组成的,substance_meronyms()
树木的集合形成了森林,即member_holonyms()
print(wn.synset('tree.n.01').part_meronyms())
print(wn.synset('tree.n.01').substance_meronyms())
print(wn.synset('tree.n.01').member_holonyms())
for synset in wn.synsets('mint',wn.NOUN):
print(synset.name() + ':',synset.definition())
print(wn.synset('mint.n.04').part_holonyms())
print(wn.synset('mint.n.04').substance_holonyms())
蕴涵关系
print(wn.synset('walk.v.01').entailments())
print(wn.synset('eat.v.01').entailments())
print(wn.synset('tease.v.03').entailments())
反义词
print(wn.lemma('supply.n.02.supply').antonyms())
print(wn.lemma('rush.v.01.rush').antonyms())
print(wn.lemma('horizontal.a.01.horizontal').antonyms())
print(wn.lemma('staccato.r.01.staccato').antonyms())
使用dir查看词汇关系和同义词集上定义的其他方法
print(dir(wn.synset('harmony.n.02')))
2.5.3语义相似度’
right = wn.synset('right_whale.n.01')
orca = wn.synset('orca.n.01')
minke = wn.synset('minke_whale.n.01')
tortoise = wn.synset('tortoise.n.01')
novel = wn.synset('novel.n.01')
print(right.lowest_common_hypernyms(minke))
print(right.lowest_common_hypernyms(orca))
print(right.lowest_common_hypernyms(tortoise))
print(right.lowest_common_hypernyms(novel))
print(wn.synset('baleen_whale.n.01').min_depth())
print(wn.synset('whale.n.02').min_depth())
print(wn.synset('vertebrate.n.01').min_depth())
print(wn.synset('entity.n.01').min_depth())
print(right.path_similarity(minke))
print(right.path_similarity(orca))
print(right.path_similarity(tortoise))
print(right.path_similarity(novel))