自然语言处理2.2——条件频率分布
前面我们学习过使用FreqDist(textlist)函数来计算textlist链表中每个项目出现的次数,现在我们推广这一想法。
当语料文本分为几类(文体、主题、作者)时,可以计算每个类别独立的频率分布,这样就可以研究类别之间的系统性差异。——nltk.ConditionalFreqDist来实现、
条件频率分布是频率分布的集合,每个频率分布有一个不同的‘条件’(通常为文本的类别)——(条件,事件)的形式。如果我们按照问题处理整个布朗语料库,将得到15个条件(一个文体一个条件)和1161192个事件(一个词一个事件)
【按文体计数词汇】
>>>from nltk.corpus import brown >>>cfd=nltk.ConditionalFreqDist((genre,word) for genre in brown.categories() for word in brown.words(categories=genre) )
上面两行代码就是对brown语料库按照问题进行统计单词的数量,我们也可以只看部分问题,例如:新闻和言情。
>>>genre_word=[(genre,word) for genre in ['news','romance'] for word in brown.words(categories=genre)]
>>>len(genre_word)
170576
上面生成的genre_word前面配对会是('news',word)的形式,而后面会是('romance',word)的形式
现在我们就可以对此链表创建一个ConditionalFreqDist:
>>>cfd=nltk.ConditionalFreqDist(genre_word) >>>cfd.conditions() ['news','romance']
这两个条件他们每一个只有一个频率分布。要访问某个条件的某个单词的频率,只需和访问字典元素一样操作即可:例如访问'Romance'下的'could'频率
>>>cfd['romance']['could'] 193
【绘制分布图和分布表】
绘制分布图:cfd.plot()
例子:绘制特定演讲中出现['america','citizen']的次数随时间变化情况
from nltk.corpus import inaugural cfd=nltk.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()
绘制分布表:cfd.tabulate()[上节以及使用过]
注意在使用plot和tabulate时候可以使用condition=参数来制定显示哪些条件。同样也可以使用samples=参数来限制要显示的样本。
例如:我们只想看英语和德语中单词长度小于10个字符的词汇个数:
from nltk.corpus import udhr lan=['Chickasaw','English','German_Deutsch','Greenlandic_Inuktikut','Hungarian_Magyar','Ibibio_Efik'] cfd=nltk.ConditionalFreqDist((lang,len(word) ) for lang in lan for word in udhr.words(lang+'-Latin1')) cfd.tabulate(conditions=['English','German_Deutsch'],samples=range(10),cumulative=True)
结果:
【使用双连词生成随机文本】
我们可以使用条件频率分布创建一个双连词表。bigrams()函数能接受一个词汇链表,并且建立起一个连续的词对链表
sent=['In','the','begining','God','created','the','heaven','and','the','earth','.'] print(list(nltk.bigrams(sent)))
输出:[('In', 'the'), ('the', 'begining'), ('begining', 'God'), ('God', 'created'), ('created', 'the'), ('the', 'heaven'), ('heaven', 'and'), ('and', 'the'), ('the', 'earth'), ('earth', '.')]
例2-1.产生随机文本:程序获得《创世纪》文本中所有的双连词,然后构造一个条件频率分布来记录哪些词汇最有可能会跟在给定次后面。generate_model()函数适用这些数据和种子词来产生随机文本。
def generate_model(cfdist,word,num=15): for i in range(num): print (word,) word=cfdist[word].max() text=nltk.corpus.genesis.words('english-kjv.txt') bigrams=nltk.bigrams(text) cfd=nltk.ConditionalFreqDist(bigrams)
测试living后面最长跟的双连词:
generate_model(cfd,'living')
结果为:living,creature,that,he,said,and,the,land,of,the,land,of,the,land
发现在循环中卡住了。。
条件频率分布是一个对许多NLP任务都有用的数据结构。