天天看点

《Python自然语言处理》——第1章 语言处理与Python 1.1 语言计算:文本和词汇

本节书摘来自异步社区《python自然语言处理》一书中的第1章,第1.1节,作者[美]steven bird,ewan klein,edward loper, 陈涛,张旭,崔杨,刘海平 译,更多章节内容可以访问云栖社区“异步社区”公众号查看。

我们能够很容易地得到数百万数量级的文本。假设我们会写一些简单的程序,那可以用它来做些什么?本章将解决以下几个问题。

(1)通过将技术性较简单的程序与大规模文本结合起来,我们能实现什么?

(2)如何自动地提取出关键字和词组,用来总结文本的风格和内容?

(3)python编程语言为上述工作提供了哪些工具和技术?

(4)自然语言处理中有哪些有趣的挑战呢?

我们都对文本非常熟悉,因为我们每天都在进行阅读和写作。在本书中,把文本视为编写程序的原始数据,并通过很多有趣的编程方式来处理和分析文本。但在能写这些程序之前,必须得从了解python解释器开始。

python入门

python与用户友好交互的方式之一包括你可以在交互式解释器直接输入代码——解释器将运行你的python代码的程序。你可以通过一个叫做交互式开发环境(interactive development environment,idle)的简单图形接口来访问python解释器。在mac上,你可以在“applications→macpython”中找到;在windows中,你可以在“程序→python”中找到。在unix下,你可以在shell输入“idle”来运行python(如果没有安装,尝试输入python)。解释器将会输入关于你的python的版本简介,请检查你是否运行在python 2.4或2.5(这里是2.5.1)。

提示符>>>表示python解释器正在等待输入。复制这本书的例子时,自己不要键入>>>。现在,把python当作计算器使用。

一旦解释器完成计算并显示出答案,提示符就会重新出现。这表示python解释器在等待另一个指令。

前面的例子展示了如何使用python交互式解释器,体验python语言中各种表达式,看看它们能做些什么。现在让我们尝试一个无意义的表达式,看看解释器将如何处理。

结果产生了一个语法错误。在python中,指令以加号结尾是没有意义的。python解释器会指出发生错误的行(的第1行,表示“标准输入”)。

现在我们学会使用python解释器了,已经准备好开始处理语言数据了。

nltk入门

一旦安装完成,便可像前面那样启动python解释器。在python提示符后面输入下面两行命令来安装本书所需的数据,然后选择book,如图1-1所示。

《Python自然语言处理》——第1章 语言处理与Python 1.1 语言计算:文本和词汇

一旦数据被下载到你的机器,你就可以使用python解释器加载其中的一些了。第一步是在python提示符后输入一个特殊的命令,告诉解释器去加载一些我们要用的文本:from nltk.book import * 。这条语句是说“从nltk的book模块中加载所有的条目”。book模块包含你阅读本章时所需的所有数据。在输出欢迎信息之后,将会加载一些书的文本(这将需要几秒钟)。下面就是你需要输入的命令及输出的结果,注意拼写和标点符号的正确性,记住不要输入>>>。

无论什么时候想要找到这些文本,只需要在python提示符后输入它们的名字即可。

现在我们可以使用python解释器和这些数据,准备开始了。

搜索文本

除了简单地阅读文本之外,还有很多方法可以用来查看文本内容。词语索引视图可以显示指定单词的出现情况,同时还可以显示一些上下文。下面我们输入text1并在后面跟一个点,再输入函数名concordance,然后将monstrous放在括号里,用来查找《白鲸记》中的词monstrous。

通过一段时间对这些文本的研究,我们希望你能对语言的丰富性和多样性有一个新的认识。在下一章中,你将学习如何获取更广泛的文本,包括英语以外其他语言的文本。

关键词索引让我们可以看到上下文中的词。例如:我们看到monstrous出现在文章中,如the___pictures和the____ size。还有哪些词出现在相似的上下文中?我们可以通过在被查询的文本名后添加函数名similar,然后在括号中插入相关词的方法来查找到。

可以发现从不同的文本中能够得到不同的结果。austen(奥斯丁,英国女小说家)在词汇的使用上与melville完全不同。对于她来说,monstrous是正面的意思,有时它的功能像词very一样用作强调成分。

我们可以使用函数common_contexts研究共用两个或两个以上词汇的上下文,如monstrous和very。使用方括号和圆括号将这些词括起来,中间用逗号分割。

自动检测出现在文本中的特定的词,并显示同一上下文中出现的其他词。我们也可以判断词在文本中的位置:从文本开头算起有多少词出现。这个位置信息可以用离散图表示。每一列代表一个单词,每一行代表整个文本。在图1-2中,我们看到在过去220年中的一些显著的词语用法模式(在一个由就职演说语料首尾相连组合的人工文本中)。可以利用下面的方法画出离散图。你也许会想尝试更多的单词(如:liberty,constitution)和不同的文本。你能在看到这幅图之前预测一个单词的分布吗?如前所述,保证引号、逗号、中括号及小括号的使用完全正确。

