2.3 绘制分布图和分布表

除了组合两个或两个以上的频率分布和更容易初始化之外,ConditionalFreqDist还为制表和绘图提供了一些有用的方法。

1.1是基于下面的代码产生的一个条件频率分布绘制的。条件是词 america 或 citizen[2],被绘图的计数是在特定演讲中出现的词的次数。它利用了每个演讲的文件名——例如1865-Lincoln.txt ——的前 4 个字符包含年代的事实[1]。这段代码为文件1865-Lincoln.txt中每个小写形式以 america 开头的词——如 Americans——产生一个配对('america', '1865')

  1. >>> from nltk.corpus import inaugural
  2. >>> cfd = nltk.ConditionalFreqDist(
  3. ... (target, fileid[:4]) ![[1]](/projects/nlp-py-2e-zh/Images/eeff7ed83be48bf40aeeb3bf9db5550e.jpg)
  4. ... for fileid in inaugural.fileids()
  5. ... for w in inaugural.words(fileid)
  6. ... for target in ['america', 'citizen'] ![[2]](/projects/nlp-py-2e-zh/Images/6efeadf518b11a6441906b93844c2b19.jpg)
  7. ... if w.lower().startswith(target))

1.2也是基于下面的代码产生的一个条件频率分布绘制的。这次的条件是语言的名称,图中的计数来源于词长[1]。它利用了每一种语言的文件名是语言名称后面跟'-Latin1'(字符编码)的事实。

  1. >>> from nltk.corpus import udhr
  2. >>> languages = ['Chickasaw', 'English', 'German_Deutsch',
  3. ... 'Greenlandic_Inuktikut', 'Hungarian_Magyar', 'Ibibio_Efik']
  4. >>> cfd = nltk.ConditionalFreqDist(
  5. ... (lang, len(word)) ![[1]](/projects/nlp-py-2e-zh/Images/eeff7ed83be48bf40aeeb3bf9db5550e.jpg)
  6. ... for lang in languages
  7. ... for word in udhr.words(lang + '-Latin1'))

plot()tabulate()方法中,我们可以使用conditions=来选择指定哪些条件显示。如果我们忽略它,所有条件都会显示。同样,我们可以使用samples=parameter 来限制要显示的样本。这使得载入大量数据到一个条件频率分布,然后通过选定条件和样品,绘图或制表的探索成为可能。这也使我们能全面控制条件和样本的显示顺序。例如:我们可以为两种语言和长度少于 10 个字符的词汇绘制累计频率数据表,如下所示。我们解释一下上排最后一个单元格中数值的含义是英文文本中 9 个或少于 9 个字符长的词有 1,638 个。

  1. >>> cfd.tabulate(conditions=['English', 'German_Deutsch'],
  2. ... samples=range(10), cumulative=True)
  3. 0 1 2 3 4 5 6 7 8 9
  4. English 0 185 525 883 997 1166 1283 1440 1558 1638
  5. German_Deutsch 0 171 263 614 717 894 1013 1110 1213 1275

注意

轮到你来: 处理布朗语料库的新闻和言情文体,找出一周中最有新闻价值并且是最浪漫的日子。定义一个变量days,包含星期的列表,如['Monday', ...]。然后使用cfd.tabulate(samples=days)为这些词的计数制表。接下来用plot替代tabulate尝试同样的事情。你可以在额外的参数samples=['Monday', ...]的帮助下控制星期输出的顺序。

你可能已经注意到:我们已经在使用的条件频率分布看上去像列表推导,但是不带方括号。通常,我们使用列表推导作为一个函数的参数,如set([w.lower() for w in t]),忽略掉方括号而只写set(w.lower() for w in t)是允许的。(更多的讲解请参见4.2节“生成器表达式”的讨论。)