diff --git a/new/handson-ds-py-ml/08.md b/new/handson-ds-py-ml/08.md index 240fc99e9636781088021498d746e33eb1f37bb0..55e80004f283526232246b5ad87727890d1b9e1f 100644 --- a/new/handson-ds-py-ml/08.md +++ b/new/handson-ds-py-ml/08.md @@ -28,7 +28,7 @@ * 从左上角的飞镖板开始,您可以看到我们的点都分散在中心周围。 因此,总的来说,您知道平均误差非常接近实际。 我们的偏见实际上非常低,因为我们的预测都围绕着相同的正确点。 但是,我们的方差很高,因为这些点散布在整个地方。 因此,这是低偏差和高方差的示例。 * 如果我们继续移动到右上角的飞镖板上,就会看到我们的点始终一致地从其应有的位置偏向西北。 因此,这是我们的预测中存在高度偏见的一个示例,在这些偏见中始终存在一定偏差。 我们的差异很小,因为它们都紧密地聚集在错误的位置,但是至少它们彼此靠近,因此我们的预测是一致的。 那是低方差。 但是,偏见很高。 同样,这是高偏差,低方差。 * 在左下角的飞镖板上,您可以看到我们的预测分散在错误的均值周围。 因此,我们有很高的偏见。 一切都偏向了不该有的地方。 但是我们的差异也很大。 因此,这是两个世界中最糟糕的一个。 在此示例中,我们具有较高的偏见和较高的方差。 -* 最后,在一个奇妙的完美世界中,您将看到一个示例,例如右下方向的飞镖盘,其中我们的偏见低,所有事物都集中在应该放置的地方,而方差很小,所有事物都紧密地聚集在应该放置的地方 是。 因此,在一个完美的世界中,这就是最终的结果。 +* 最后,在一个奇妙的完美世界中,您将看到一个示例,例如右下方向的飞镖盘,其中我们的偏见低,所有事物都集中在应该放置的地方,而方差很小,所有事物都紧密地聚集在应该放置的地方。 因此,在一个完美的世界中,这就是最终的结果。 实际上,您通常需要在偏差和方差之间进行选择。 归结为过度拟合对数据的拟合不足。 让我们看下面的例子: @@ -77,7 +77,7 @@ 现在,这一切在实践中的工作方式是您将要尝试调整一个模型,并且该模型将具有不同的变体,您可能需要对其进行调整的不同参数,对吗? -例如,多项式拟合的多项式次数。 因此,我们的想法是尝试使用模型的不同值,不同的变体,使用 K 折交叉验证对它们进行度量,然后找到一个对测试数据集最小化误差的变量。 那是您在那里的最佳去处。 在实践中,您想使用 K 折交叉验证来衡量模型相对于测试数据集的准确性,并且只是不断完善该模型,继续尝试其中的不同值,继续尝试该模型的不同变体,甚至尝试不同的方法 完全建模,直到您找到使用 K 折交叉验证最大程度地减少错误的技术为止。 +例如,多项式拟合的多项式次数。 因此,我们的想法是尝试使用模型的不同值,不同的变体,使用 K 折交叉验证对它们进行度量,然后找到一个对测试数据集最小化误差的变量。 那是您在那里的最佳去处。 在实践中,您想使用 K 折交叉验证来衡量模型相对于测试数据集的准确性,并且只是不断完善该模型,继续尝试其中的不同值,继续尝试该模型的不同变体,甚至尝试完全不同的建模方法,直到您找到使用 K 折交叉验证最大程度地减少错误的技术为止。 让我们深入一个例子,看看它是如何工作的。 我们将再次将其应用于鸢尾花数据集,重新访问 SVC,然后我们将进行 K 折交叉验证,看看它有多简单。 我们实际上使用一些真实的 Python 代码在此处进行 K 折交叉验证和训练/测试。 您会发现它实际上非常易于使用,这是一件好事,因为这是您应使用的一种技术,用于在监督学习中测量模型的准确性和有效性。 @@ -504,7 +504,7 @@ for result in results[:20]: ![](img/a5aa652b-c518-403f-821e-576828f6d14a.png) -最后,我们得到了一些似乎有意义的结果! 因此,看起来像是,我小的 No-Hate News 网站上实际人类所要求的首页是首页,然后是`orlando-headlines`,接着是世界新闻,接着是漫画,接着是天气,以及有关 屏幕。 因此,这开始看起来更加合法。 +最后,我们得到了一些似乎有意义的结果! 因此,看起来像是,我小的 No-Hate News 网站上实际人类所要求的首页是首页,然后是`orlando-headlines`,接着是世界新闻,接着是漫画,接着是天气,以及关于屏幕。 因此,这开始看起来更加合法。 如果您要进行更深入的研究,您会发现此分析仍然存在问题。 例如,那些提要页面仍然来自机器人,只是试图从我的网站获取 RSS 数据。 因此,这在看似简单的分析如何在获得有意义的结果之前需要进行大量的预处理和清理源数据方面是一个很好的寓言。 diff --git a/new/handson-ds-py-ml/09.md b/new/handson-ds-py-ml/09.md index 57994b19b08096a2c9031f62b4890d5e5a0c1623..257ab87cc8a2744d29a6e777e7d1b6b22aca5b06 100644 --- a/new/handson-ds-py-ml/09.md +++ b/new/handson-ds-py-ml/09.md @@ -14,7 +14,7 @@ 在本节中,我将为您设置使用 Apache Spark 的设置,并向您展示一些实际使用 Apache Spark 解决与本书过去使用单计算机解决的相同问题的示例。 我们需要做的第一件事是在您的计算机上设置 Spark。 因此,在接下来的两节中,我们将引导您完成该操作。 这是非常简单的东西,但是有一些陷阱。 因此,不要只跳过这些部分; 要使 Spark 成功运行,需要特别注意一些事项,尤其是在 Windows 系统上。 让我们在系统上进行 Apache Spark 的设置,这样您就可以真正开始使用它了。 -现在,我们将仅在您自己的桌面上运行它。 但是,我们将在本章中编写的相同程序可以在实际的 Hadoop 集群上运行。 因此,您可以采用我们在 Spark 独立模式下在桌面上本地编写和运行的这些脚本,并从实际 Hadoop 集群的主节点实际运行它们,然后使其扩展到 Hadoop 集群的全部功能 并以这种方式处理海量数据集。 即使我们打算将事情设置为在您自己的计算机上本地运行,但请记住,这些相同的概念也可以扩展到在群集上运行。 +现在,我们将仅在您自己的桌面上运行它。 但是,我们将在本章中编写的相同程序可以在实际的 Hadoop 集群上运行。 因此,您可以采用我们在 Spark 独立模式下在桌面上本地编写和运行的这些脚本,并从实际 Hadoop 集群的主节点实际运行它们,然后使其扩展到 Hadoop 集群的全部功能,并以这种方式处理海量数据集。 即使我们打算将事情设置为在您自己的计算机上本地运行,但请记住,这些相同的概念也可以扩展到在群集上运行。 # 在 Windows 上安装 Spark @@ -24,8 +24,8 @@ 2. **安装 Python**:显然,您将需要 Python,但是如果您到此为止,则应该已经建立了 Python 环境,并希望使用 Enthought Canopy。 因此,我们可以跳过此步骤。 3. **安装适用于 Hadoop 的 Spark 的预构建版本**:幸运的是,Apache 网站提供了可用的 Spark 的预构建版本,这些预构建版本可以立即使用为最新 Hadoop 版本进行预编译的版本。 您无需构建任何东西,只需将其下载到计算机上,然后将其放置在正确的位置即可,大部分时间都很好。 4. **创建`conf/log4j.properties`文件**:我们需要处理一些配置事项。 我们要做的一件事就是调整警告级别,这样我们在工作时就不会收到很多警告垃圾邮件。 我们将逐步介绍如何做到这一点。 基本上,您需要重命名其中一个属性文件,然后在其中调整错误设置。 -5. **添加一个`SPARK_HOME`环境变量**:接下来,我们需要设置一些环境变量,以确保您可以实际从任何路径运行 Spark。 我们将添加一个指向您安装 Spark 的位置的`SPARK_HOME`环境变量,然后将`%SPARK_HOME%\bin`添加到您的系统路径中,以便在您运行 Spark Submit,PySpark 或所需的任何 Spark 命令时,Windows 会知道 在哪里找到它。 -6. **设置一个`HADOOP_HOME`变量**:在 Windows 上,我们还需要做一件事,我们还需要设置一个`HADOOP_HOME`变量,因为它将期望找到一点点 Hadoop,即使您 不要在独立系统上使用 Hadoop。 +5. **添加一个`SPARK_HOME`环境变量**:接下来,我们需要设置一些环境变量,以确保您可以实际从任何路径运行 Spark。 我们将添加一个指向您安装 Spark 的位置的`SPARK_HOME`环境变量,然后将`%SPARK_HOME%\bin`添加到您的系统路径中,以便在您运行 Spark Submit,PySpark 或所需的任何 Spark 命令时,Windows 会知道在哪里找到它。 +6. **设置一个`HADOOP_HOME`变量**:在 Windows 上,我们还需要做一件事,我们还需要设置一个`HADOOP_HOME`变量,因为它将期望找到一点点 Hadoop,即使您不在独立系统上使用 Hadoop。 7. **安装`winutils.exe`**:最后,我们需要安装一个名为`winutils.exe`的文件。 本书的资源中有指向`winutils.exe`的链接,因此您可以在那里找到它。 如果您想详细了解这些步骤,可以参考后面的章节。 @@ -86,7 +86,7 @@ ![](img/a3e884d4-be31-4274-b858-9c7ed7e14ed6.jpg) -因此,让我们继续解压缩 TGZ 文件。 我将打开我的`Downloads`文件夹以找到我们下载的 Spark 存档,然后继续右键单击该存档并将其解压缩到我选择的文件夹中-我将放置它 现在在我的`Downloads`文件夹中。 再次,WinRAR 现在为我执行此操作: +因此,让我们继续解压缩 TGZ 文件。 我将打开我的`Downloads`文件夹以找到我们下载的 Spark 存档,然后继续右键单击该存档并将其解压缩到我选择的文件夹中-我现在将它放置在我的`Downloads`文件夹中。 再次,WinRAR 现在为我执行此操作: ![](img/edaa679b-44dd-4811-bbed-52b39f6488bc.png) @@ -247,7 +247,7 @@ Spark 是一项非常热门的技术,并且相对来说还很年轻,因此 * 无需编译,管理依赖项等。 * 较少的编码开销 * 您已经知道 Python -* 让我们专注于概念而非 新语言 +* 让我们专注于概念而非新语言 | @@ -265,7 +265,7 @@ Spark 是一项非常热门的技术,并且相对来说还很年轻,因此 # Spark 和弹性分布式数据集(RDD) -让我们更深入地了解 Spark 的工作方式。 我们将讨论称为 RDD 的弹性分布式数据集。 这是您在 Spark 中编程时使用的核心,我们将提供一些代码片段来尝试使其成为现实。 我们将在这里为您提供 Apache Spark 速成班。 除了我们在接下来的几节中将要介绍的内容之外,它还涉及很多其他内容,但是我只是向您提供一些基本知识,您需要它们才能真正理解这些示例中发生的事情,并希望可以开始并 指向正确的方向。 +让我们更深入地了解 Spark 的工作方式。 我们将讨论称为 RDD 的弹性分布式数据集。 这是您在 Spark 中编程时使用的核心,我们将提供一些代码片段来尝试使其成为现实。 我们将在这里为您提供 Apache Spark 速成班。 除了我们在接下来的几节中将要介绍的内容之外,它还涉及很多其他内容,但是我只是向您提供一些基本知识,您需要它们才能真正理解这些示例中发生的事情,并希望可以开始并指向正确的方向。 如上所述,Spark 的最基本部分称为弹性分布式数据集(RDD),它将成为您用来实际加载和转换并从正在尝试的数据中获取所需答案的对象 处理。 了解这是非常重要的事情。 RDD 中的最后一个字母代表数据集,而到了最后,一切都结束了。 它只是一堆信息行,可以包含几乎所有内容。 但是关键是 R 和第一个 D。 @@ -381,7 +381,7 @@ rdd.map(lambda x: x*x) 那么,MLlib 可以做什么? 好吧,其中之一就是特征提取。 -您可以按比例做的一件事是术语频率和逆文档频率,这对于例如创建搜索索引很有用。 实际上,本章后面将通过一个示例。 同样,关键是它可以使用海量数据集在整个集群中做到这一点,因此您可以潜在地为网络创建自己的搜索引擎。 它还提供基本的统计功能,卡方检验,Pearson 或 Spearman 相关性,以及一些更简单的内容,例如最小值,最大值,均值和方差。 这些本身并不十分令人兴奋,但令人兴奋的是,您实际上可以跨庞大的数据集计算方差,均值或其他任何东西或相关分数,并且实际上会将数据集分解为多个块 并在必要时在整个群集中运行。 +您可以按比例做的一件事是术语频率和逆文档频率,这对于例如创建搜索索引很有用。 实际上,本章后面将通过一个示例。 同样,关键是它可以使用海量数据集在整个集群中做到这一点,因此您可以潜在地为网络创建自己的搜索引擎。 它还提供基本的统计功能,卡方检验,Pearson 或 Spearman 相关性,以及一些更简单的内容,例如最小值,最大值,均值和方差。 这些本身并不十分令人兴奋,但令人兴奋的是,您实际上可以跨庞大的数据集计算方差,均值或其他任何东西或相关分数,并且实际上会将数据集分解为多个块,并在必要时在整个群集中运行。 因此,即使其中的一些操作不是很有趣,但有趣的是它可以运行的规模。 它还可以支持线性回归和逻辑回归等功能,因此,如果您需要将函数拟合到大量数据并将其用于预测,则也可以这样做。 它还支持支持向量机。 我们将在这里介绍一些更高级的算法,一些更高级的算法,并且它们也可以使用 Spark 的 MLlib 扩展到海量数据集。 MLlib 中内置了一个朴素的贝叶斯分类器,因此,还记得我们在本书前面构建的垃圾邮件分类器吗? 实际上,您可以使用 Spark 在整个电子邮件系统中执行此操作,然后将其扩展到所需的范围。 @@ -393,7 +393,7 @@ rdd.map(lambda x: x*x) # 向量数据类型 -还记得本书前面提到的电影相似之处和电影推荐吗? 向量的一个示例可能是给定用户评分的所有电影的列表。 向量有两种类型:稀疏和密集。 让我们看一个例子。 世界上有很多电影,无论用户是否实际观看,密集的向量实际上代表每个电影的数据。 例如,假设我有一个用户观看过《玩具总动员》,显然我会存储他们对玩具总动员的评分,但是如果他们不看电影《星球大战》,我实际上会存储一个事实,那就是没有数字 为星球大战。 因此,我们最终以密集的向量为所有这些丢失的数据点占用了空间。 稀疏向量仅存储存在的数据,因此不会在丢失的数据上浪费任何内存空间,好的。 因此,它是内部表示向量的一种更紧凑的形式,但是显然在处理时会引入一些复杂性。 因此,如果您知道向量中会有很多丢失的数据,那么这是节省内存的好方法。 +还记得本书前面提到的电影相似之处和电影推荐吗? 向量的一个示例可能是给定用户评分的所有电影的列表。 向量有两种类型:稀疏和密集。 让我们看一个例子。 世界上有很多电影,无论用户是否实际观看,密集的向量实际上代表每个电影的数据。 例如,假设我有一个用户观看过《玩具总动员》,显然我会存储他们对玩具总动员的评分,但是如果他们不看电影《星球大战》,我实际上会存储一个事实,那就是《星球大战》没有数字。 因此,我们最终以密集的向量为所有这些丢失的数据点占用了空间。 稀疏向量仅存储存在的数据,因此不会在丢失的数据上浪费任何内存空间,好的。 因此,它是内部表示向量的一种更紧凑的形式,但是显然在处理时会引入一些复杂性。 因此,如果您知道向量中会有很多丢失的数据,那么这是节省内存的好方法。 # LabeledPoint 数据类型 diff --git a/new/py-ds-essentials/2.md b/new/py-ds-essentials/2.md index 74305c8b5534c235ea14703978c1f57a36f74fd4..d475bcf24fc8f982002ef33512651ca190217f82 100644 --- a/new/py-ds-essentials/2.md +++ b/new/py-ds-essentials/2.md @@ -1114,7 +1114,7 @@ In: section = soup.find_all(id='mw-normal-catlinks')[0] # 使用 NumPy 进行数据处理 -引入了基本的 Pandas 命令后,您可以在数据科学流水线的这一点上完全,小批量甚至单个数据行上载和预处理数据到内存中,您必须对其进行处理以准备合适的数据 监督和非监督学习程序的数据矩阵。 +引入了基本的 Pandas 命令后,您可以在数据科学流水线的这一点上完全,小批量甚至单个数据行上载和预处理数据到内存中,您必须处理监督和非监督学习程序的数据矩阵来准备合适的数据。 作为最佳实践,我们建议您在数据仍然是异构的(数字和符号值的混合)工作阶段和将其转换为数据数字表的另一个阶段之间划分任务。 数据表或矩阵排列在代表示例的行中,而列则包含示例的特征观察值(即变量)。 @@ -1301,7 +1301,7 @@ In: # Check if a NumPy array is of the desired numeric type # 从列表到多维数组 -如果将包含数字或文本对象的列表渲染为一维数组(例如,可以表示系数向量),则列表列表转换为二维数组,并且列表列表变为三维 一: +如果将包含数字或文本对象的列表渲染为一维数组(例如,可以表示系数向量),则列表的列表转换为二维数组,并且列表的列表的列表变为三维: ```py In: import numpy as np @@ -1554,7 +1554,7 @@ In: import numpy as np 结果,该操作将按元素进行; 也就是说,数组的每个元素都可以通过标量值或另一个数组的相应元素来操作。 -当对不同维数的数组进行操作时,如果其中一个维数为 1,则仍然可以进行元素操作,而不必重新构建数据。实际上,在这种情况下,大小为 1 的维数会一直扩展到 匹配相应数组的尺寸。 这种转换称为广播。 +当对不同维数的数组进行操作时,如果其中一个维数为 1,则仍然可以进行元素操作,而不必重新构建数据。实际上,在这种情况下,大小为 1 的维数会一直扩展来匹配相应数组的尺寸。 这种转换称为广播。 例如: @@ -1807,7 +1807,7 @@ In: bias = np.ones(10).reshape(10,1) np.hstack((dataset,bias)) ``` -2. 无需更改`bias`的形状(因此,它可以是与数组行相同长度的任何数据序列),您可以使用`column_stack()`函数将其作为序列添加,该函数可获得相同的结果,但数量较少 有关数据重塑的问题: +2. 无需更改`bias`的形状(因此,它可以是与数组行相同长度的任何数据序列),您可以使用`column_stack()`函数将其作为序列添加,该函数可获得相同的结果,但数据重塑的问题数量较少: ```py In: bias = np.ones(10) @@ -1830,7 +1830,7 @@ In: np.dstack((dataset*1,dataset*2,dataset*3)) In: np.insert(dataset, 3, bias, axis=1) ``` -您只需要定义要插入的数组(`dataset`),位置(索引`3`),要插入的序列(在本例中为数组`bias`)以及沿其插入的轴 您想要操作插入(轴`1`是垂直轴)。 +您只需要定义要插入的数组(`dataset`),位置(索引`3`),要插入的序列(在本例中为数组`bias`)以及沿其插入的轴(轴`1`是垂直轴)。 自然地,您可以通过确保要插入的数组与操作插入的尺寸对齐来插入整个数组(而不仅仅是向量),例如偏移。 在此示例中,为了将相同的数组插入自身,我们必须将其作为插入的元素进行转置: @@ -1871,7 +1871,7 @@ You can find all of SciPy's documentation about sparse matrices at [https://docs 让我们开始创建一个稀疏矩阵: -1. 为了创建稀疏矩阵,您可以从 NumPy 数组生成它(仅通过将数组传递给 SciPy 的稀疏矩阵格式之一),或通过向 COO 提供包含行索引,列索引和数据值的三个向量 矩阵分别为: +1. 为了创建稀疏矩阵,您可以从 NumPy 数组生成它(仅通过将数组传递给 SciPy 的稀疏矩阵格式之一),或通过向 COO 矩阵分别提供包含行索引,列索引和数据值的三个向量: ```py In: row_idx = np.array([0, 1, 3, 3, 4]) @@ -1911,12 +1911,12 @@ In: print(sparse_coo) Out: (0, 1) 1.0 (1, 2) 1.0 (3, 2) 2.0 (3, 4) 1.0 (4, 2) 2.0 ``` -从输出表示中,我们可以得出一个稀疏坐标格式矩阵的工作原理是将打印值存储在三个单独的存储数组中:一个用于`x`坐标,一个用于`y`坐标,以及 一个值。 这意味着在插入信息时,COO 矩阵的确非常快(每个新元素是每个存储阵列中的新行),但是处理起来缓慢,因为它无法立即找出行或列中的值以进行扫描 数组。 +从输出表示中,我们可以得出一个稀疏坐标格式矩阵的工作原理是将打印值存储在三个单独的存储数组中:一个用于`x`坐标,一个用于`y`坐标,以及一个用于值。 这意味着在插入信息时,COO 矩阵的确非常快(每个新元素是每个存储阵列中的新行),但是处理起来缓慢,因为它无法通过扫描数组立即找出行或列中的值。 -对于键字典(DOK)和列表的列表(LIL)也是如此。 第一个使用坐标字典操作(因此它可以快速检索单个元素),第二个使用两个列表,两个列表被排列来代表行,包含该行中的非零坐标以及其他值(很容易 通过添加更多行进行扩展)。 +对于键字典(DOK)和列表的列表(LIL)也是如此。 第一个使用坐标字典操作(因此它可以快速检索单个元素),第二个使用两个列表,两个列表被排列来代表行,包含该行中的非零坐标以及其他值(很容易通过添加更多行进行扩展)。 COO 矩阵的另一个优点是,它们可以立即转换为专门用于在行或列级别有效工作的其他类型的矩阵:CSR 和 CSC 矩阵。 -**压缩的稀疏行**(**CSR**)和**压缩的稀疏列**(**CSC**)是创建稀疏矩阵后最常用的格式 他们。 他们使用的索引系统更支持对 CSR 的行和对 CSC 的列进行计算。 但是,这使得编辑的计算量很大(因此,创建它们后更改它们并不方便)。 +**压缩的稀疏行**(**CSR**)和**压缩的稀疏列**(**CSC**)是创建稀疏矩阵后用于操作它们的最常用的格式。 他们使用的索引系统更支持对 CSR 的行和对 CSC 的列进行计算。 但是,这使得编辑的计算量很大(因此,创建它们后更改它们并不方便)。 CSR 和 CSC 的性能实际上取决于所使用的算法及其优化参数的方式。 您必须实际对算法进行试验,以找出效果最佳的算法。 diff --git a/new/py-ds-essentials/3.md b/new/py-ds-essentials/3.md index dd164fadf621041d1052d067de41288855aa2d09..e9971222452be016404194f14a84a2dda5825555 100644 --- a/new/py-ds-essentials/3.md +++ b/new/py-ds-essentials/3.md @@ -160,7 +160,7 @@ In: from sklearn.preprocessing import StandardScaler 请注意,我们没有使用原始功能。 我们使用了它们的线性修改,这更适合使用 KNN 回归器进行学习。 -代替 Z 归一化,我们可以在对异常值更鲁棒的特征上使用缩放函数,即`RobustScaler`。这样的缩放器使用中位数和**四分位间距**(**IQR**),而不是使用均值和标准差来缩放每个特征 独立地。 它比异常值更健壮,因为如果几个点(最终只有一个)距离中心较远,例如由于错误的读数,传输错误或 传感器损坏: +代替 Z 归一化,我们可以在对异常值更鲁棒的特征上使用缩放函数,即`RobustScaler`。这样的缩放器使用中位数和**四分位间距**(**IQR**),而不是使用均值和标准差来独立缩放每个特征。 它比异常值更健壮,因为如果几个点(最终只有一个)距离中心较远,例如由于错误的读数,传输错误或传感器损坏: ```py In: from sklearn.preprocessing import RobustScaler @@ -271,7 +271,7 @@ Out: 0.97763177502480336 前两个组件的散点图 -我们可以立即看到,在应用 PCA 之后,输出集仅具有两个功能。 这是因为在`n_components`参数设置为`2`的情况下调用了`PCA()`对象。 获得相同结果的另一种方法是对`1`,`2`和`3`组件运行`PCA()`,然后从解释的方差比和视觉检查得出结论,对于`n_components = 2`,我们得到了 最好的结果。 然后,我们将有证据表明,当使用两个基向量时,输出数据集包含几乎 98% 的输入信号能量,并且在模式中,这些类几乎可以很好地分离。 每种颜色位于二维欧几里得空间的不同区域。 +我们可以立即看到,在应用 PCA 之后,输出集仅具有两个功能。 这是因为在`n_components`参数设置为`2`的情况下调用了`PCA()`对象。 获得相同结果的另一种方法是对`1`,`2`和`3`组件运行`PCA()`,然后从解释的方差比和视觉检查得出结论,对于`n_components = 2`,我们得到了最好的结果。 然后,我们将有证据表明,当使用两个基向量时,输出数据集包含几乎 98% 的输入信号能量,并且在模式中,这些类几乎可以很好地分离。 每种颜色位于二维欧几里得空间的不同区域。 请注意,此过程是自动的,培训 PCA 时不需要提供标签。 实际上,PCA 是一种无监督算法,它不需要与自变量有关的数据来旋转投影基础。 @@ -461,7 +461,7 @@ In: from sklearn.decomposition import KernelPCA # T-SNE -PCA 是一种广泛的降维技术,但是当我们处理大数据并呈现许多功能时,我们首先需要了解*特征空间中*的情况。 实际上,在 EDA 阶段,您通常会对数据进行几次散点图绘制,以了解要素之间的关系。 在这一点上,T 分布随机邻居嵌入或 T-SNE 可以为您提供帮助,因为它的设计目标是将高维数据嵌入 2D 或 3D 空间中以充分利用 散点图。 它是由 Laurens van der Maaten 和 Geoffrey Hinton 开发的一种非线性降维技术,该算法的核心是基于两个规则:第一个是周期性的相似观测必须对输出有更大的贡献(这是通过概率实现的)。 分配功能); 其次,高维空间中的分布必须类似于小空间中的分布(这是通过最小化 **Kullback-Leibler**(**KL** 来实现的),两者之间的差异 概率分布函数)。 输出在视觉上是不错的,并允许您猜测要素之间的非线性相互作用。 +PCA 是一种广泛的降维技术,但是当我们处理大数据并呈现许多功能时,我们首先需要了解*特征空间中*的情况。 实际上,在 EDA 阶段,您通常会对数据进行几次散点图绘制,以了解要素之间的关系。 在这一点上,T 分布随机邻居嵌入或 T-SNE 可以为您提供帮助,因为它的设计目标是将高维数据嵌入 2D 或 3D 空间中以充分利用散点图。 它是由 Laurens van der Maaten 和 Geoffrey Hinton 开发的一种非线性降维技术,该算法的核心是基于两个规则:第一个是周期性的相似观测必须对输出有更大的贡献(这是通过概率实现的)。 分配功能); 其次,高维空间中的分布必须类似于小空间中的分布(这是通过最小化 **Kullback-Leibler**(**KL** 来实现的),两者概率分布函数之间的差异)。 输出在视觉上是不错的,并允许您猜测要素之间的非线性相互作用。 让我们通过将 T-SNE 应用于鸢尾花数据集并将其绘制到二维空间来查看一个简单的示例如何工作: @@ -582,7 +582,7 @@ In: print (list(zip(outliers_rows, outliers_columns))) Out: [(55, 1), (56, 1), ( Scikit-learn 软件包提供了两个类,这些类可以直接为您自动工作并发出所有可疑情况的信号: * `covariance.EllipticEnvelope`类适合您的数据的可靠分布估计,指出可能污染数据集的异常值,因为它们是数据一般分布中的极端点。 -* `svm.OneClassSVM`类是一种支持向量机算法,可以近似于数据的形状并确定是否应将提供的任何新实例视为新颖性(它充当新颖性检测器,因为默认情况下,它假定存在 数据中没有异常值)。 通过仅修改其参数,它也可以在存在异常值的数据集上工作,从而提供比`EllipticEnvelope`更鲁棒和可靠的异常值检测系统。 +* `svm.OneClassSVM`类是一种支持向量机算法,可以近似于数据的形状并确定是否应将提供的任何新实例视为新颖性(它充当新颖性检测器,因为默认情况下,它假定数据中没有异常值)。 通过仅修改其参数,它也可以在存在异常值的数据集上工作,从而提供比`EllipticEnvelope`更鲁棒和可靠的异常值检测系统。 这两种课程都基于不同的统计和机器学习方法,需要在建模阶段进行了解和应用。 @@ -644,7 +644,7 @@ In: from sklearn.datasets import make_blobs 在唯一的基础多元分布的情况下(当变量`blob = 1`时),`EllipticEnvelope`算法已成功将观测值的 10% 定位在分布本身的边缘,并因此向所有可疑异常值发出信号。 -相反,当数据中存在多个分布时,好像有两个或两个以上的自然簇时,该算法试图拟合唯一的一般分布,往往会将潜在异常值定位在最远端的簇上,从而忽略了数据的其他区域 可能会受到外围案例的影响。 +相反,当数据中存在多个分布时,好像有两个或两个以上的自然簇时,该算法试图拟合唯一的一般分布,往往会将潜在异常值定位在最远端的簇上,从而忽略了数据的其他区域,它们可能会受到外围案例的影响。 对于真实数据,这并非罕见情况,它代表了`EllipticEnvelope`算法的重要局限性。 @@ -706,13 +706,13 @@ In: # Draw the distribution and the detected outliers 与前面的示例一样,在我们假设等于 0.05 的低污染的情况下,基于`EllipticEnvelope`的代码将预测异常值,并将其存储在数组中的方式与存储异常值的方式相同。 最后,是可视化(如前所述,我们将在第 5 章,“可视化,见解和结果”中讨论所有可视化方法)。 -现在,让我们观察由散点图提供的结果,该散点图用于可视化数据的前两个`PCA`分量并标记外围观察。 关于我们示例中数据点的总体分布,由两个组成部分提供,它们约占数据方差的 62%,看来波士顿似乎有两个不同的房价集群,分别对应于 市场中存在高端和低端设备。 一般而言,对于`EllipticEnvelope`估算,数据中群集的存在并不是最佳的情况。 实际上,根据我们在使用合成斑点进行实验时已经注意到的结果,该算法仅指出了一个簇上的离群值-较小的一个。 鉴于这样的结果,有充分的理由相信我们刚刚收到了有偏见的,部分的回应,在将这些点视为异常值之前,需要进行一些进一步的调查。 Scikit-learn 软件包实际上将鲁棒的协方差估计方法(从根本上讲是一种统计方法)与一种扎根于机器学习的另一种方法集成在一起:`OneClassSVM`类。 现在,我们将继续进行试验。 +现在,让我们观察由散点图提供的结果,该散点图用于可视化数据的前两个`PCA`分量并标记外围观察。 关于我们示例中数据点的总体分布,由两个组成部分提供,它们约占数据方差的 62%,看来波士顿似乎有两个不同的房价集群,分别对应于市场中存在高端和低端设备。 一般而言,对于`EllipticEnvelope`估算,数据中群集的存在并不是最佳的情况。 实际上,根据我们在使用合成斑点进行实验时已经注意到的结果,该算法仅指出了一个簇上的离群值-较小的一个。 鉴于这样的结果,有充分的理由相信我们刚刚收到了有偏见的,部分的回应,在将这些点视为异常值之前,需要进行一些进一步的调查。 Scikit-learn 软件包实际上将鲁棒的协方差估计方法(从根本上讲是一种统计方法)与一种扎根于机器学习的另一种方法集成在一起:`OneClassSVM`类。 现在,我们将继续进行试验。 在离开此示例之前,请注意,为了同时适合 PCA 和`EllipticEnvelope`,我们使用了一个名为`normalized_data`的数组,该数组仅包含标准化的连续数据集变量。 请始终注意,使用非标准化数据并将二进制或分类数据与连续数据混合可能会导致`EllipticEnvelope`算法的错误和近似估计。 # OneClassSVM -由于`EllipticEnvelope`利用参数和统计假设拟合假设的高斯分布,因此`OneClassSVM`是一种机器学习算法,可从数据本身学习特征的分布,因此适用于多种情况 您希望能够捕获所有离群值以及异常数据示例。 +由于`EllipticEnvelope`利用参数和统计假设拟合假设的高斯分布,因此`OneClassSVM`是一种机器学习算法,可从数据本身学习特征的分布,因此适用于多种情况,其中您希望能够捕获所有离群值以及异常数据示例。 如果您已经拥有一个干净的数据集,并且已通过机器学习算法进行了拟合,那就太好了。 之后,可以召唤`OneClassSVM`来检查是否有任何新示例适合历史分布,如果不合适,它将发出一个新示例的信号,该示例可能是错误,也可能是某些新的,以前看不见的情况。 @@ -797,7 +797,7 @@ nu = no_estimated nu_estimate = 0.95 * outliers_fraction + 0.05 ``` -因此,通过将`outliers_fraction`(从`0.02`更改为较大的值,例如`0.1`),当假定发生率较高时,您需要算法对可能出现的异常现象给予更多关注 您数据中的异常情况。 +因此,通过将`outliers_fraction`(从`0.02`更改为较大的值,例如`0.1`),当假定您数据中的异常情况发生率较高时,您需要算法对可能出现的异常现象给予更多关注。 我们还要观察 PCA 组件从 2 到 5 的图形输出,并将其与主组件进行比较(所解释方差的 51%)。 该系列的第一个图(包括四个散点图)如下: @@ -899,7 +899,7 @@ In: from sklearn.metrics import classification_report ![](img/23bf9c64-7ed6-4f0b-aa55-25ccaa4b24d2.png) -在数据科学实践中,**精度**和**召回**比**准确率**更为广泛地使用,因为数据问题中的大多数数据集倾向于不平衡。 为了解决这种不平衡,数据科学家经常以**精度**,**召回**和 **F1 分数**来表示其结果。 此外,我们必须注意**准确率**,**精度**,**召回**和 **F1 分数**如何采用`[0.0, 1.0]`范围。 完美的分类器在所有这些指标上的得分都达到`1.0`(但是要当心任何完美的分类,如果太令人难以置信,请当心,因为这通常意味着出了点问题;现实世界中的数据问题永远不会 完美的解决方案)。 +在数据科学实践中,**精度**和**召回**比**准确率**更为广泛地使用,因为数据问题中的大多数数据集倾向于不平衡。 为了解决这种不平衡,数据科学家经常以**精度**,**召回**和 **F1 分数**来表示其结果。 此外,我们必须注意**准确率**,**精度**,**召回**和 **F1 分数**如何采用`[0.0, 1.0]`范围。 完美的分类器在所有这些指标上的得分都达到`1.0`(但是要当心任何完美的分类,如果太令人难以置信,请当心,因为这通常意味着出了点问题;现实世界中的数据问题永远不会有完美的解决方案)。 # 二进制分类 @@ -1005,11 +1005,11 @@ In: chosen_random_state = 1 0.953703703704 ``` -通过执行前面的代码,`model_selection.train_test_split()`函数根据参数`test_size`将初始数据随机分为两个互斥的集合(该整数可以表示测试集示例的确切数目,也可以是 浮点数,表示要用于测试目的的总数据的百分比)。 拆分由`random_state`控制,该操作可确保在不同时间和不同计算机上(即使您使用的是完全不同的操作系统)也可以重现该操作。 +通过执行前面的代码,`model_selection.train_test_split()`函数根据参数`test_size`将初始数据随机分为两个互斥的集合(该整数可以表示测试集示例的确切数目,也可以是浮点数,表示要用于测试目的的总数据的百分比)。 拆分由`random_state`控制,该操作可确保在不同时间和不同计算机上(即使您使用的是完全不同的操作系统)也可以重现该操作。 -目前的平均准确度为 0.94。 如果您尝试使用`chosen_random_state`参数使用不同的整数值再次运行同一单元,则实际上您会注意到准确性会发生变化,这表明测试集进行的性能评估并非绝对的性能指标,并且 应谨慎使用。 给定不同的测试样本,您必须了解它的可变性。 +目前的平均准确度为 0.94。 如果您尝试使用`chosen_random_state`参数使用不同的整数值再次运行同一单元,则实际上您会注意到准确性会发生变化,这表明测试集进行的性能评估并非绝对的性能指标,并且应谨慎使用。 给定不同的测试样本,您必须了解它的可变性。 -实际上,我们甚至可以从测试集中获得有偏差的性能估计。 如果我们选择(在使用`random_state`进行各种试验后)可以确认我们假设的测试集,或者开始使用测试集作为参考以对学习过程做出决定(例如,选择 符合特定测试样本的最佳假设)。 +实际上,我们甚至可以从测试集中获得有偏差的性能估计。 如果我们选择(在使用`random_state`进行各种试验后)可以确认我们假设的测试集,或者开始使用测试集作为参考以对学习过程做出决定(例如,选择符合特定测试样本的最佳假设)。 与仅评估训练数据的拟合度一样,对选定的测试集进行操作也可以确保最终的性能看起来不错。 但是,您建立的模型不会在不同的测试集上复制相同的性能(再次是过度拟合问题)。 @@ -1089,7 +1089,7 @@ Out: X train shape, (1078, 64), X validation shape (359, 64), 在我们推荐的交叉验证中,十折是很常见的配置。 对于线性估计等有偏估计量,使用较少的折痕可能会很好,但它可能会惩罚更复杂的机器学习算法。 在某些情况下,您确实需要使用更多的折痕以确保有足够的训练数据供机器学习算法正确归纳。 这在没有足够数据点的医学数据集中很常见。 另一方面,如果手头的示例数量不成问题,则使用更多的折叠会占用更多的计算资源,并且交叉验证完成可能需要更长的时间。 有时,使用五折可以很好地权衡估算的准确性和运行时间。 -标准偏差将提示您模型如何受到训练提供的数据(实际上是模型的方差)的影响,并且平均值提供了对其总体性能的合理估计。 使用从不同模型获得的交叉验证结果的平均值(由于使用了不同的模型类型,或者因为使用了不同的训练变量选择,或者因为模型的不同超参数),您可以放心地选择 表现最佳的假设,可进行总体表现测试。 +标准偏差将提示您模型如何受到训练提供的数据(实际上是模型的方差)的影响,并且平均值提供了对其总体性能的合理估计。 使用从不同模型获得的交叉验证结果的平均值(由于使用了不同的模型类型,或者因为使用了不同的训练变量选择,或者因为模型的不同超参数),您可以放心地选择表现最佳的假设,可进行总体表现测试。 我们强烈建议您将交叉验证仅用于优化目的,而不是用于性能估计(也就是说,找出新数据上的模型错误可能是什么)。 交叉验证只是根据最佳平均结果指出最佳算法和参数选择。 将其用于性能评估将意味着使用找到的最佳结果,这比应该的结果更为乐观。 为了报告您可能的性能的无偏估计,您应该首选使用测试集。 @@ -1183,7 +1183,7 @@ In: h1.fit(X[train_idx],y[train_idx]) 在其他最有用的迭代器中,值得一提的是: * `StratifiedKFold`的工作方式与`Kfold`相似,但它始终返回与训练集大致相同的班级百分比的折叠。 这样可以使每个折痕保持平衡; 因此,学习者适合正确的课堂比例。 代替案例数,它需要输入目标变量 y 作为输入参数。 如上一节所述,默认情况下,迭代器包装在`cross_val_score`函数中。 -* `LeaveOneOut`的工作方式类似于`Kfold`,但它仅作为一个观测值的验证集返回。 因此,最后,折叠数将等于训练集中的示例数。 我们建议您仅在训练集严重不平衡(例如,在欺诈检测问题中)或很小的训练集时使用此交叉验证方法,尤其是在观察值少于 100 的情况下– K 倍验证会减少训练集 很多。 +* `LeaveOneOut`的工作方式类似于`Kfold`,但它仅作为一个观测值的验证集返回。 因此,最后,折叠数将等于训练集中的示例数。 我们建议您仅在训练集严重不平衡(例如,在欺诈检测问题中)或很小的训练集时使用此交叉验证方法,尤其是在观察值少于 100 的情况下 – K 倍验证会极大减少训练集。 * `LeavePOut`在`LeaveOneOut`的优点和局限性方面相似,但其验证集由 P 个案例组成。 因此,总折叠数将是所有可用案例中 P 个案例的组合(随着数据集大小的增长,实际上可能是相当大的数量)。 * `LeaveOneLabelOut`提供了一种方便的方法,可根据您预先准备或计算的方案进行交叉验证。 实际上,它的行为类似于`Kfolds`,但是对于折叠已经被标记并提供给标签参数这一事实。 * `LeavePLabelOut`是`LeaveOneLabelOut`的变体。 在这种情况下,根据您事先准备的方案,测试折痕由许多标签组成。 @@ -1269,7 +1269,7 @@ Out:[37, 12, 72, 9, 75, 5, 79, 64, 16, 1, 76, 71, 6, 25, 50, 20, 18, 84, # 超参数优化 -机器学习假设不仅由学习算法确定,还由其超参数(算法的参数必须事先确定,并且在训练过程中无法学习)确定,并选择要用于实现的变量 最好的学习参数。 +机器学习假设不仅由学习算法确定,还由其超参数(算法的参数必须事先确定,并且在训练过程中无法学习)确定,并选择要用于实现最佳学习参数的变量。 在本节中,我们将探索如何扩展交叉验证方法,以找到能够推广到我们的测试集的最佳超参数。 我们将继续使用 Scikit-learn 软件包提供的手写数字数据集。 这是有关如何加载数据集的有用提示: @@ -1490,7 +1490,7 @@ In: res = search_func.cv*results* for el in zip(res['mean_test_score'], James Bergstra 和 Yoshua Bengio 设计了随机搜索,以使深度学习中超参数的最佳组合搜索更加有效。 [原始论文为进一步了解这种方法提供了很好的资源](http://www.jmlr.org/papers/volume13/bergstra12a/bergstra12a.pdf)。 -统计测试表明,要使随机搜索取得良好的效果,您应尝试从最少 30 次试验到最多 60 次试验(此经验法则是基于最佳覆盖了 5% 至 10% 超参数的假设 空间,并且 95% 的成功率是可以接受的)。 因此,如果您的网格搜索需要类似的搜索(这样您就可以利用随机搜索的属性)或需要进行大量的实验(从而可以节省计算量),通常可以选择随机搜索。 +统计测试表明,要使随机搜索取得良好的效果,您应尝试从最少 30 次试验到最多 60 次试验(此经验法则是基于最佳覆盖了 5% 至 10% 超参数的假设空间,并且 95% 的成功率是可以接受的)。 因此,如果您的网格搜索需要类似的搜索(这样您就可以利用随机搜索的属性)或需要进行大量的实验(从而可以节省计算量),通常可以选择随机搜索。 # 功能选择 @@ -1509,7 +1509,7 @@ Scikit-learn 软件包提供了广泛的功能选择方法: * 基于 L1 的功能选择 * 基于树的特征选择 -方差,单变量和递归消除可以在`feature_selection`模块中找到。 其他是特定机器学习算法的副产品。 除了基于树的选择(将在第 4 章,“机器学习”中提到)之外,我们还将介绍所有前面的方法,并指出它们如何帮助您改善您的 从数据中学习。 +方差,单变量和递归消除可以在`feature_selection`模块中找到。 其他是特定机器学习算法的副产品。 除了基于树的选择(将在第 4 章,“机器学习”中提到)之外,我们还将介绍所有前面的方法,并指出它们如何帮助您改善您从数据中学习的结果。 # 基于特征差异的选择 @@ -1666,7 +1666,7 @@ In: from sklearn.svm import LinearSVC 样本外精度比使用贪婪方法获得的精度更高。 秘密是在初始化`LogisticRegression`类时分配的`penalty='l1'`和`C`值。 由于`C`是基于 L1 的选择的主要成分,因此正确选择它非常重要。 这可以通过使用网格搜索和交叉验证来完成,但是通过正则化获得变量选择的方法更简单,更有效:稳定性选择。 -稳定性选择即使在默认值下也可以成功使用 L1 正则化(尽管您可能需要更改它们才能改善结果),因为它通过二次采样(即通过使用来重新计算正则化过程多次)来验证其结果 训练数据集中随机选择的一部分。 +稳定性选择即使在默认值下也可以成功使用 L1 正则化(尽管您可能需要更改它们才能改善结果),因为它通过随机选择训练数据集中的一部分来二次采样(即通过使用来重新计算正则化过程多次)来验证其结果。 结果不包括通常将其系数估计为零的所有变量。 仅当变量的系数为非零时,该变量才被认为对数据集和要素集变化稳定,这是要包含在模型中的重要内容(因此,其名称为“稳定性选择”)。 diff --git a/new/py-ds-essentials/7.md b/new/py-ds-essentials/7.md index 90697a2f63a0b8956603054d76e3592304bc937b..b0d6026edc3566dee99274545b54ba3b747702b1 100644 --- a/new/py-ds-essentials/7.md +++ b/new/py-ds-essentials/7.md @@ -57,7 +57,7 @@ # 使用 CNN 对图像进行分类 -现在让我们将深度神经网络应用于图像分类问题。 在这里,我们将尝试根据其图像预测交通标志。 对于此任务,我们将使用 **CNN**(**卷积神经网络**),该技术能够利用图像中附近像素之间的空间相关性,这是目前的水平 在解决此类问题时进行深度学习。 +现在让我们将深度神经网络应用于图像分类问题。 在这里,我们将尝试根据其图像预测交通标志。 对于此任务,我们将使用 **CNN**(**卷积神经网络**),该技术能够利用图像中附近像素之间的空间相关性,这是目前在解决此类问题时的深度学习水平。 [数据集可在此处找到](http://benchmark.ini.rub.de/?section=gtsrb&subsection=dataset)。 我们要感谢团队免费发布了数据集,并参考了涉及该数据集的出版物: diff --git a/new/py-ds-essentials/8.md b/new/py-ds-essentials/8.md index 484184d315926dde6f3723ff6d863b907a50f3ce..bfea92227385609e7b36ff957b38004e4460ad23 100644 --- a/new/py-ds-essentials/8.md +++ b/new/py-ds-essentials/8.md @@ -433,7 +433,7 @@ Out: {'chars': 5535014, 'words': 959893, 'lines': 149689} 5. 我们翻转键和值并创建一个新的 RDD。 这是一个地图操作。 6. 我们将 RDD 降序排列,然后提取(获取)第一个元素。 这是一项操作,可以通过`takeOrdered`方法执行一次操作。 -我们实际上可以进一步改进该解决方案,将第二步和第三步合并在一起(`flatMap`-为每个单词分配一个键-值对,其中键是小写单词,值是出现的次数),并且 第五步和第六步(将 RDD 中的第一个元素按值排序,即该对中的第二个元素): +我们实际上可以进一步改进该解决方案,将第二步和第三步合并在一起(`flatMap`-为每个单词分配一个键-值对,其中键是小写单词,值是出现的次数),以及第五步和第六步(将 RDD 中的第一个元素按值排序,即该对中的第二个元素): ```py In: import re @@ -723,7 +723,7 @@ Out: +-------+------+-------+ In: df.na.drop(subset=["gender"]).show() ``` -另外,如果要为每列设置默认值而不是删除行数据,则可以使用`fill`方法,传递由列名组成的字典(作为字典键)和默认值以替换丢失的数据 在该列中(作为字典中键的值)。 +另外,如果要为每列设置默认值而不是删除行数据,则可以使用`fill`方法,传递由列名组成的字典(作为字典键)和默认值(作为字典中键的值)以替换该列中丢失的数据。 例如,如果要确保将变量平衡(缺少的地方)设置为`0`并将变量性别(缺少的地方)设置为`U`,则只需执行以下操作: @@ -1051,7 +1051,7 @@ Out: root 类似地,我们可以使用单热编码器生成数值观察矩阵。 对于单编码器,在`DataFrame`中将有多个输出列,每个分类特征的每个级别对应一个输出列。 为此,Spark 提供了`pyspark.ml.feature.OneHotEncoderEstimator`类。 -从 Spark 2.3.1 开始,[Python 可用的功能操作包含在以下详尽列表中](https://spark.apache.org/docs/latest/ml-features.html)(所有这些 可以在`pyspark.ml.feature`包中找到)。 除了几个名称外,其他名称应直观易懂,这些内容将以内联或稍后的方式进行解释。 +从 Spark 2.3.1 开始,[Python 可用的功能操作包含在以下详尽列表中](https://spark.apache.org/docs/latest/ml-features.html)(所有这些可以在`pyspark.ml.feature`包中找到)。 除了几个名称外,其他名称应直观易懂,这些内容将以内联或稍后的方式进行解释。 回到该示例,我们现在想将每个分类变量中的级别编码为离散数字。 正如我们所解释的,为此,我们将为每个变量使用`StringIndexer`对象。 此外,我们可以使用 ML 管道并将其设置为其阶段。 diff --git a/new/py-ds-essentials/9.md b/new/py-ds-essentials/9.md index 1cf0add3b466cf6feed7f5e240e4b5f187f97d83..40ce3d021b253bf417529f55b11e47845079f439 100644 --- a/new/py-ds-essentials/9.md +++ b/new/py-ds-essentials/9.md @@ -166,7 +166,7 @@ else: b_dict.get('a_key') ``` -最后,您可以使用集合模块中的数据结构`defaultdict`,它将永远不会引发`KeyError`,因为它是由不带任何参数并为它可能想要的任何不存在的键提供默认值的函数实例化的 要求: +最后,您可以使用集合模块中的数据结构`defaultdict`,它将永远不会引发`KeyError`,因为它是由不带任何参数,并为它可能想要的任何不存在的键提供默认值的函数实例化的: ```py from collections import defaultdict @@ -200,7 +200,7 @@ def sigmoid(x): return 1.0 ``` -最后,您可以使用`lambda`函数来创建匿名函数。 将匿名函数视为简单函数,您可以在代码中的任何位置内联定义,而无需使用`verbose`构造函数(以`def`开头的函数)。 只需调用`lambda`,然后输入其输入参数即可; 然后,冒号将发信号通知要由`lambda`功能执行的命令的开始,这些命令必须在同一行上。 (没有`return`命令!这些命令将从`lambda`函数返回。)您可以将`lambda`函数用作另一个函数的参数,如先前在`defaultdict`中看到的那样,也可以使用它 为了在一行中表达一个功能。 在我们的示例中就是这种情况,我们通过返回`lambda`函数并结合第一个参数来定义函数: +最后,您可以使用`lambda`函数来创建匿名函数。 将匿名函数视为简单函数,您可以在代码中的任何位置内联定义,而无需使用`verbose`构造函数(以`def`开头的函数)。 只需调用`lambda`,然后输入其输入参数即可; 然后,冒号将发信号通知要由`lambda`功能执行的命令的开始,这些命令必须在同一行上。 (没有`return`命令!这些命令将从`lambda`函数返回。)您可以将`lambda`函数用作另一个函数的参数,如先前在`defaultdict`中看到的那样,也可以使用它在一行中表达一个功能。 在我们的示例中就是这种情况,我们通过返回`lambda`函数并结合第一个参数来定义函数: ```py def sum_a_const(c):