《Python自然语言处理》——第1章 语言处理与Python 1.1 语言计算:文本和词汇

现在轻松一下,尝试以上述不同风格产生一些随机文本。要做到这一点,我们需要输入后面跟着函数名generate的文本名称。(需要带括号,但括号里什么也没有。)

请注意,第一次运行此命令时,由于要搜集单词序列的统计信息,因而执行速度比较慢。每次运行后,输出的文本都会不同。现在尝试产生就职演说风格或互联网聊天室风格的随机文本。虽然文本是随机的,但它重复使用了源文本中常见的单词和短语,从而使我们能感觉到它的风格和内容。

计数词汇

在前面例子中出现的文本中,最明显的地方在于它们所使用的词汇不同。在本节中,我们将看到如何使用计算机并以各种有用的方式来计数词汇。像以前一样,你可以马上开始使用python解释器进行试验,即使你可能还没有系统地研究过python。修改这些例子并测试一下你对它们的理解程度,尝试一下本章结尾的练习题。

首先,让以文本中出现的单词和标点符号为单位算出文本从头到尾的长度。使用函数len获取长度,参考《创世纪》中使用的例子。

《创世纪》有44764个单词和标点符号,也被称作“标识符”。标识符是表示一组字符序列——如:hairy、his或者:)——的术语。当计算文本中标识符的个数时,如to be or not to be这句话,我们计算的是这些序列出现的次数。因此,例句中出现了to和be各两次,or和not各一次。然而在例句中只有4个不同的单词。《创世纪》中有多少不同的单词?如果要用python来回答这个问题,就不得不稍微改变一下提出的问题。因为一个文本词汇表只是它用到的标识符的集合,在集合中所有重复的元素都只算一个。在python中可以使用命令:set(text3)来获得text3的词汇表。这样做之后,屏幕上的很多词就会被掠过。现在尝试以下操作。

用sorted()包裹python表达式set(text3)①,得到一个词汇条目的排序表,这个表以各种标点符号开始,然后接着是以a开头的词汇。大写单词排在小写单词前面。通过求集合中项目的个数,可以间接地获得词汇表的大小。再次使用命令len来获得这个数值②。尽管书中有44764个标识符,但只有2789个不同的词汇或“词类型”。词类型是指一个词在一个文本中独一无二的出现或拼写形式。也就是说,这个单词在词汇表中是唯一的。计数的2789个项目中包括标点符号,所以把它们称作唯一项目类型而不是词类型。

现在,开始对文本词汇丰富度进行测量。下面的例子展示的结果含义为每个词平均被使用了16次(应该确保python使用的是浮点除法)。

接下来,专注于特定的词。计数一个单词在文本中出现的次数,再计算一个特定词在文本中占据的百分比。

也许你想要对几个文本重复进行这些计算,但重新输入公式是很乏味的。方法是可以自己命名一个任务,如“lexical_diversity”或“percentage”,然后用一个代码块关联它。这样,你只需输入一个很短的名字就可以代替一行或多行python代码,而且想用多少次就用多少次。执行一个任务的代码段叫做函数。使用关键字def给函数定义一个简短的名字。下面的例子演示的是如何定义两个新的函数,lexical_diversity()和percentage()。

在lexical_diversity()1的定义中,指定了一个text参数。这个参数是计算文本词汇多样性时的一个“占位符”,并在使用函数时,重现在运行的代码段中2。类似地,percentage()3定义了两个参数:count和total。

只要python知道了lexical_diversity()和percentage()是指定代码段的名字,我们就可以继续使用这些函数了。

简要重述一下,使用或者说是调用一个如lexical_diversity()这样的函数时,只要输入它的名字并在后面跟一个左括号,再输入文本名字,然后是右括号即可。这些括号经常出现,它们的作用是将任务名——如:lexical_diversity()——与任务将要处理的数据——如:text3分割开。调用函数时放在参数位置的数据值叫做函数的实参。

在本章中,你已经遇到了一些函数,如:len(),set()和sorted()。通常会在函数名后面加一对空括号,例如len(),这只是为了表明这是一个函数而不是其他的python表达式。函数是编程中的一个重要概念,我们只是在一开始提到了它们,为了是让新手体会到编程的强大和它的创造力。如果你现在觉得有点混乱,请不要担心。

稍后将学习如何使用函数列表显示数据,见表1-1。表中每一行包含了不同数据相同的计算,将使用函数进行这种重复性的工作。

《Python自然语言处理》——第1章 语言处理与Python 1.1 语言计算:文本和词汇