提交 8cd1199c 编写于 作者: W wizardforcel

2021-02-23 22:09:30

上级 9ab81275
......@@ -881,7 +881,7 @@ scikit_learn==0.19.0
### 注意
`apply`方法之所以出色,是因为它可以解决各种问题并允许易于阅读的代码。 但是,矢量化方法(例如`pd.Series.str`)通常可以更快地完成同一件事。 因此,建议尽可能避免使用它,尤其是在处理大型数据集时。 在接下来的课程中,我们将看到一些矢量化方法的示例。
`apply`方法之所以出色,是因为它可以解决各种问题并允许易于阅读的代码。 但是,向量化方法(例如`pd.Series.str`)通常可以更快地完成同一件事。 因此,建议尽可能避免使用它,尤其是在处理大型数据集时。 在接下来的课程中,我们将看到一些向量化方法的示例。
4. 通过在新单元格中键入`df.groupby('AGE_category').size()`并运行它,检查我们将每个年龄组归类了多少个样本:
......
......@@ -423,7 +423,7 @@ plt.show()
# 用 Python 计算协方差和相关性
好吧,让我们在这里通过一些实际的 Python 代码来了解协方差和相关性。 再次,您可以在概念上将协方差视为将这些多维方差量从每个属性的均值中提取出来,并计算它们之间的角度作为协方差的量度。 做到这一点的数学比听起来容易得多。 我们正在谈论高维向量。 这听起来像是史蒂芬·霍金(Stephen Hawking)的东西,但实际上,从数学角度来看,这非常简单。
好吧,让我们在这里通过一些实际的 Python 代码来了解协方差和相关性。 再次,您可以在概念上将协方差视为将这些多维方差量从每个属性的均值中提取出来,并计算它们之间的角度作为协方差的量度。 做到这一点的数学比听起来容易得多。 我们正在谈论高维向量。 这听起来像是史蒂芬·霍金(Stephen Hawking)的东西,但实际上,从数学角度来看,这非常简单。
# 计算相关性-困难的方法
......
......@@ -347,7 +347,7 @@ classifier.fit(counts, targets)
构建`MultinomialNB`分类器后,它需要两个输入。 它需要我们正在训练的实际数据(`counts`)和每个事物的目标(`targets`)。 因此,`counts`基本上是每封电子邮件中所有单词的列表以及该单词出现的次数。
因此,这就是`CountVectorizer()`的作用:它从 DataFrame 中获取`message`列,并从中获取所有值。 我将调用`vectorizer.fit_transform`,它基本上将数据中看到的所有单个单词标记化或转换为数字和值。 然后,它计算每个单词出现的次数。
因此,这就是`CountVectorizer()`的作用:它从 DataFrame 中获取`message`列,并从中获取所有值。 我将调用`vectorizer.fit_transform`,它基本上将数据中看到的所有单个单词分词或转换为数字和值。 然后,它计算每个单词出现的次数。
这是表示每个单词在电子邮件中出现多少次的更紧凑的方式。 我不是真正地保留单词本身,而是在稀疏矩阵中将这些单词表示为不同的值,这基本上是在说我将每个单词视为一个数字,作为一个数字索引,放入一个数组中。 这样做的意思是,仅用简单的英语,它将每个消息分成一个单词列表,并计算每个单词出现的次数。 因此,我们称其为`counts`。 基本上,每个单词在每个消息中出现多少次的信息。 而`targets`是我遇到的每封电子邮件的实际分类数据。 因此,我可以使用`MultinomialNB()`函数调用`classifier.fit()`来使用朴素贝叶斯(Naive Bayes)实际创建一个模型,该模型将根据我们提供的信息来预测新电子邮件是否为垃圾邮件。
......@@ -361,7 +361,7 @@ predictions
```
我们要做的第一件事是将消息转换为我训练模型时所用的格式。 因此,我使用在创建模型时创建的相同量化器,将每个消息转换为单词及其频率列表,其中单词由数组中的位置表示。 然后,一旦完成了转换,我就可以在分类器上使用`predict()`函数,将其转换为已转换为单词列表的示例数组,然后看看我们会想到什么:
我们要做的第一件事是将消息转换为我训练模型时所用的格式。 因此,我使用在创建模型时创建的相同量化器,将每个消息转换为单词及其频率列表,其中单词由数组中的位置表示。 然后,一旦完成了转换,我就可以在分类器上使用`predict()`函数,将其转换为已转换为单词列表的示例数组,然后看看我们会想到什么:
![](img/9cd78d24-18d0-4700-b154-aa2ac869322b.jpg)
......@@ -703,7 +703,7 @@ Image(graph.create_png())
因此,您可以看到,对于每种情况,只要有可能,我们就一直保持熵达到 0。
# 合奏学习–使用随机森林
# 集成学习–使用随机森林
现在,假设我们要使用随机森林,您知道,我们担心我们可能过度拟合训练数据。 创建包含多个决策树的随机森林分类器实际上非常容易。
......@@ -738,17 +738,17 @@ print clf.predict([[10, 0, 4, 0, 0, 0]])
因此,我认为决策树和随机森林是机器学习中更有趣的部分之一。 我一直认为,凭空生成这样的流程图非常酷。 因此,希望您会发现它有用。
# 合奏学习
# 集成学习
当我们谈论随机森林时,这就是集成学习的一个例子,实际上我们是将多个模型组合在一起以得出比任何单个模型都可以得出的更好的结果。 因此,让我们更深入地了解这一点。 让我们来谈谈整体学习。
那么,还记得随机森林吗? 我们有一堆决策树,它们使用输入数据的不同子样本以及将要分支的不同属性集,当您尝试对某些事物进行最后的分类时,它们都会对最终结果进行投票。 那是合奏学习的一个例子。 另一个例子:当我们讨论 k 均值聚类时,我们想到了可能使用具有不同初始随机质心的不同 k 均值模型,并让它们都对最终结果进行投票。 这也是合奏学习的一个例子。
那么,还记得随机森林吗? 我们有一堆决策树,它们使用输入数据的不同子样本以及将要分支的不同属性集,当您尝试对某些事物进行最后的分类时,它们都会对最终结果进行投票。 那是集成学习的一个例子。 另一个例子:当我们讨论 k 均值聚类时,我们想到了可能使用具有不同初始随机质心的不同 k 均值模型,并让它们都对最终结果进行投票。 这也是集成学习的一个例子。
基本上,您的想法是拥有多个模型,它们可能是同一类型的模型,也可能是不同类型的模型,但是您可以在一组训练数据上运行所有模型,并且它们都对模型进行投票 无论您要预测什么,最终结果。 通常,您会发现,不同模型的组合所产生的结果要比任何单个模型单独产生的结果都要好。
几年前的一个很好的例子是 Netflix 奖。 Netflix 举办了一场竞赛,他们向可以超越现有电影推荐算法的任何研究人员提供一百万美元。 获胜的方法是整体方法,实际上他们可以一次运行多个推荐算法,然后让他们都对最终结果进行投票。 因此,集成学习可以是一种非常强大但简单的工具,可以提高机器学习中最终结果的质量。 现在让我们尝试探索各种类型的集成学习:
* **自举集成或装袋**:现在,随机森林使用一种称为袋装的技术,是自举集成的简称。 这意味着我们将从训练数据中随机抽取一些子样本,并将其输入相同模型的不同版本中,然后让它们全部对最终结果进行投票。 如果您还记得的话,随机森林采用了许多不同的决策树,它们使用训练数据的不同随机样本进行训练,然后它们最终聚集在一起,对最终结果进行投票。 袋。
* **自举集成或装袋**:现在,随机森林使用一种称为袋装的技术,是自举集成的简称。 这意味着我们将从训练数据中随机抽取一些子样本,并将其输入相同模型的不同版本中,然后让它们全部对最终结果进行投票。 如果您还记得的话,随机森林采用了许多不同的决策树,它们使用训练数据的不同随机样本进行训练,然后它们最终聚集在一起,对最终结果进行投票。 袋。
* **提升**: 提升是一个替代模型,这里的想法是从一个模型开始,但是每个后续模型都会增强处理那些被先前模型错误分类的区域的属性。 因此,您在模型上进行训练/测试,找出根本上出错的属性,然后在后续模型中增强这些属性-希望那些后续模型会更多地关注它们并得到它们 正确的。 因此,这就是推动发展的总体思路。 您可以运行一个模型,找出其薄弱环节,并在不断发展时将重点放在这些薄弱环节上,并基于前一个薄弱环节,继续构建越来越多的模型以不断完善该模型。
* **模型桶**: Netflix 获奖者所做的另一项技术称为模型桶,您可能会使用完全不同的模型来预测某些事物。 也许我正在使用 k 均值,决策树和回归。 我可以在一组训练数据上同时运行所有这三个模型,并在我试图预测某些结果时让它们全部对最终分类结果进行投票。 也许这比孤立使用其中任何一个模型要好。
* **堆叠**:堆叠具有相同的想法。 因此,您可以对数据运行多个模型,并以某种方式将结果组合在一起。 在存储桶和堆叠模型之间的细微区别是,您选择了获胜的模型。 因此,您将进行训练/测试,找到最适合您的数据的模型,然后使用该模型。 相比之下,堆叠会将所有这些模型的结果组合在一起,以得出最终结果。
......@@ -758,14 +758,14 @@ print clf.predict([[10, 0, 4, 0, 0, 0]])
现在,所有这些都是非常复杂的技术,我在本书的范围内无法真正涉及到,但是总而言之,很难仅胜过我们已经讨论过的简单技术。 这里列出了一些复杂的技术:
* **贝叶斯光学分类器**:从理论上讲,有一种称为 Bayes 最佳分类器的东西总是最好的,但是这是不切实际的,因为这样做在计算上是令人望而却步的。
* **贝叶斯参数平均**:许多人试图对贝叶斯最佳分类器进行变型以使其更实用,例如贝叶斯参数平均变型。 但是它仍然容易过度拟合,并且经常由于袋而表现不佳,这与随机森林的想法相同。 您只需多次对数据进行重新采样,运行不同的模型,然后让它们全部对最终结果进行投票。 事实证明,该方法同样有效,而且简单得多!
* **贝叶斯参数平均**:许多人试图对贝叶斯最佳分类器进行变型以使其更实用,例如贝叶斯参数平均变型。 但是它仍然容易过度拟合,并且经常由于袋而表现不佳,这与随机森林的想法相同。 您只需多次对数据进行重新采样,运行不同的模型,然后让它们全部对最终结果进行投票。 事实证明,该方法同样有效,而且简单得多!
* **贝叶斯模型组合**:最后,有一种称为贝叶斯模型组合的东西试图解决贝叶斯最佳分类器和贝叶斯参数平均的所有缺点。 但是,归根结底,它并没有比对模型组合进行交叉验证做得更好。
同样,这些都是非常复杂的技术,很难使用。 在实践中,最好使用我们已详细讨论过的简单方法。 但是,如果您想听起来很聪明,并且经常使用贝叶斯一词,那么至少要熟悉这些技术并知道它们是什么是很好的。
因此,这就是合奏学习。 再次强调,简单的技术通常是正确的选择,例如引导聚合,装袋,增强,堆叠或模型桶。 那里有许多更先进的技术,但它们在很大程度上是理论上的。 但是,至少您现在了解它们。
因此,这就是集成学习。 再次强调,简单的技术通常是正确的选择,例如引导聚合,装袋,增强,堆叠或模型桶。 那里有许多更先进的技术,但它们在很大程度上是理论上的。 但是,至少您现在了解它们。
尝试合奏学习总是一个好主意。 一次又一次地证明,它会比任何单个模型产生更好的结果,因此请务必考虑一下!
尝试集成学习总是一个好主意。 一次又一次地证明,它会比任何单个模型产生更好的结果,因此请务必考虑一下!
# 支持向量机概述
......
......@@ -43,7 +43,7 @@
![](img/6934cbac-7e47-42d5-b5ab-de9465b3144d.png)
假设上图中的这位漂亮女士看过《星球大战》和《帝国反击战》,她爱他们俩。 因此,我们有一位这位女士的用户量,将《星球大战》和《帝国反击战》评为 5 星。
假设上图中的这位漂亮女士看过《星球大战》和《帝国反击战》,她爱他们俩。 因此,我们有一位这位女士的用户量,将《星球大战》和《帝国反击战》评为 5 星。
我们也说 Edgy Mohawk Man 先生来了,他只看了《星球大战》。 那是他唯一见过的东西,他不知道《帝国反击战》,但不知何故,他生活在一个陌生的宇宙中,他不知道实际上有很多很多《星球大战》电影,实际上每年都在增长。
......@@ -191,7 +191,7 @@ movieRatings.head()
怎么能将所有这些整合在一起对我们来说真是太神奇了。 现在,您将看到一些`NaN`值,它们代表**非数字**,以及Pandas如何指示缺失值。 因此,这种解释的方式是,例如`user_id`数字`1`没看电影`1-900 (1994)`,但是`user_id`数字`1`却看了`101 Dalmatians (1996)`并将它评为`2`星。 `user_id`数字`1`也观看了`12 Angry Men (1957)`并将其评为`5`星,但没有观看电影`2 Days in the Valley (1996)`,例如,好吗? 因此,我们最终得到的基本上是一个稀疏矩阵,其中包含每个用户和每个电影,并且在用户对电影进行评分的每个路口处都有一个评分值。
因此,现在您可以看到,我们可以很容易地提取用户观看的每部电影的矢量,我们还可以提取对给定电影评分的每个用户的矢量,这正是我们想要的。 因此,这对于基于用户和基于项目的协作过滤都很有用,对吗? 如果要查找用户之间的关系,可以查看这些用户行之间的相关性,但是如果要查找电影之间的相关性,则对于基于项目的协作过滤,可以根据用户行为查看列之间的相关性。 因此,这就是真正的*反转用户与项目之间的相似性*的地方。
因此,现在您可以看到,我们可以很容易地提取用户观看的每部电影的向量,我们还可以提取对给定电影评分的每个用户的向量,这正是我们想要的。 因此,这对于基于用户和基于项目的协作过滤都很有用,对吗? 如果要查找用户之间的关系,可以查看这些用户行之间的相关性,但是如果要查找电影之间的相关性,则对于基于项目的协作过滤,可以根据用户行为查看列之间的相关性。 因此,这就是真正的*反转用户与项目之间的相似性*的地方。
现在,我们要进行基于项目的协作过滤,因此我们想提取列,为此,我们运行以下代码:
......
......@@ -393,7 +393,7 @@ rdd.map(lambda x: x*x)
# 向量数据类型
还记得本书前面提到的电影相似之处和电影推荐吗? 向量的一个示例可能是给定用户评分的所有电影的列表。 向量有两种类型:稀疏和密集。 让我们看一个例子。 世界上有很多电影,无论用户是否实际观看,密集的矢量实际上代表每个电影的数据。 例如,假设我有一个用户观看过《玩具总动员》,显然我会存储他们对玩具总动员的评分,但是如果他们不看电影《星球大战》,我实际上会存储一个事实,那就是没有数字 为星球大战。 因此,我们最终以密集的矢量为所有这些丢失的数据点占用了空间。 稀疏向量仅存储存在的数据,因此不会在丢失的数据上浪费任何内存空间,好的。 因此,它是内部表示向量的一种更紧凑的形式,但是显然在处理时会引入一些复杂性。 因此,如果您知道向量中会有很多丢失的数据,那么这是节省内存的好方法。
还记得本书前面提到的电影相似之处和电影推荐吗? 向量的一个示例可能是给定用户评分的所有电影的列表。 向量有两种类型:稀疏和密集。 让我们看一个例子。 世界上有很多电影,无论用户是否实际观看,密集的向量实际上代表每个电影的数据。 例如,假设我有一个用户观看过《玩具总动员》,显然我会存储他们对玩具总动员的评分,但是如果他们不看电影《星球大战》,我实际上会存储一个事实,那就是没有数字 为星球大战。 因此,我们最终以密集的向量为所有这些丢失的数据点占用了空间。 稀疏向量仅存储存在的数据,因此不会在丢失的数据上浪费任何内存空间,好的。 因此,它是内部表示向量的一种更紧凑的形式,但是显然在处理时会引入一些复杂性。 因此,如果您知道向量中会有很多丢失的数据,那么这是节省内存的好方法。
# LabeledPoint 数据类型
......
......@@ -29,7 +29,7 @@
从上图可以看到,有训练数据,机器学习模型将从中学习。
让我们假设训练数据是一组代表不同新闻文章的文本。 这些新闻文章可以与体育新闻,国际新闻,国家新闻以及其他各种新闻类别相关。 这些类别将充当我们的标签。 从该训练数据中,我们将得出特征向量,其中每个单词可以是一个向量,或者某些向量可以从文本中得出。 例如,单词“ Football”的实例数可以是矢量,或者单词“总理”的实例数也可以是矢量。
让我们假设训练数据是一组代表不同新闻文章的文本。 这些新闻文章可以与体育新闻,国际新闻,国家新闻以及其他各种新闻类别相关。 这些类别将充当我们的标签。 从该训练数据中,我们将得出特征向量,其中每个单词可以是一个向量,或者某些向量可以从文本中得出。 例如,单词“ Football”的实例数可以是向量,或者单词“总理”的实例数也可以是向量。
这些特征向量和标签被馈送到机器学习算法,该算法从数据中学习。 训练完模型后,将其用于新数据,然后再次提取特征,然后将其输入到模型中,从而生成目标数据。
......
......@@ -6,7 +6,7 @@
* 预处理数据
* 从数据绘制 Wordcloud
* 单词和句子标记化
* 单词和句子分词
* 标记词性
* 词干和词条去除
* 应用斯坦福命名实体识别器
......@@ -193,11 +193,11 @@ $ pip install git+git://github.com/amueller/word_cloud.git
[这个页面](http://moviepilot.com/)强调了电影中所显示的 Immortan Joe 的角色,一般角色以及的战争男孩。
# 单词和句子标记化
# 单词和句子分词
我们之前已经处理过单词标记化,但是我们可以使用 NLTK 以及句子标记化来执行此操作,这非常棘手,因为英语中有用于缩写和其他目的的句点符号。 幸运的是,句子标记器是`nltk``tokenize.punkt`模块中`PunktSentenceTokenizer`的实例,该模块有助于标记句子。
我们之前已经处理过单词分词,但是我们可以使用 NLTK 以及句子分词来执行此操作,这非常棘手,因为英语中有用于缩写和其他目的的句点符号。 幸运的是,句子标记器是`nltk``tokenize.punkt`模块中`PunktSentenceTokenizer`的实例,该模块有助于标记句子。
让我们看一下使用以下代码的单词标记化
让我们看一下使用以下代码的单词分词
```py
>>> #Loading the forbes data
......@@ -223,7 +223,7 @@ $ pip install git+git://github.com/amueller/word_cloud.git
```
现在,让我们执行《福布斯》文章的句子标记化
现在,让我们执行《福布斯》文章的句子分词
```py
>>> sent_tokenize(data)[:5]
......@@ -232,7 +232,7 @@ $ pip install git+git://github.com/amueller/word_cloud.git
```
您可以看到在执行句子标记化之后,每个句子都是列表的元素。
您可以看到在执行句子分词之后,每个句子都是列表的元素。
# 语音标记
......
......@@ -563,7 +563,7 @@ DUMP top10_word_count;
```
在前面的代码中,我们可以加载 Moby Dick 的摘要,然后将其逐行标记化,并基本上拆分成各个元素。 flatten 函数将一行中单个单词标记的集合转换为逐行形式。 然后,我们对单词进行分组,然后对每个单词进行单词计数。 最后,我们按降序对单词计数进行排序,然后将单词计数限制在前 10 行,以获取出现次数最多的前 10 个单词。
在前面的代码中,我们可以加载 Moby Dick 的摘要,然后将其逐行分词,并基本上拆分成各个元素。 flatten 函数将一行中单个单词标记的集合转换为逐行形式。 然后,我们对单词进行分组,然后对每个单词进行单词计数。 最后,我们按降序对单词计数进行排序,然后将单词计数限制在前 10 行,以获取出现次数最多的前 10 个单词。
让我们执行前面的 Pig 脚本:
......
......@@ -428,7 +428,7 @@ $> conda remove -n python36 --all
# NumPy
**NumPy** 是 Travis Oliphant 的创作,是 Python 语言的真正分析主力。 它为用户提供了多维数组,以及为这些数组进行大量数学运算的大量函数。 数组是沿多个维度排列的数据块,它们实现数学向量和矩阵。 数组具有最佳的内存分配特征,不仅对存储数据有用,而且对快速矩阵运算(量化)也很有用,当您希望解决临时数据科学问题时,数组必不可少:
**NumPy** 是 Travis Oliphant 的创作,是 Python 语言的真正分析主力。 它为用户提供了多维数组,以及为这些数组进行大量数学运算的大量函数。 数组是沿多个维度排列的数据块,它们实现数学向量和矩阵。 数组具有最佳的内存分配特征,不仅对存储数据有用,而且对快速矩阵运算(量化)也很有用,当您希望解决临时数据科学问题时,数组必不可少:
* [**网站**](http://www.numpy.org/)
* **打印时的版本**:1.12.1
......@@ -579,7 +579,7 @@ import networkx as nx
# Gensim
**Gensim** 由 RadimŘehůřek 编程,是一个开源软件包,适用于借助并行可分配的在线算法分析大型文本集。 在高级功能中,它实现**潜在语义分析****LSA**),通过**潜在 Dirichlet 分配****LDA**)进行主题建模。 HTG10] word2vec ,一种强大的算法,可将文本转换为量特征,可用于有监督和无监督的机器学习:
**Gensim** 由 RadimŘehůřek 编程,是一个开源软件包,适用于借助并行可分配的在线算法分析大型文本集。 在高级功能中,它实现**潜在语义分析****LSA**),通过**潜在 Dirichlet 分配****LDA**)进行主题建模。 HTG10] word2vec ,一种强大的算法,可将文本转换为量特征,可用于有监督和无监督的机器学习:
* [**网站**](http://radimrehurek.com/gensim/)
* **打印时的版本**:3.4.0
......@@ -1096,7 +1096,7 @@ In: selector = SelectKBest(f_regression, k=1)
对于`In:`,我们选择`SelectKBest`类的一项功能(最具区别性的一项),该功能通过使用`.fit()`方法适合数据。 因此,我们借助通过对所有行和所选要素建立索引进行选择的操作将数据集简化为向量,可以通过`.get_support()`方法检索该索引。
由于目标值是量,因此,我们可以尝试查看输入(特征)和输出(房屋价值)之间是否存在线性关系。 当两个变量之间存在线性关系时,输出将以相同的比例量和方向不断对输入的变化做出反应:
由于目标值是量,因此,我们可以尝试查看输入(特征)和输出(房屋价值)之间是否存在线性关系。 当两个变量之间存在线性关系时,输出将以相同的比例量和方向不断对输入的变化做出反应:
```py
In: def plot_scatter(X,Y,R=None):
......
......@@ -131,7 +131,7 @@ In: X = iris[['sepal_length', 'sepal_width']]
![](img/a295947d-5326-40ac-9005-3f11abce5498.png)
在这种情况下,结果是一个Pandas DataFrame。 使用相同功能时,结果为何如此不同? 在第一种情况下,我们要求提供一列。 因此,输出为一维矢量(即Pandas系列)。 在第二个示例中,我们询问了多列,并获得了类似矩阵的结果(并且我们知道矩阵被映射为 pandas DataFrames)。 新手阅读者只需查看输出标题即可发现差异。 如果列被标记,则说明您正在处理 pandas DataFrame。 另一方面,如果结果是矢量,并且不显示标题,则为Pandas系列。
在这种情况下,结果是一个Pandas DataFrame。 使用相同功能时,结果为何如此不同? 在第一种情况下,我们要求提供一列。 因此,输出为一维向量(即Pandas系列)。 在第二个示例中,我们询问了多列,并获得了类似矩阵的结果(并且我们知道矩阵被映射为 pandas DataFrames)。 新手阅读者只需查看输出标题即可发现差异。 如果列被标记,则说明您正在处理 pandas DataFrame。 另一方面,如果结果是向量,并且不显示标题,则为Pandas系列。
到目前为止,我们已经从数据科学过程中学到了一些常见步骤; 加载数据集后,通常会分离特征和目标标签。
......@@ -232,7 +232,7 @@ In: bad_dataset = pd.read_csv('a_loading_example_2.csv',
# 处理大型数据集
如果要加载的数据集太大而无法容纳在内存中,则可以使用批处理机器学习算法来处理它,该算法一次只能处理部分数据。 如果您只需要数据样本(假设您要查看数据),则使用批处理方法也很有意义。 多亏了 Python,您实际上可以分块加载数据。 此操作也称为数据流,因为数据集作为连续流流入 DataFrame 或某些其他数据结构。 与以前的所有情况相反,该数据集已在独立步骤中完全加载到内存中。
如果要加载的数据集太大而无法容纳在内存中,则可以使用批量机器学习算法来处理它,该算法一次只能处理部分数据。 如果您只需要数据样本(假设您要查看数据),则使用批量方法也很有意义。 多亏了 Python,您实际上可以分块加载数据。 此操作也称为数据流,因为数据集作为连续流流入 DataFrame 或某些其他数据结构。 与以前的所有情况相反,该数据集已在独立步骤中完全加载到内存中。
对于Pandas,有两种方法可以分块和加载文件。 第一种方法是将数据集以相同大小的块加载; 每个块都是数据集的一部分,包含所有列和有限数量的行,最多不超过您在函数调用中实际设置的数量(`chunksize`参数)。 请注意,在这种情况下,`read_csv`函数的输出不是 pandas DataFrame,而是类似迭代器的对象。 实际上,要将结果存储在内存中,您需要迭代该对象:
......@@ -327,7 +327,7 @@ In: with open(iris_filename, 'rt') as data_stream:
在这里,代码更加简单,输出也更加简单,提供了一个包含序列中行值的列表。
至此,基于第二段代码,我们可以创建一个可从 for 循环迭代中调用的生成器。 这将从函数的批处理参数定义的大小的块中的文件中即时获取数据:
至此,基于第二段代码,我们可以创建一个可从 for 循环迭代中调用的生成器。 这将从函数的批参数定义的大小的块中的文件中即时获取数据:
```py
In: def batch_read(filename, batch=5):
......@@ -349,7 +349,7 @@ In: def batch_read(filename, batch=5):
yield(np.array(batch_output))
```
与上一个示例类似,由于`enumerate`函数包装的`csv.reader`函数与提取的数据列表以及示例编号(从零开始)一起提供,因此可以提取数据。 根据示例编号,批处理列表将附加到数据列表中,或者使用生成的`yield`函数返回到主程序。 重复此过程,直到整个文件被读取并批量返回为止:
与上一个示例类似,由于`enumerate`函数包装的`csv.reader`函数与提取的数据列表以及示例编号(从零开始)一起提供,因此可以提取数据。 根据示例编号,批列表将附加到数据列表中,或者使用生成的`yield`函数返回到主程序。 重复此过程,直到整个文件被读取并批量返回为止:
```py
In: import numpy as np
......@@ -368,7 +368,7 @@ In: import numpy as np
在第一个示例中,我们将使用 SQLite 和 SQL 语言存储一些数据并检索其过滤后的版本。 与其他数据库相比,SQLite 具有许多优点:它是独立的(所有数据都将存储在一个文件中),无服务器(Python 将提供存储,操作和访问数据的接口)且速度很快。 导入`sqlite3`程序包(它是 Python 堆栈的一部分,因此无论如何都不需要安装)后,您定义了两个查询:一个删除同名的先前数据表,另一个创建一个新表 能够保留日期,城市,温度和目的地数据(并且您使用整数,浮点数和 varchar 类型,它们对应于`int``float``str`)。
打开数据库(此时已创建,如果尚未在磁盘上创建的数据库)之后,执行两个查询,然后提交更改(通过提交,[实际上是在一个批处理中开始执行所有先前的数据库命令](https://www.sqlite.org/atomiccommit.html)):
打开数据库(此时已创建,如果尚未在磁盘上创建的数据库)之后,执行两个查询,然后提交更改(通过提交,[实际上是在一个批中开始执行所有先前的数据库命令](https://www.sqlite.org/atomiccommit.html)):
```py
In: import sqlite3
......@@ -977,7 +977,7 @@ In: from sklearn.feature_extraction.text import TfidfVectorizer
频率的总和为 1(或由于近似值而接近 1)。 发生这种情况是因为我们选择了`l1`规范。 在这种特定情况下,单词`frequency`是概率分布函数。 有时,增加稀有词与常见词之间的差异会很好。 在这种情况下,可以使用`l2`范数归一化特征向量。
量化文本数据的一种更有效的方法是使用`tf-idf`。 简而言之,您可以将构成文档的单词的术语频率乘以单词本身的逆文档频率(即,它出现在文档中的数量或对数缩放转换中)。 这对于突出显示有效描述每个文档的单词非常有用,这些单词是数据集中强大的区分元素:
量化文本数据的一种更有效的方法是使用`tf-idf`。 简而言之,您可以将构成文档的单词的术语频率乘以单词本身的逆文档频率(即,它出现在文档中的数量或对数缩放转换中)。 这对于突出显示有效描述每个文档的单词非常有用,这些单词是数据集中强大的区分元素:
```py
In: from sklearn.feature_extraction.text import TfidfVectorizer
......@@ -1135,7 +1135,7 @@ Python 提供了本机数据结构,例如列表和字典,您应尽量使用
NumPy 提供了具有以下属性的`ndarray`对象类(n 维数组):
* 它是内存最佳的(除了其他方面,还配置为以性能最佳的内存块布局将数据传输到 C 或 Fortran 例程)
* 它允许进行快速的线性代数计算(量化)和逐元素运算(广播),而无需使用带有 for 循环的迭代
* 它允许进行快速的线性代数计算(量化)和逐元素运算(广播),而无需使用带有 for 循环的迭代
* 诸如 SciPy 或 Scikit-learn 之类的关键库期望数组作为其功能正常运行的输入
所有这些都有一些限制。 实际上,`ndarray`对象具有以下缺点:
......@@ -1452,7 +1452,7 @@ In: fractions = np.linspace(start=0, stop=1, num=10)
growth = np.logspace(start=0, stop=1, num=10, base=10.0)
```
取而代之的是,统计分布,例如正态分布或均匀分布,对于系数的量或矩阵的初始化可能是方便的。
取而代之的是,统计分布,例如正态分布或均匀分布,对于系数的量或矩阵的初始化可能是方便的。
在这里可以看到 3 x 3 的标准化标准值矩阵(平均值= 0,标准= 1):
......@@ -1832,7 +1832,7 @@ In: np.insert(dataset, 3, bias, axis=1)
您只需要定义要插入的数组(`dataset`),位置(索引`3`),要插入的序列(在本例中为数组`bias`)以及沿其插入的轴 您想要操作插入(轴`1`是垂直轴)。
自然地,您可以通过确保要插入的数组与操作插入的尺寸对齐来插入整个数组(而不仅仅是量),例如偏移。 在此示例中,为了将相同的数组插入自身,我们必须将其作为插入的元素进行转置:
自然地,您可以通过确保要插入的数组与操作插入的尺寸对齐来插入整个数组(而不仅仅是量),例如偏移。 在此示例中,为了将相同的数组插入自身,我们必须将其作为插入的元素进行转置:
```py
In: np.insert(dataset, 3, dataset.T, axis=1)
......
......@@ -245,7 +245,7 @@ In: import matplotlib.pyplot as plt
# 主成分分析
**主成分分析****PCA**)是一种有助于定义更小且更相关的功能集的技术。 从 PCA 获得的新特征是当前特征的线性组合(即旋转),即使它们是二进制的。 输入空间旋转后,输出集的第一个量包含信号的大部分能量(或换句话说,其方差)。 第二个正交于第一个,它包含大部分剩余能量; 第三个与前两个向量正交,并且包含大部分剩余能量,依此类推。 就像通过将尽可能多的信息聚合到 PCA 产生的初始向量上来重构数据集中的信息一样。
**主成分分析****PCA**)是一种有助于定义更小且更相关的功能集的技术。 从 PCA 获得的新特征是当前特征的线性组合(即旋转),即使它们是二进制的。 输入空间旋转后,输出集的第一个量包含信号的大部分能量(或换句话说,其方差)。 第二个正交于第一个,它包含大部分剩余能量; 第三个与前两个向量正交,并且包含大部分剩余能量,依此类推。 就像通过将尽可能多的信息聚合到 PCA 产生的初始向量上来重构数据集中的信息一样。
在 AWGN 的理想​​情况下,初始向量包含输入信号的所有信息; 靠近末端的仅包含噪音。 此外,由于输出基础是正交的,因此您可以分解并合成输入数据集的近似版本。 能量是决定人能使用多少个基向量的关键参数。 由于该算法在本质上是用于奇异值分解的,因此在阅读有关 PCA 时经常会引用两个特征向量(基本向量)和特征值(与该向量相关的标准偏差)。 通常,输出集的基数是保证存在 95%(在某些情况下需要 90% 或 99%)输入能量(或方差)的基数。 对 PCA 的严格解释超出了本书的范围,因此,我们仅向您介绍有关如何在 Python 中使用此功能强大的工具的准则。
......@@ -318,7 +318,7 @@ In: pca_1c = PCA(n_components=1)
在这种情况下,输出能量较低(原始信号的 92.4%),并且输出点被添加到一维欧几里德空间中。 这可能不是一个很棒的功能简化步骤,因为许多具有不同标签的点被混合在一起。
最后,这是一个把戏。 为确保生成的输出集至少包含 95% 的输入能量,您可以在第一次调用 PCA 对象时指定该值。 可以使用以下代码获得等于两个量的结果:
最后,这是一个把戏。 为确保生成的输出集至少包含 95% 的输入能量,您可以在第一次调用 PCA 对象时指定该值。 可以使用以下代码获得等于两个量的结果:
```py
In: pca_95pc = PCA(n_components=0.95)
......@@ -917,14 +917,14 @@ ROC 曲线是一种图形化的方式,用于表达分类器的性能在所有
在必须预测实数或回归的任务中,许多误差度量均来自欧几里得代数:
* **平均绝对误差或 MAE**:这是预测值和实际值之间的差量的平均 L1 范数:
* **平均绝对误差或 MAE**:这是预测值和实际值之间的差量的平均 L1 范数:
```py
In: from sklearn.metrics import mean_absolute_error
mean_absolute_error([1.0, 0.0, 0.0], [0.0, 0.0, -1.0]) Out: 0.66666666666666663
```
* **均方误差或 MSE**:这是预测值和实际值之间的差量的平均 L2 范数:
* **均方误差或 MSE**:这是预测值和实际值之间的差量的平均 L2 范数:
```py
In: from sklearn.metrics import mean_squared_error
......@@ -955,7 +955,7 @@ In: from sklearn.datasets import load_digits
![](img/42ddf221-6f62-4f86-8040-882d84e8b11c.png)
这些数字实际上存储为矢量(从每个 8 x 8 图像的平整度得出),其矢量值为 0 到 16 之间的 64 个数值,代表每个像素的灰度色调:
这些数字实际上存储为向量(从每个 8 x 8 图像的平整度得出),其向量值为 0 到 16 之间的 64 个数值,代表每个像素的灰度色调:
```py
In: X[0] Out: array([0., 0., 5., 13., 9., 1., 0., 0., ...])
......
此差异已折叠。
此差异已折叠。
# 社交网络分析
*“社交网络分析”*(通常称为 **SNA**)创建模型并研究以网络形式存在的一组社交实体的关系。 实体可以是人,计算机或网页,关系可以是喜欢,链接或友谊(即,实体之间的连接)。
“社交网络分析”(通常称为 **SNA**)创建模型并研究以网络形式存在的一组社交实体的关系。 实体可以是人,计算机或网页,关系可以是喜欢,链接或友谊(即,实体之间的连接)。
在本章中,您将了解以下内容:
......@@ -12,7 +12,7 @@
基本上,图是一种能够表示对象集合中的关系的数据结构。 在这种范式下,对象是图的节点,关系是图的链接(或边)。 如果链接具有方向(在概念上,它们就像城市的单向街道),则对图形进行定向。 否则,该图是无向的。 下表提供了众所周知的图形的示例:
| **图表示例** | **类型** | **节点** | **边线** |
| **图表示例** | **类型** | **节点** | **边** |
| 全球资讯网 | 导演 | 网页 | 链接 |
| Facebook | 无向 | 人们 | 友谊 |
| 推特 | 导演 | 人们 | 追随者 |
......@@ -129,7 +129,7 @@ In: nx.to_numpy_matrix(G) Out: matrix([[ 0., 1., 0., 1.],
![](img/ea88aeb5-d78f-4d2e-bf84-7de068c2287a.png)
当然,如果要加载 NetworkX 图,则可以使用相反的功能(将函数名称中的*从*更改为*到*),并且可以加载 NetworkX 列表,边列表以及 NumPy,SciPy 和`pandas`结构的字典中的图形。**
当然,如果要加载 NetworkX 图,则可以使用相反的功能(将函数名称中的`from`更改为`to`),并且可以加载 NetworkX 列表,边列表以及 NumPy,SciPy 和`pandas`结构的字典中的图形。
图中每个节点的重要度量是其度。 在无向图中,节点的度数表示该节点具有的链接数。 对于有向图,度有两种类型:入度和出度。 这些分别计算节点的入站和出站链接。
......@@ -214,7 +214,7 @@ In: paths = list(nx.all_pairs_shortest_path(G))
9: [5, 7, 8, 9]}
```
不出所料,`5`与所有其他节点之间的路径以`5`本身开始。 请注意,此结构也是字典,因此,为了获得节点`a``b`之间的最短路径,可以将其称为 **path [a] [b]**。 在大型网络上,请谨慎使用此功能。 实际上,在后台,它以 *O(N <sup>2</sup> )*的计算复杂度来计算所有成对的最短路径。
不出所料,`5`与所有其他节点之间的路径以`5`本身开始。 请注意,此结构也是字典,因此,为了获得节点`a``b`之间的最短路径,可以将其称为`path[a][b]`。 在大型网络上,请谨慎使用此功能。 实际上,在后台,它以`O(N²)`的计算复杂度来计算所有成对的最短路径。
# 节点中心性的类型
......@@ -271,7 +271,7 @@ In: nx.closeness_centrality(G) Out: {0: 0.5294117647058824,
具有高度接近中心性的节点是`5``6``3`。 实际上,它们是存在于网络中间的节点,平均而言,它们可以通过几跳到达所有其他节点。 最低分属于节点`9`。 实际上,它到达所有其他节点的平均距离相当高。
* **谐波中心**:此度量类似于接近中心点,但不是距离的倒数之和的倒数,而是距离的倒数的总和。 这样做强调了距离的极限。 让我们看看我们的网络中的谐波距离是什么样的:
* **谐波中心**:此度量类似于接近中心点,但不是距离的倒数之和的倒数,而是距离的倒数的总和。 这样做强调了距离的极限。 让我们看看我们的网络中的谐波距离是什么样的:
```py
In: nx.harmonic_centrality(G) Out: {0: 6.083333333333333,
......
......@@ -15,7 +15,7 @@
**深度学习**是使用神经网络的经典机器学习方法的扩展:我们可以堆叠数百层,而不是构建几层网络(所谓的*浅层网络*) 创建一个精巧但功能更强大的学习者。 深度学习是当今最流行的**人工智能****AI**)方法之一,因为它非常有效并且有助于解决模式识别中的许多问题,例如对象或序列识别。 使用标准的机器学习工具似乎牢不可破。
神经网络的思想来自人类的中枢神经系统,其中将能够处理简单信息的多个节点(或*神经元)*连接在一起以创建能够处理复杂信息的网络。 实际上,神经网络之所以这么称呼是因为它们可以自动和自适应地学习模型的权重,并且在足够复杂的网络体系结构下,它们能够近似任何非线性函数。 在深度学习中,节点通常称为单元或神经元。
神经网络的思想来自人类的中枢神经系统,其中将能够处理简单信息的多个节点(或*神经元*连接在一起以创建能够处理复杂信息的网络。 实际上,神经网络之所以这么称呼是因为它们可以自动和自适应地学习模型的权重,并且在足够复杂的网络体系结构下,它们能够近似任何非线性函数。 在深度学习中,节点通常称为单元或神经元。
让我们看看如何构建深度架构及其组成部分。 我们将从一个由三层组成的分类问题的小型深度架构开始,如下图所示:
......@@ -42,7 +42,7 @@
这个过程看起来非常简单,它由多个令人尴尬的并行任务组成。 解释的最后一个缺失点是激活功能:它是什么,为什么需要它? 激活函数有助于使二元决策更加可分离(它使决策边界成为非线性,从而有助于更好地分离示例),并且它是每个单元的属性(或属性); 理想情况下,每个单元应该具有不同的激活功能,尽管通常将它们按层分组。
典型的激活函数是 S 形,双曲正切和`softmax`(用于分类问题)函数,尽管目前最流行的函数是**整流线性单元**(或 **ReLU**,其输出是 0 和输入之间的最大值(其中输入是上一层输出和连接权重之间的点积)。
典型的激活函数是 S 形,双曲正切和`softmax`(用于分类问题)函数,尽管目前最流行的函数是**整流线性单元**(或 **ReLU**),其输出是 0 和输入之间的最大值(其中输入是上一层输出和连接权重之间的点积)。
激活函数(单位数量和隐藏层数量)是深层网络的参数,科学家应该对其进行优化以获得更好的性能。
......@@ -89,7 +89,7 @@ In: N_CLASSES = 43
1. 导入处理所需的模块。 最重要的是 Scikit-learn(即 sklearn),其中包含处理图像的功能。
2. 我们一个接一个地读取图像。 标签包含在路径中。 例如,图像`GTSRB/Final_Training/Images/00000/00003_00024.ppm`的标签为`00000`,即`0`; 并且图像`GTSRB/Final_Training/Images/00025/00038_00005.ppm`带有标签`00025`,即`25`。 标签存储为标记编码的数组,该数组是一个 43 单元长的数组,只有一个值为`1`的数组(所有其他均为`0`)。
3. 图像以 **PPM****Portable PixMap**)格式存储,这是一种将像素存储在图像中的无损方式。 Scikit 图像或只是 [skimage](https://scikit-image.org/) 可以使用功能`imread`读取该格式。 如果您的系统上尚未安装 Scikit 映像,只需在 shell 中键入以下内容:`conda install scikit-image``pip install -U scikit-image`。 返回的对象是 3D NumPy 数组。
3. 图像以 **PPM****可移植像素图**)格式存储,这是一种将像素存储在图像中的无损方式。 Scikit 图像或只是 [skimage](https://scikit-image.org/) 可以使用功能`imread`读取该格式。 如果您的系统上尚未安装 Scikit 映像,只需在 shell 中键入以下内容:`conda install scikit-image``pip install -U scikit-image`。 返回的对象是 3D NumPy 数组。
4. 然后将包含图像像素表示的 3D NumPy 数组(具有三个通道-红色,蓝色和绿色)转换为灰度。 在这里,我们首先转换为 LAB 颜色空间(请参见[这个页面](https://hidefcolor.com/blog/color-management/what-is-lab-color-space)-该颜色空间比线性颜色更具感知性) 其他,这意味着颜色值的相同变化量应产生相同视觉重要性的影响),然后保留第一个通道(包含亮度)。 再次,此操作很容易使用 skimage 完成。 结果,我们有一个包含图像像素的一维 NumPy 数组。
5. 最终,再次使用 Skimage 函数将图像调整为 32x32 像素格式。
......@@ -197,8 +197,8 @@ Out: (29406, 32, 32, 1)
然后编译模型,最后将其拟合到训练数据。 在此操作期间,我们选择了以下内容:
* **优化器**:SGD,最简单的一种
* **批处理大小**:每批 32 张图像
* **期数**:10
* **批大小**:每批 32 张图像
* **期数**:10
这是将生成我们刚刚描述的模型的代码:
......@@ -292,11 +292,11 @@ Out:
分类似乎已经很好了。 我们可以做得更好,避免过度拟合吗? 是的,这是我们可以使用的:
* **脱落层**:这等效于正则化,并且可以防止过度拟合。 基本上,在训练的每个步骤中,都会停用一部分单元,因此该层的输出不会过分依赖其中的一些单元。
* **BatchNormalization 层**:通过减去批次平均值并将其除以标准偏差,此 z 标准化层。 这对于更新数据很有用,并且在每个步骤都会放大/衰减信号。
* **MaxPooling**:这是一个非线性变换,用于通过对内核下的每个区域应用最大滤波器来对输入进行下采样。 用于选择最大功能,该功能在同一类中的位置可能略有不同。
* **丢弃层**:这等效于正则化,并且可以防止过度拟合。 基本上,在训练的每个步骤中,都会停用一部分单元,因此该层的输出不会过分依赖其中的一些单元。
* **批量规范化层**:通过减去批次平均值并将其除以标准偏差,此 z 标准化层。 这对于更新数据很有用,并且在每个步骤都会放大/衰减信号。
* **最大池化**:这是一个非线性变换,用于通过对内核下的每个区域应用最大滤波器来对输入进行下采样。 用于选择最大功能,该功能在同一类中的位置可能略有不同。
除此之外,总是有改变深层网络和训练属性的空间。 也就是说,优化程序(及其参数),批处理大小和时期数。 在下一个单元格中,这里是具有以下几层的改进的深层网络:
除此之外,总是有改变深层网络和训练属性的空间。 也就是说,优化程序(及其参数),批大小和时期数。 在下一个单元格中,这里是具有以下几层的改进的深层网络:
1. 卷积层,具有 32 个 3x3 滤镜和 ReLU 激活
2. BatchNormalization 层
......@@ -409,7 +409,7 @@ Out:
首先下载一些图像进行测试。 在以下示例中,我们将使用 Caltech 提供的数据集,[该数据集可在此处使用](http://www.vision.caltech.edu/Image_Datasets/Caltech101/)
我们要感谢数据集的作者,并建议阅读他们的论文: *L. Fei-Fei,R。Fergus 和 P. Perona。 一键式学习对象类别。* *IEEE Trans。 模式识别和机器智能*
我们要感谢数据集的作者,并建议阅读他们的论文:`L. Fei-Fei, R. Fergus and P. Perona. One-Shot learning of object categories. IEEE Trans. Pattern Recognition and Machine Intelligence`
它包含 101 个类别的几张图像,并以`tar.gz`格式显示。
......@@ -542,9 +542,9 @@ Out: (1, 2048)
* **将英语文本翻译为法语**:在这种情况下,输入序列将转换为另一个序列
* **Chatbot**:在这种情况下,输入和输出都是序列(使用相同语言)
* **聊天机器人**:在这种情况下,输入和输出都是序列(使用相同语言)
对于此示例,让我们做些简单的事情。 我们将尝试检测电影评论的情绪。 在此特定示例中,输入数据是单词序列(和顺序计数!),输出是二进制标签(即情感*为正**为负*)。
对于此示例,让我们做些简单的事情。 我们将尝试检测电影评论的情绪。 在此特定示例中,输入数据是单词序列(和顺序计数!),输出是二进制标签(即情感*正*或为*负*)。
让我们开始导入数据集。 幸运的是,Keras 已经包含了该数据集,并且已经进行了预索引。 也就是说,每个评论不是由单词组成,而是由字典索引组成。 另外,可以只选择最重要的单词,并使用此代码选择包含最重要的`25000`单词的字典:
......
......@@ -19,16 +19,16 @@
处理大数据不仅仅是大小问题; 这实际上是一个多方面的现象。 实际上,根据 **3V 模型**(体积,速度和变化),可以使用三个(正交)标准对在大数据上运行的系统进行分类:
* 要考虑的第一个标准是系统处理数据所达到的**速度**。 尽管几年前,速度还是用来表示系统处理批处理的速度,但如今,速度表示系统是否可以提供流数据的实时输出。
* 要考虑的第一个标准是系统处理数据所达到的**速度**。 尽管几年前,速度还是用来表示系统处理批的速度,但如今,速度表示系统是否可以提供流数据的实时输出。
* 第二个标准是**体积**; 也就是说,可以处理多少信息。 它可以用行数或特征数来表示,也可以仅用字节数表示。 在流数据中,卷指示到达系统的数据的吞吐量。
* 最后一个标准是**品种**; 即数据源的类型。 几年前,这种类型受到结构化数据集的限制,但如今,数据可以结构化(表,图像等),半结构化(JSON,XML 等)和非结构化(网页, 社交数据,等等)。 通常,大数据系统会尝试处理尽可能多的相关源并将各种源混合在一起。
* 最后一个标准是**种类**; 即数据源的类型。 几年前,这种类型受到结构化数据集的限制,但如今,数据可以结构化(表,图像等),半结构化(JSON,XML 等)和非结构化(网页, 社交数据,等等)。 通常,大数据系统会尝试处理尽可能多的相关源并将各种源混合在一起。
除了这些标准,最近几年还出现了许多其他 V,它们试图解释大数据的其他特征。 其中一些如下:
* **准确**:提供数据中包含的异常,偏差和噪声的指示; 最终表明其准确性
* **准确**:提供数据中包含的异常,偏差和噪声的指示; 最终表明其准确性
* **波动率**:指示可以将数据用于提取有意义的信息的时间
* **有效**:数据的正确性
* **值**:根据数据指示投资回报率
* **有效**:数据的正确性
* **值**:根据数据指示投资回报率
近年来,所有 V 都急剧增加。 现在,许多公司发现他们保留的数据具有可被货币化的巨大价值,并且他们希望从中提取信息。 技术挑战已经转向具有足够的存储和处理能力,以便能够快速,大规模并使用不同的输入数据流来提取有意义的见解。
......@@ -45,7 +45,7 @@
* 如果处理节点死亡,我们将无法跟踪其正在执行的进程,从而很难在另一个节点上恢复处理。
* 如果网络出现故障,则在恢复正常后很难预测这种情况。
崩溃事件(甚至不止一个)很可能发生,这是一个事实,要求必须事先考虑这种情况并进行适当处理,以确保对数据进行操作的连续性。 此外,当使用便宜的硬件或更大的群集时,几乎可以肯定至少有一个节点将发生故障。 到目前为止,绝大多数集群框架都使用名为 *Divide et Impera* 的方法(拆分和征服):
崩溃事件(甚至不止一个)很可能发生,这是一个事实,要求必须事先考虑这种情况并进行适当处理,以确保对数据进行操作的连续性。 此外,当使用便宜的硬件或更大的群集时,几乎可以肯定至少有一个节点将发生故障。 到目前为止,绝大多数集群框架都使用名为*分治*的方法(拆分和征服):
* 有用于数据节点的*专用*模块和用于数据处理节点(也称为工作器)的其他一些专用模块。
* 数据跨数据节点复制,一个节点为主节点,确保写入和读取操作均成功。
......@@ -67,15 +67,15 @@
# Hadoop 分布式文件系统
**Hadoop 分布式文件系统(HDFS)**是容错的分布式文件系统,旨在在低成本硬件上运行,并且能够处理非常大的数据集(数百 PB 到 EB 级) )。 尽管 HDFS 需要快速的网络连接来跨节点传输数据,但是延迟不能像传统文件系统中那样低(它可能在几秒钟的时间内)。 因此,HDFS 被设计用于批处理和高吞吐量。 每个 HDFS 节点都包含文件系统数据的一部分; 在其他实例中也将复制相同的数据,这可确保高吞吐量访问和容错。
**Hadoop 分布式文件系统(HDFS)**是容错的分布式文件系统,旨在在低成本硬件上运行,并且能够处理非常大的数据集(数百 PB 到 EB 级) )。 尽管 HDFS 需要快速的网络连接来跨节点传输数据,但是延迟不能像传统文件系统中那样低(它可能在几秒钟的时间内)。 因此,HDFS 被设计用于批和高吞吐量。 每个 HDFS 节点都包含文件系统数据的一部分; 在其他实例中也将复制相同的数据,这可确保高吞吐量访问和容错。
HDFS 的体系结构是主从结构。 如果主服务器(称为 **NameNode**)发生故障,则表明有一个辅助节点/备份节点可以控制。 所有其他实例都是从属(**DataNodes**); 如果其中一个发生故障,这并不是问题,因为 HDFS 就是在设计时考虑到这一点的,因此不会丢失任何数据(进行冗余复制),并且可以将操作迅速重新分配给尚存的节点。 **数据节点**包含数据块:HDFS 中保存的每个文件被分解成块(或块),每个文件通常为 64 MB,然后在一组 **DataNodes** 中进行分发和复制。 **NameNode** 仅存储分布式文件系统中文件的元数据; 它不存储任何实际数据,而只是存储有关如何访问其管理的多个 **DataNodes** 中文件的正确指示。
HDFS 的体系结构是主从结构。 如果主服务器(称为**名称节点**)发生故障,则表明有一个辅助节点/备份节点可以控制。 所有其他实例都是从属(**数据节点**); 如果其中一个发生故障,这并不是问题,因为 HDFS 就是在设计时考虑到这一点的,因此不会丢失任何数据(进行冗余复制),并且可以将操作迅速重新分配给尚存的节点。 **数据节点**包含数据块:HDFS 中保存的每个文件被分解成块(或块),每个文件通常为 64 MB,然后在一组**数据节点**中进行分发和复制。 **名称节点**仅存储分布式文件系统中文件的元数据; 它不存储任何实际数据,而只是存储有关如何访问其管理的多个**数据节点**中文件的正确指示。
请求读取文件的客户端必须首先联系 **NameNode**,它将返回一个表,其中包含块及其位置的有序列表(如 **DataNodes** 中所示)。 此时,客户端应分别与 **DataNodes** 联系,下载所有块并重建文件(通过将块附加在一起)。
请求读取文件的客户端必须首先联系**名称节点**,它将返回一个表,其中包含块及其位置的有序列表(如**数据节点**中所示)。 此时,客户端应分别与**数据节点**联系,下载所有块并重建文件(通过将块附加在一起)。
要写入文件,客户端应首先联系 **NameNode**,后者将首先决定如何处理请求,然后更新其记录并使用 **DataNodes** 的有序列表回复客户端 ]写入文件每个块的位置。 客户端现在将根据 **NameNode** 答复中的报告,将块联系并上传到 **DataNodes**。 命名空间查询(例如,列出目录内容,创建文件夹等)由 **NameNode** 通过访问其元数据信息完全处理。
要写入文件,客户端应首先联系**名称节点**,后者将首先决定如何处理请求,然后更新其记录并使用**数据节点**的有序列表回复客户端 写入文件每个块的位置。 客户端现在将根据**名称节点**答复中的报告,将块联系并上传到**数据节点**。 命名空间查询(例如,列出目录内容,创建文件夹等)由**名称节点**通过访问其元数据信息完全处理。
此外,**NameNode** 还负责正确处理 **DataNode** 故障(如果未接收到心跳数据包,则标记为死),并将其数据复制到其他节点。
此外,**名称节点**还负责正确处理**数据节点**故障(如果未接收到心跳数据包,则标记为死),并将其数据复制到其他节点。
尽管这些操作很长且难以实现,但是由于许多库和 HDFS Shell,它们对用户完全透明。 在 HDFS 上进行操作的方式与当前在文件系统上进行的操作非常相似,这是 Hadoop 的一大优势:隐藏复杂性并让用户简单地使用它。
......@@ -85,10 +85,10 @@ HDFS 的体系结构是主从结构。 如果主服务器(称为 **NameNode**
具体来说,这是 MapReduce 用于 Hadoop 实现的步骤:
* **数据分块器**:从文件系统读取数据并将其拆分为块。 块是输入数据集的一部分,通常是固定大小的块(例如,从 **DataNode** 读取的 HDFS 块)或另一个更合适的拆分。 例如,如果我们要计算文本文件中的字符,单词和行数,则很好的拆分可以是一行文本。
* **映射器**:从每个块中生成一系列键值对。 每个映射器实例将相同的映射函数应用于不同的数据块。 继续前面的示例,对于每一行,在此步骤中生成了三个键值对-一个键值对包含该行中的字符数(键可以简单地是*字符*字符串),其中一个包含数字 个单词(在这种情况下,密钥必须不同,所以假设*个单词*),其中一个包含行数,该行数始终为 1(在这种情况下,密钥可以是*行)* )。
* **混洗器**:从可用键的数量和可用的化简器的数量,混洗器将具有相同键的所有键-值对分配给同一异化器。 通常,此操作是计算键的哈希值,将其除以精简器的数量,然后使用余数来指出特定的精简器。 这应确保每个异径管有足够数量的钥匙。 该功能不是用户可编程的,而是由 MapReduce 框架提供的。
* **简化器**:每个简化器都接收一组特定键的所有键值对,并且可以产生零个或多个聚合结果。 在该示例中,所有与*单词*键相关的值都到达简化器; 它的工作只是总结所有价值。 其他键也一样,这将产生三个最终值:字符数,单词数和行数。 请注意,这些结果可能在不同的减速器上。
* **数据分块器**:从文件系统读取数据并将其拆分为块。 块是输入数据集的一部分,通常是固定大小的块(例如,从**数据节点**读取的 HDFS 块)或另一个更合适的拆分。 例如,如果我们要计算文本文件中的字符,单词和行数,则很好的拆分可以是一行文本。
* **映射器**:从每个块中生成一系列键值对。 每个映射器实例将相同的映射函数应用于不同的数据块。 继续前面的示例,对于每一行,在此步骤中生成了三个键值对-一个键值对包含该行中的字符数(键可以简单地是*字符串*),其中一个包含单词个数(在这种情况下,密钥必须不同,所以假设是*单词*),其中一个包含行数,该行数始终为 1(在这种情况下,密钥可以是*行*)。
* **打乱器**:从可用键的数量和可用的化简器的数量,混洗器将具有相同键的所有键-值对分配给同一异化器。 通常,此操作是计算键的哈希值,将其除以精简器的数量,然后使用余数来指出特定的精简器。 这应确保每个异径管有足够数量的钥匙。 该功能不是用户可编程的,而是由 MapReduce 框架提供的。
* **归约器**:每个简化器都接收一组特定键的所有键值对,并且可以产生零个或多个聚合结果。 在该示例中,所有与*单词*键相关的值都到达简化器; 它的工作只是总结所有价值。 其他键也一样,这将产生三个最终值:字符数,单词数和行数。 请注意,这些结果可能在不同的减速器上。
* **输出编写器**:减速器的输出写在文件系统(或 HDFS)上。 在默认的 Hadoop 配置中,每个 reducer 都会写入一个文件(`part-r-00000`是第一个 reducer 的输出,`part-r-00001`是第二个 reducer 的输出,依此类推)。 要在文件上显示完整的结果列表,应将所有结果串联起来。
在视觉上,可以简单地传达和理解此操作,如下所示:
......@@ -101,7 +101,7 @@ HDFS 的体系结构是主从结构。 如果主服务器(称为 **NameNode**
# 介绍 Apache Spark
**Apache Spark** 是 Hadoop 的演进,并在最近几年变得非常流行。 与 Hadoop 及其以 Java 和批处理为重点的设计相比,Spark 能够以快速简便的方式生成迭代算法。 此外,它具有用于多种编程语言的非常丰富的 API 套件,并且本身支持许多不同类型的数据处理(机器学习,流传输,图形分析,SQL 等)。
**Apache Spark** 是 Hadoop 的演进,并在最近几年变得非常流行。 与 Hadoop 及其以 Java 和批为重点的设计相比,Spark 能够以快速简便的方式生成迭代算法。 此外,它具有用于多种编程语言的非常丰富的 API 套件,并且本身支持许多不同类型的数据处理(机器学习,流传输,图形分析,SQL 等)。
Apache Spark 是一个集群框架,旨在用于大数据的快速通用处理。 速度的提高之一来自以下事实:与 Hadoop,MapReduce 和 HDFS 一样,每项工作之后的数据都保留在内存中,而不是存储在文件系统中(除非您愿意这样做)。 由于内存提供的延迟和带宽比物理磁盘更具性能,因此这种事情使迭代作业(例如群集 K-means 算法)越来越快。 因此,运行 Spark 的集群需要为每个节点配备大量 RAM。
......@@ -488,7 +488,7 @@ Spark 集群中可以共享的其他变量是累加器。 累加器是只写变
所需步骤如下:
1. 首先,我们从网上下载要处理的文本文件,由古腾堡计划提供的*亚瑟·柯南·道尔爵士的《福尔摩斯历险记》*
1. 首先,我们从网上下载要处理的文本文件,由古腾堡计划提供的亚瑟·柯南·道尔爵士的《福尔摩斯历险记》
```py
In: import urllib.request
......@@ -597,7 +597,7 @@ Out: [('DummyClassifier', 0.33333333333333331),
('SGDClassifier', 0.85333333333333339)]
```
如预期的那样,输出中仅包含*实数*分类器。 让我们看看哪些分类器产生了错误。 毫不奇怪,这里我们从前面的输出中发现了两个缺失的:
如预期的那样,输出中仅包含*真实*分类器。 让我们看看哪些分类器产生了错误。 毫不奇怪,这里我们从前面的输出中发现了两个缺失的:
```py
In: print("The errors are:", errAccum.value)
......@@ -1150,7 +1150,7 @@ Out: Row(features=SparseVector(41, {1: 8.0, 7: 181.0, 15: 1.0, 16: 2.0, 22:
# 培训学习者
最后,我们到达了任务的热点:训练分类器。 分类器包含在`pyspark.ml.classification`包中,对于本示例,我们使用随机森林。 对于 Spark 2.3.1,可以在[这个页面](https://spark.apache.org/docs/2.3.1/ml-classification-regression.html)中找到可用的算法的广泛列表。 算法列表非常完整,包括线性模型,SVM,朴素贝叶斯和树合奏。 请注意,并非所有这些工具都能够处理多类问题,并且可能具有不同的参数。 始终检查与使用版本有关的文档。 除分类器外,Spark 2.3.1 中使用 Python 接口实现的其他学习器如下:
最后,我们到达了任务的热点:训练分类器。 分类器包含在`pyspark.ml.classification`包中,对于本示例,我们使用随机森林。 对于 Spark 2.3.1,可以在[这个页面](https://spark.apache.org/docs/2.3.1/ml-classification-regression.html)中找到可用的算法的广泛列表。 算法列表非常完整,包括线性模型,SVM,朴素贝叶斯和树集成。 请注意,并非所有这些工具都能够处理多类问题,并且可能具有不同的参数。 始终检查与使用版本有关的文档。 除分类器外,Spark 2.3.1 中使用 Python 接口实现的其他学习器如下:
* 群集(`pyspark.ml.clustering`程序包):KMeans
* 推荐人(`pyspark.ml.recommendation`软件包):ALS(协作过滤推荐器,基于交替最小二乘法)
......@@ -1423,7 +1423,7 @@ In: pipeline_to_clf = Pipeline(
在此示例中,我们要设置分类器的一些参数,这些参数在整个交叉验证过程中都不会改变。 就像 scikit-learn 一样,它们是在创建`classification`对象时设置的(在这种情况下,是列名,种子和最大数量的容器)。
然后,借助网格生成器,我们决定应为交叉验证算法的每次迭代更改哪些参数。 在此示例中,我们要检查分类性能是否将森林中每棵树的最大深度从`3`更改为`12`(增加 3),并将森林中的树数从 20 或 50 改变为最后。 设置网格图,我们要测试的分类器和折叠次数后,启动交叉验证(使用`fit`方法)。 参数评估器是必不可少的:它会告诉我们哪种是交叉验证后保持的最佳模型。 请注意,此操作可能需要 15-20 分钟才能运行(在引擎盖下,训练并测试了 *4 * 2 * 3 = 24* 模型):
然后,借助网格生成器,我们决定应为交叉验证算法的每次迭代更改哪些参数。 在此示例中,我们要检查分类性能是否将森林中每棵树的最大深度从`3`更改为`12`(增加 3),并将森林中的树数从 20 或 50 改变为最后。 设置网格图,我们要测试的分类器和折叠次数后,启动交叉验证(使用`fit`方法)。 参数评估器是必不可少的:它会告诉我们哪种是交叉验证后保持的最佳模型。 请注意,此操作可能需要 15-20 分钟才能运行(在引擎盖下,训练并测试了`4 * 2 * 3 = 24`模型):
```py
In: from pyspark.ml.tuning import ParamGridBuilder, CrossValidator
......
......@@ -491,8 +491,8 @@ IPython 内核(Jupyter 的 Python 内核,因为 Jupyter 可以运行许多
# 别害羞,接受真正的挑战
如果您想做一些可以使您的 Python 编码能力达到不同水平的事情,我们建议您去挑战 Kaggle。 **Kaggle**[www.kaggle.com](http://www.kaggle.com)是用于预测建模和分析竞赛的平台,在数据中应用了竞争性编程(参与者尝试根据提供的规范进行编程)的思想 向参与者提出具有挑战性的数据问题,并要求他们提供可能在测试集上评估的解决方案,从而实现科学。 测试集的结果部分是公开的,部分是私有的。
如果您想做一些可以使您的 Python 编码能力达到不同水平的事情,我们建议您去挑战 Kaggle。 [**Kaggle**](http://www.kaggle.com) 是用于预测建模和分析竞赛的平台,在数据中应用了竞争性编程(参与者尝试根据提供的规范进行编程)的思想 向参与者提出具有挑战性的数据问题,并要求他们提供可能在测试集上评估的解决方案,从而实现科学。 测试集的结果部分是公开的,部分是私有的。
对于 Python 学习者来说,最有趣的部分是有机会参加没有明显解决方案的实际问题,这需要您编写一些代码以提出可能的问题解决方案,甚至是简单或幼稚的解决方案(我们建议您从头开始) 参与复杂的解决方案之前)。 这样,学习者将发现有趣的教程,基准测试代码,有用的数据科学家社区,以及其他数据科学家或 Kaggle 本身在其博客中提出的一些非常聪明的解决方案。 *]( [blog.kaggle.com](http://blog.kaggle.com/) )。*
对于 Python 学习者来说,最有趣的部分是有机会参加没有明显解决方案的实际问题,这需要您编写一些代码以提出可能的问题解决方案,甚至是简单或幼稚的解决方案(我们建议您从头开始) 参与复杂的解决方案之前)。 这样,学习者将发现有趣的教程,基准测试代码,有用的数据科学家社区,以及其他数据科学家或 [Kaggle](http://blog.kaggle.com/) 本身在其博客中提出的一些非常聪明的解决方案。
您可能想知道如何为自己找到正确的挑战。 只需在[这个页面](https://www.kaggle.com/competitions)上查看过去和现在的比赛,并寻找每一个有知识作为奖励的比赛。 您会惊讶地发现一个理想的阶段来学习其他数据科学家如何用 Python 进行编码,并且您可以立即应用从本书中学到的知识。
\ No newline at end of file
......@@ -313,7 +313,7 @@ def do_training(train, train_labels, test, test_labels, num_classes):
[您可以在此处找到代码文件](https://github.com/DTAIEB/Thoughtful-Data-Science/blob/master/chapter%206/sampleCode2.py)
`classifier.train`方法使用`train_input_fn`方法,该方法负责提供训练输入数据(又称地面实况)作为小批处理,返回`tf.data.Dataset``(features, labels)`的元组。 我们的代码也正在使用`classifier.evaluate`执行模型评估,以通过根据测试数据集对模型评分并在给定标签中比较结果来验证准确性。 然后将结果作为函数输出的一部分返回。
`classifier.train`方法使用`train_input_fn`方法,该方法负责提供训练输入数据(又称地面实况)作为小批,返回`tf.data.Dataset``(features, labels)`的元组。 我们的代码也正在使用`classifier.evaluate`执行模型评估,以通过根据测试数据集对模型评分并在给定标签中比较结果来验证准确性。 然后将结果作为函数输出的一部分返回。
此方法需要与`train_input_fn`相似的`eval_input_fn`方法,除了我们在评估期间不使数据集可重复。 由于这两种方法共享大多数相同的代码,因此我们使用一种称为`input_fn`的辅助方法,这两种方法都使用适当的标志来调用该方法:
......
......@@ -604,15 +604,15 @@ id: b621e268-f21d-4eef-b6cd-cb0bc66e53c4
**注意**:我们将在*第 3 部分–创建实时仪表板 PixieApp* 中展示如何构建此 PixieApp。
## 从 Parquet 文件创建批处理 DataFrame
## 从 Parquet 文件创建批 DataFrame
### 注意
**注意**:对于本章的其余部分,我们将批处理 Spark DataFrame 定义为经典的 Spark DataFrame,它是非流式的。
**注意**:对于本章的其余部分,我们将批 Spark DataFrame 定义为经典的 Spark DataFrame,它是非流式的。
此流计算流程的最后一步是创建一个或多个批处理 DataFrame,我们可以将其用于构建分析和数据可视化。 我们可以认为这最后一步是对数据进行快照以进行更深入的分析。
此流计算流程的最后一步是创建一个或多个批 DataFrame,我们可以将其用于构建分析和数据可视化。 我们可以认为这最后一步是对数据进行快照以进行更深入的分析。
有两种方法可以通过编程方式从 Parquet 文件中加载批处理 DataFrame:
有两种方法可以通过编程方式从 Parquet 文件中加载批 DataFrame:
* 使用`spark.read`(注意,我们不像以前那样使用`spark.readStream`):
......@@ -655,7 +655,7 @@ display(parquet_batch_df)
该图表按来源显示与棒球相关的推文数量
在本节中,我们已经看到了如何使用 Tweepy 库创建 Twitter 流,清理原始的数据并将其存储在 CSV 文件中,创建 Spark Streaming DataFrame,对其运行流查询并将其存储在 一个 Parquet 数据库,从 Parquet 文件创建一个批处理 DataFrame,并使用 PixieDust `display()`可视化数据。
在本节中,我们已经看到了如何使用 Tweepy 库创建 Twitter 流,清理原始的数据并将其存储在 CSV 文件中,创建 Spark Streaming DataFrame,对其运行流查询并将其存储在 一个 Parquet 数据库,从 Parquet 文件创建一个批 DataFrame,并使用 PixieDust `display()`可视化数据。
### 注意
......@@ -884,7 +884,7 @@ Batch: 2
+----------+---------------+---------------+---------+------------+-------------+
```
最后,我们使用 Parquet `output`接收器运行结构化查询,创建一个批处理 DataFrame,并使用 PixieDust `display()`浏览数据以显示例如按情感分类的 tweets 数(`positive`,`negative`,`neutral`)由实体聚类,如下图所示:
最后,我们使用 Parquet `output`接收器运行结构化查询,创建一个批 DataFrame,并使用 PixieDust `display()`浏览数据以显示例如按情感分类的 tweets 数(`positive`,`negative`,`neutral`)由实体聚类,如下图所示:
![Getting started with the IBM Watson Natural Language Understanding service](img/00154.jpeg)
......@@ -1067,7 +1067,7 @@ TweetInsightApp().run()
Twitter 情绪仪表板的欢迎屏幕
在`Go`按钮中,我们使用用户提供的查询字符串调用`search_query`路由。 在此路由中,我们首先启动各种流,并从 Parquet 数据库所在的输出目录中创建一个存储在名为`parquet_df`的类变量中的批处理 DataFrame。 然后我们返回由三个小部件组成的 HTML 片段,其中显示了以下指标:
在`Go`按钮中,我们使用用户提供的查询字符串调用`search_query`路由。 在此路由中,我们首先启动各种流,并从 Parquet 数据库所在的输出目录中创建一个存储在名为`parquet_df`的类变量中的批 DataFrame。 然后我们返回由三个小部件组成的 HTML 片段,其中显示了以下指标:
* 实体聚集的三种情感中的每一种的条形图
* 折线图子图显示了按情感分布的推文
......@@ -1135,7 +1135,7 @@ print("Number of tweets received: {}".format(streams_manager.twitter_stream.list
从前面的代码中有多个注意事项:
* 当我们尝试加载`parquet_df`批处理 DataFrame 时,Parquet 文件的输出目录可能未准备好,这会导致异常。 为了解决此时序问题,我们将代码包装到`try...except`语句中,并使用`time.sleep(5)`等待 5 秒钟。
* 当我们尝试加载`parquet_df`批 DataFrame 时,Parquet 文件的输出目录可能未准备好,这会导致异常。 为了解决此时序问题,我们将代码包装到`try...except`语句中,并使用`time.sleep(5)`等待 5 秒钟。
* 我们还将在标题中显示当前的推文计数。 为此,我们添加一个`<div>`元素,该元素每 5 秒刷新一次,并添加一个`<pd_script>`,该元素使用`streams_manager.twitter_stream.listener.tweet_count`来打印当前的 tweet 计数,该变量是我们添加到 `RawTweetsListener`类。 我们还更新了`on_data()`方法,以在每次有新的 tweet 到达时增加`tweet_count`变量,如以下代码所示:
```py
......@@ -1229,7 +1229,7 @@ def do_display_wc(self):
[您可以在此处找到代码文件](https://github.com/DTAIEB/Thoughtful-Data-Science/blob/master/chapter%207/sampleCode23.py)。
传递给`WordCloud`类的文本是通过收集`parquet_df`批处理 DataFrame 中的所有实体而生成的。
传递给`WordCloud`类的文本是通过收集`parquet_df`批 DataFrame 中的所有实体而生成的。
以下屏幕快照显示了让通过搜索查询`baseball`创建的 Twitter 流运行一段时间后的仪表板:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册