🔎大家好,我是Sonhhxg_柒,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎
📝个人主页-Sonhhxg_柒的博客_CSDN博客 📃
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝
📣系列专栏 - 机器学习【ML】 自然语言处理【NLP】 深度学习【DL】
🖍foreword
✔说明⇢本人讲解主要包括Python、机器学习(ML)、深度学习(DL)、自然语言处理(NLP)等内容。
如果你对这个系列感兴趣的话,可以关注订阅哟👋
我们很容易掌握数百万字的文本。假设我们可以编写一些简单的程序,我们可以用它做什么?在本章中,我们将解决以下问题:
-
通过将简单的编程技术与大量文本相结合,我们可以实现什么?
-
我们如何自动提取概括文本风格和内容的关键词和短语?
-
Python 编程语言为此类工作提供了哪些工具和技术?
-
自然语言处理有哪些有趣的挑战?
本章分为在两种完全不同的风格之间跳过的部分。在“使用语言计算”部分,我们将承担一些以语言为动机的编程任务,而不必解释它们是如何工作的。在“深入了解 Python”部分中,我们将系统地回顾关键的编程概念。我们将在章节标题中标记这两种风格,但后面的章节将混合这两种风格,而不是那么提前。我们希望这种介绍风格能够让您真正体验到后面的内容,同时涵盖语言学和计算机科学中的一系列基本概念。如果你对这两个领域有基本的了解,你可以跳到自动自然语言理解; 我们将在后面的章节中重复任何重要的点,如果您遗漏了任何内容,您可以轻松地查阅http://www.nltk.org/上的在线参考资料。如果这些材料对您来说是全新的,那么本章将提出的问题多于它所回答的问题,这些问题将在本书的其余部分中解决。
我们都非常熟悉文本,因为我们每天都在阅读和写作。在这里,我们将文本视为我们编写的程序的原始数据,这些程序以各种有趣的方式对其进行操作和分析。但在我们这样做之前,我们必须开始使用 Python 解释器。
Python 的优点之一是它允许您直接在交互式解释器中输入内容——该程序将运行您的 Python 程序。您可以使用称为交互式开发环境 (IDLE) 的简单图形界面访问 Python 解释器。在 Mac 上,您可以在 Applications→MacPython 下找到它,在 Windows 上,您可以在 All Programs→Python 下找到它。在 Unix 下,您可以通过键入从 shell 运行 Python idle
(如果未安装,请尝试键入python
)。解释器将打印有关您的 Python 版本的简介;只需检查您运行的是 Python 2.4 还是 2.5(这里是 2.5.1):
Python 2.5.1 (r251:54863, Apr 15 2008, 22:57:26)
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
笔记
如果您无法运行 Python 解释器,那么您可能没有正确安装 Python。请访问Welcome to Python.org了解详细说明。
提示表示 Python 解释器现在>>>
正在等待输入。复制本书中的示例时,不要>>>
自己键入“ ”。现在,让我们从使用 Python 作为计算器开始:
1 + 5 * 2 - 3
8
一旦解释器计算完答案并显示出来,提示符就会重新出现。这意味着 Python 解释器正在等待另一条指令。
笔记
轮到你了:输入更多你自己的表达方式。您可以使用星号 (*
) 进行乘法运算,使用斜线 (/
) 进行除法运算,并使用括号将表达式括起来。请注意,除法并不总是像您预期的那样 - 它在您键入时执行整数除法(分数向下舍入),在您键入时执行1/3
“浮点”(或小数)除法1.0/3.0
。为了获得除法的预期行为(Python 3.0 中的标准),您需要键入:from __future__ import division
.
前面的示例演示了如何与 Python 解释器交互工作,试验语言中的各种表达式以查看它们的作用。现在让我们尝试一个无意义的表达式,看看解释器是如何处理它的:
1 +
File "<stdin>", line 1
1 +
^
SyntaxError: invalid syntax
这产生了语法错误。在 Python 中,以加号结束指令是没有意义的。Python 解释器指示问题发生的行(第 1 行<stdin>
,代表“标准输入”)。
既然我们可以使用 Python 解释器,我们就可以开始处理语言数据了。
在继续之前,您应该安装 NLTK,可从NLTK :: Natural Language Toolkit免费下载。按照那里的说明下载您的平台所需的版本。
安装 NLTK 后,像以前一样启动 Python 解释器,并通过在 Python 提示符下键入以下两个命令来安装本书所需的数据,然后选择 book
集合,如图 1-1所示。
import nltk
nltk.download()
将数据下载到您的机器后,您可以使用 Python 解释器加载其中的一些数据。第一步是在 Python 提示符下键入一个特殊的命令,它告诉解释器加载一些文本供我们探索:from nltk.book import *
. 这表示“从 NLTK 的book
模块中,加载所有项目”。该book
模块包含阅读本章所需的所有数据。打印欢迎信息后,它会加载几本书的文本(这将需要几秒钟)。这是命令,以及您将看到的输出。注意正确拼写和标点符号,并记住不要键入>>>
.
>>> from nltk.book import *
*** Introductory Examples for the NLTK Book ***
Loading text1, ..., text9 and sent1, ..., sent9
Type the name of the text or sentence to view it.
Type: 'texts()' or 'sents()' to list the materials.
text1: Moby Dick by Herman Melville 1851
text2: Sense and Sensibility by Jane Austen 1811
text3: The Book of Genesis
text4: Inaugural Address Corpus
text5: Chat Corpus
text6: Monty Python and the Holy Grail
text7: Wall Street Journal
text8: Personals Corpus
text9: The Man Who Was Thursday by G . K . Chesterton 1908
>>>
任何时候我们想知道这些文本,我们只需要在 Python 提示符下输入它们的名字:
>>> text1
<Text: Moby Dick by Herman Melville 1851>
>>> text2
<Text: Sense and Sensibility by Jane Austen 1811>
>>>
现在我们可以使用 Python 解释器,并且有一些数据可以使用,我们已经准备好开始了。
除了简单地阅读之外,还有很多方法可以检查文本的上下文。索引视图向我们展示了给定单词的每一次出现,以及一些上下文。在这里,我们通过输入一个句号来查找 Moby Dick中的monstrous这个词,然后是这个词text1
concordance
,然后放在"monstrous"
括号中:
>>> text1.concordance("monstrous")
Building index...
Displaying 11 of 11 matches:
ong the former , one was of a most monstrous size . ... This came towards us ,
ON OF THE PSALMS . " Touching that monstrous bulk of the whale or ork we have r
ll over with a heathenish array of monstrous clubs and spears . Some were thick
d as you gazed , and wondered what monstrous cannibal and savage could ever hav
that has survived the flood ; most monstrous and most mountainous ! That Himmal
they might scout at Moby Dick as a monstrous fable , or still worse and more de
th of Radney .'" CHAPTER 55 Of the monstrous Pictures of Whales . I shall ere l
ing Scenes . In connexion with the monstrous pictures of whales , I am strongly
ere to enter upon those still more monstrous stories of them which are to be fo
ght have been rummaged out of this monstrous cabinet there is no telling . But
of Whale - Bones ; for Whales of a monstrous size are oftentimes cast up dead u
>>>
笔记
轮到你了:尝试搜索其他词;为了节省重新输入,您可以使用向上箭头、Ctrl-向上箭头或 Alt-p 来访问上一个命令并修改正在搜索的单词。您还可以尝试搜索我们包含的其他一些文本。例如, 在Sense 和 Sensibility中搜索单词 affinity,使用
text2.concordance("affection")
。搜索创世记以找出一些人的寿命,使用:text3.concordance("lived")
。您可以查看Inaugural Address Corpustext4
, 以查看可追溯到 1789 年的英语示例,并搜索诸如 国家、恐怖之类的词, 上帝看看这些词随着时间的推移如何以不同的方式使用。我们还包括NPS 聊天语料库text5
:在此搜索非常规单词,如 im、ur、 lol。(请注意,这个语料库是未经审查的!)
一旦您花一点时间检查这些文本,我们希望您对语言的丰富性和多样性有新的认识。在下一章中,您将学习如何访问更广泛的文本,包括英语以外的其他语言的文本。
索引允许我们在上下文中看到单词。例如,我们看到monstrous发生在___ 图片和___ 大小等上下文中。还有哪些其他词出现在类似的上下文中?我们可以通过附加术语来找出similar
到相关文本的名称,然后在括号中插入相关单词:
>>> text1.similar("monstrous")
Building word-context index...
subtly impalpable pitiable curious imperial perilous trustworthy
abundant untoward singular lamentable few maddens horrible loving lazy
mystifying christian exasperate puzzled
>>> text2.similar("monstrous")
Building word-context index...
very exceedingly so heartily a great good amazingly as sweet
remarkably extremely vast
>>>
观察我们对不同的文本得到不同的结果。奥斯汀使用这个词与梅尔维尔完全不同。对她来说, monstrous有积极的含义,有时像very这个词一样充当增强词 。
期限common_contexts
允许我们仅检查两个或多个单词共享的上下文,例如monstrous和 very。我们必须用方括号和括号将这些词括起来,并用逗号分隔它们:
>>> text2.common_contexts(["monstrous", "very"])
be_glad am_glad a_pretty is_pretty a_lucky
>>>
自动检测文本中出现的特定单词并显示出现在同一上下文中的某些单词是一回事。但是,我们也可以确定一个单词在文本中的 位置:它从开头出现了多少个单词。该位置信息可以使用分散图来显示。每个条纹代表一个单词的实例,每一行代表整个文本。在图 1-2中,我们看到了过去 220 年来一些惊人的单词使用模式(在通过端到端连接就职演说语料库文本构建的人工文本中)。您可以生成该图,如下所示。您可能想尝试更多的单词(例如,自由, 宪法)和不同的文本。你能在查看一个词之前预测它的分布吗?和以前一样,注意使引号、逗号、方括号和圆括号完全正确。
>>> text4.dispersion_plot(["citizens", "democracy", "freedom", "duties", "America"])
>>>
笔记
重要提示:您需要安装 Python 的 NumPy 和 Matplotlib 包才能生成本书中使用的图形。有关安装说明,请参见NLTK :: Natural Language Toolkit。
现在,只是为了好玩,让我们尝试以我们刚刚看到的各种样式生成一些随机文本。为此,我们键入文本的名称,后跟术语generate
. (我们需要包括括号,但它们之间没有任何内容。)
>>> text3.generate()
In the beginning of his brother is a hairy man , whose top may reach
unto heaven ; and ye shall sow the land of Egypt there was no bread in
all that he was taken out of the month , upon the earth . So shall thy
wages be ? And they made their father ; and Isaac was old , and kissed
him : and Laban with his cattle in the midst of the hands of Esau thy
first born , and Phichol the chief butler unto his son Isaac , she
>>>
请注意,第一次运行此命令时,它会很慢,因为它会收集有关单词序列的统计信息。每次运行它,你都会得到不同的输出文本。现在尝试以就职演说或互联网聊天室的形式生成随机文本。尽管文本是随机的,但它重用了源文本中的常用单词和短语,并让我们对其风格和内容有所了解。(这个随机生成的文本缺少什么?)
笔记
什么时候
generate
产生它的输出,标点符号从前面的单词中分离出来。虽然这不是英文文本的正确格式,但我们这样做是为了明确单词和标点符号是相互独立的。您将在第 3 章中了解更多相关信息。
从前面的例子中可以看出关于文本的最明显的事实是它们使用的词汇不同。在本节中,我们将了解如何使用计算机以各种有用的方式计算文本中的单词。和以前一样,即使您可能还没有系统地学习过 Python,您也将直接进入并尝试使用 Python 解释器。通过修改示例和尝试本章末尾的练习来测试您的理解。
让我们首先根据出现的单词和标点符号找出文本从头到尾的长度。我们用这个词len
来表示某些东西的长度,我们将在此将其应用于创世记:
>>> len(text3)
44764
>>>
所以创世纪有 44,764 个单词和标点符号,或“标记”。标记是我们希望将其视为一个组的一系列字符的技术名称,例如hairy
、his
或。:)
当我们计算文本中标记的数量时,例如,短语to be 或 not to be,我们正在计算这些序列的出现次数。因此,在我们的示例短语中,出现两次 to,两次出现be,以及一次出现or和not. 但是这个短语中只有四个不同的词汇项目。创世记有多少不同的词?为了在 Python 中解决这个问题,我们必须稍微不同地提出问题。文本的词汇表只是它使用的一组标记,因为在一组中,所有重复项都折叠在一起。text3
在 Python 中,我们可以通过以下命令获取词汇项: set(text3)
。当你这样做时,许多文字屏幕会飞过。现在尝试以下操作:
>>> sorted(set(text3)) 1
['!', "'", '(', ')', ',', ',)', '.', '.)', ':', ';', ';)', '?', '?)',
'A', 'Abel', 'Abelmizraim', 'Abidah', 'Abide', 'Abimael', 'Abimelech',
'Abr', 'Abrah', 'Abraham', 'Abram', 'Accad', 'Achbor', 'Adah', ...]
>>> len(set(text3)) 2
2789
>>>
通过包装sorted()
Python 表达式,我们获得了一个词汇项目的排序列表,从各种标点符号开始,然后是以Aset(text3)
开头的单词。所有大写单词都在小写单词之前。我们通过询问集合中项目的数量来间接发现词汇表的大小,并且我们可以再次使用来获得这个数字。尽管它有 44,764 个标记,但这本书只有 2,789 个不同的单词,或“单词类型”。一个 字型len
是单词的形式或拼写,与它在文本中的具体出现无关——也就是说,单词被认为是词汇中的一个独特项目。我们对 2,789 个项目的计数将包括标点符号,因此我们通常将这些唯一项目称为类型 而不是单词类型。
现在,让我们计算文本词汇丰富度的度量。下一个示例向我们展示了每个单词平均使用 16 次(我们需要确保 Python 使用浮点除法):
>>> from __future__ import division
>>> len(text3) / len(set(text3))
16.050197203298673
>>>
接下来,让我们关注特定的单词。我们可以计算一个单词在文本中出现的频率,并计算特定单词占据文本的百分比:
>>> text3.count("smote")
5
>>> 100 * text4.count('a') / len(text4)
1.4643016433938312
>>>
笔记
轮到你了:lol这个词出现了
text5
?这占本文总字数的百分比是多少?
您可能想在多个文本上重复这样的计算,但是不断地重新输入公式是很乏味的。相反,您可以为任务想出自己的名称,例如“lexical_diversity”或“percentage”,并将其与代码块相关联。现在您只需键入一个简短的名称,而不是一行或多行完整的 Python 代码,您可以随意重复使用它。为我们执行任务的代码块称为函数,我们使用关键字为函数定义一个短名称def
。下一个示例展示了如何定义两个新函数,lexical_diversity()
并且percentage()
:
>>> def lexical_diversity(text): 1
... return len(text) / len(set(text)) 2
...
>>> def percentage(count, total): 3
... return 100 * count / total
...
警告!
在第一行末尾遇到冒号后,Python 解释器将提示符从 更改为
>>>
。 提示表示 Python 期望接下来出现一个...
缩进的代码块。您可以通过键入四个空格或按 Tab 键来执行缩进。要完成缩进块,只需输入一个空行。...
在 的定义中lexical_diversity()
,我们指定了一个标记为的参数text
。此参数是我们要计算其词汇多样性的实际文本的“占位符”,并且在使用该函数时将运行的代码块中重新出现在 line 中。同样,percentage()
定义为取两个参数,标记为count
和total
。
一旦 Python 知道这一点lexical_diversity()
并且percentage()
是特定代码块的名称,我们就可以继续使用这些函数:
>>> lexical_diversity(text3)
16.050197203298673
>>> lexical_diversity(text5)
7.4200461589185629
>>> percentage(4, 5)
80.0
>>> percentage(text4.count('a'), len(text4))
1.4643016433938312
>>>
回顾一下,我们使用或调用一个函数,例如lexical_diversity()
键入它的名称,然后是一个左括号,文本的名称,然后是一个右括号。这些括号会经常出现;它们的作用是将任务的名称(例如lexical_diversity()
)与要执行该任务的数据(例如text3
. 当我们调用函数时放在括号中的数据值是函数的参数。
您已经在本章中遇到了几个函数,例如len()
、set()
和sorted()
。按照惯例,我们总是会在函数名之后添加一对空括号,如 中len()
,只是为了明确我们所说的是一个函数,而不是其他类型的 Python 表达式。函数是编程中的一个重要概念,我们只是在开头提到它们,让新手了解编程的力量和创造力。如果您现在发现它有点混乱,请不要担心。
稍后我们将看到如何在数据列表中使用函数,如 表 1-1 所示。表的每一行都将涉及相同的计算但具有不同的数据,我们将使用一个函数来完成这项重复性工作。