python之获得文本语料和词汇资源(3)

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))