随机性是机器学习的重要组成部分。
随机性被用作准备数据和用于学习从输入数据映射到输出数据的预测算法的工具或特征。
为了理解机器学习中统计方法的必要性,您必须了解机器学习中随机性的来源。机器学习中随机性的来源是一种称为伪随机数生成器的数学技巧。
在本教程中,您将了解伪随机数生成器以及何时控制和控制机器学习中的随机性。
完成本教程后,您将了解:
- 应用机器学习中随机性的来源,重点关注算法。
- 什么是伪随机数生成器以及如何在Python中使用它们。
- 何时控制随机数序列以及何时控制随机性。
开始您的项目,阅读我的新书《机器学习统计学》,其中包含分步教程和所有示例的Python源代码文件。
让我们开始吧。

Python 中机器学习随机数生成器入门
照片由LadyDragonflyCC – >;<拍摄,保留部分权利。
教程概述
本教程分为5个部分,它们是:
- 机器学习中的随机性
- 伪随机数生成器
- 何时设置随机数生成器的种子
- 如何控制随机性
- 常见问题
需要机器学习统计学方面的帮助吗?
立即参加我为期7天的免费电子邮件速成课程(附示例代码)。
点击注册,同时获得该课程的免费PDF电子书版本。
机器学习中的随机性
应用机器学习中有许多随机性来源。
随机性被用作一种工具,以帮助学习算法更健壮,并最终带来更好的预测和更准确的模型。
让我们看几个随机性的来源。
数据中的随机性
我们从领域收集的数据样本中存在随机元素,这些数据样本将用于训练和评估模型。
数据可能存在错误或失误。
更深层次地说,数据包含的噪声会模糊输入和输出之间清晰的关系。
评估中的随机性
我们无法访问领域的所有观测值。
我们只使用一小部分数据。因此,我们在评估模型时利用随机性,例如使用 k 折交叉验证在可用数据集的不同子集上拟合和评估模型。
我们这样做是为了了解模型在平均情况下的表现,而不是在特定数据集上的表现。
算法中的随机性
机器学习算法在从数据样本中学习时使用随机性。
这是一个特性,随机性允许算法比不使用随机性时获得更好的数据映射性能。随机性是一个特性,允许算法尝试避免过拟合小训练集并泛化到更广泛的问题。
使用随机性的算法通常被称为随机算法(stochastic algorithms),而不是随机算法(random algorithms)。这是因为尽管使用了随机性,但由此产生的模型仅限于更窄的范围,例如有限的随机性。
机器学习算法中使用的随机性的一些明显例子包括:
- 在随机梯度下降中,在每个训练周期之前对训练数据进行洗牌。
- 在随机森林算法中,为分裂点选择的输入特征的随机子集。
- 人工神经网络中的随机初始权重。
我们可以看到,既有我们必须控制的随机性来源(例如数据中的噪声),也有我们可控的随机性来源(例如算法评估和算法本身)。
接下来,让我们看看我们在算法和程序中使用的随机性来源。
伪随机数生成器
我们注入到程序和算法中的随机性来源是一种称为伪随机数生成器的数学技巧。
随机数生成器是一种从真实随机性来源生成随机数的系统。通常是物理的,例如盖革计数器,其结果被转换成随机数。甚至还有可以购买的物理来源生成的随机数书籍,例如:
我们在机器学习中不需要真正的随机性。相反,我们可以使用伪随机性。伪随机性是看起来接近随机的数字样本,但它是使用确定性过程生成的。
洗牌数据和用随机值初始化系数使用伪随机数生成器。这些小程序通常是一个可以调用的函数,它会返回一个随机数。再次调用,它们会返回一个新的随机数。通常也有包装函数,允许您将随机性作为整数、浮点数、在特定分布内、在特定范围内等获取。
数字是按顺序生成的。序列是确定性的,并用初始数字进行种子。如果您没有显式地为伪随机数生成器设置种子,它可能会使用当前系统时间(以秒或毫秒为单位)作为种子。
种子的值无关紧要。您可以选择任何您想要的。重要的是,相同种子的过程将产生相同的随机数序列。
让我们用一些例子来具体说明这一点。
Python 中的伪随机数生成器
Python 标准库提供了一个名为 random 的模块,它提供了一套用于生成随机数的函数。
Python 使用一种流行且强大的伪随机数生成器,称为 梅森旋转算法(Mersenne Twister)。
可以通过调用 *random.seed()* 函数来为伪随机数生成器设置种子。可以通过调用 *random.random()* 函数生成介于 0 和 1 之间的随机浮点值。
下面的示例设置了伪随机数生成器的种子,生成了一些随机数,然后重新设置种子以演示生成了相同的数字序列。
1 2 3 4 5 6 7 8 9 10 11 12 |
# 演示 Python 伪随机数生成器 from random import seed from random import random # 设置生成器种子 seed(7) for _ in range(5): print(random()) # 设置生成器种子以获得相同的序列 print('Reseeded') seed(7) for _ in range(5): print(random()) |
运行示例将打印五个随机浮点值,然后再次设置伪随机数生成器的种子后打印相同的五个浮点值。
1 2 3 4 5 6 7 8 9 10 11 |
0.32383276483316237 0.15084917392450192 0.6509344730398537 0.07243628666754276 0.5358820043066892 Reseeded 0.32383276483316237 0.15084917392450192 0.6509344730398537 0.07243628666754276 0.5358820043066892 |
NumPy 中的伪随机数生成器
在机器学习中,您很可能使用 scikit-learn 和 Keras 等库。
这些库在底层使用了 NumPy,这是一个能高效处理数字向量和矩阵的库。
NumPy 也有自己的伪随机数生成器实现和方便的包装函数。
NumPy 也实现了梅森旋转算法伪随机数生成器。重要的是,设置 Python 伪随机数生成器的种子不会影响 NumPy 伪随机数生成器。它必须单独设置种子并使用。
下面的示例设置了伪随机数生成器的种子,生成了包含五个随机浮点值的数组,再次设置了生成器的种子,并演示了生成了相同的随机数序列。
1 2 3 4 5 6 7 8 9 10 |
# 演示 numpy 伪随机数生成器 from numpy.random import seed from numpy.random import rand # 设置生成器种子 seed(7) print(rand(5)) # 设置生成器种子以获得相同的序列 print('Reseeded') seed(7) print(rand(5)) |
运行示例将打印第一批数字,以及在生成器重新设置种子后相同的第二批数字。
1 2 3 |
[0.07630829 0.77991879 0.43840923 0.72346518 0.97798951] Reseeded [0.07630829 0.77991879 0.43840923 0.72346518 0.97798951] |
现在我们知道了如何生成受控的随机性,让我们看看可以在哪里有效地使用它。
何时设置随机数生成器的种子
在预测建模项目中,有时您应该考虑为随机数生成器设置种子。
让我们来看两个案例:
- 数据准备。数据准备可能使用随机性,例如对数据进行洗牌或选择值。数据准备必须一致,以便在拟合、评估以及使用最终模型进行预测时,数据始终以相同的方式准备。
数据分割。数据分割,例如训练/测试分割或 k 折交叉验证,必须一致进行。这是为了确保每个算法都在相同的数据子集上以相同的方式进行训练和评估。
您可能希望在每个任务之前或执行一批任务之前为伪随机数生成器设置一次种子。通常哪一个都可以。
有时您可能希望算法表现一致,这可能是因为它每次都在完全相同的数据上进行训练。当算法在生产环境中运行时,可能会发生这种情况。在教程环境中演示算法时也可能发生这种情况。
在这种情况下,在拟合算法之前初始化种子可能是有意义的。
如何控制随机性
随机机器学习算法在每次使用相同数据运行时都会略有不同。
这将导致每次训练时模型的性能略有不同。
如前所述,我们可以每次都使用相同的随机数序列来拟合模型。在评估模型时,这是一种不良做法,因为它掩盖了模型固有的不确定性。
更好的方法是评估算法,使其报告的性能包含模型性能的测量不确定性。
我们可以通过重复多次评估算法并使用不同的随机数序列来实现这一点。伪随机数生成器可以在评估开始时设置一次种子,或者可以在每次评估开始时用不同的种子设置。
这里需要考虑两个方面的不确定性:
- 数据不确定性:在多个数据分割上评估算法将提供对算法性能如何随训练和测试数据变化情况的洞察。
- 算法不确定性:在相同的数据分割上多次评估算法将提供对算法性能如何独立变化的洞察。
总的来说,我建议同时报告这两种不确定性来源。这是算法在每次评估运行时在不同的数据分割上进行拟合,并具有新的随机序列。评估过程可以在开始时为随机数生成器设置一次种子,然后可以重复该过程,也许 30 次或更多次,以提供可总结的性能分数总体。
这将公平地描述模型性能,同时考虑到训练数据和学习算法本身中的方差。
常见问题
我能预测随机数吗?
即使使用深度神经网络,您也无法预测随机数序列。
真正的随机数会带来更好的结果吗?
据我所知,使用真正的随机性通常没有帮助,除非您正在处理物理过程的模拟。
最终模型怎么样?
最终模型是选择在您可用于进行预测的所有可用训练数据上训练的算法和配置。此模型的性能将落在已评估模型的方差范围内。
扩展
本节列出了一些您可能希望探索的扩展本教程的想法。
- 确认设置 Python 伪随机数生成器的种子不会影响 NumPy 伪随机数生成器。
- 开发生成范围内的整数和高斯随机数的示例。
- 查找一个非常简单的伪随机数生成器的方程式并实现它。
如果您探索了这些扩展中的任何一个,我很想知道。
进一步阅读
如果您想深入了解,本节提供了更多关于该主题的资源。
文章
API
文章
总结
在本教程中,您了解了随机性在应用机器学习中的作用以及如何控制和利用它。
具体来说,你学到了:
- 机器学习具有随机性来源,例如数据样本和算法本身。
- 随机性通过伪随机数生成器注入到程序和算法中。
- 有时随机性需要仔细控制,有时需要控制随机性。
你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。
你好,Jason
TensorFlow.js 已发布。我们可以将 TensorFlow 代码用于任何 JavaScript Web 应用程序。我们还可以使用预训练模型并将其转换为 TensorFlow.js。似乎由 ML/数据科学驱动的 Web 应用程序就在眼前。您是否有计划为此创建一些博客文章?那将是完美的。
https://www.youtube.com/watch?v=YB-kfeNIPCE
感谢 Bart 的建议。
凭直觉,我认为在 JS 中学习和实践机器学习就像在 Octave 中工作一样。可能很有趣,但对工业机器学习无用。
非常遗憾听到您的意见,我不同意。我的想法更多地是关于我们如何将人工智能普及到大众。基于 Web 浏览器的应用程序非常适合!而且我们仍然可以在 Python 中创建模型并将其转换为 TF.js 使用。
TF.js 将不仅仅是为了好玩,它将是进一步利用人工智能的媒介。我正在寻找机会学习更多并利用它。您的博客一直是扩展知识的绝佳平台。很遗憾听到没有关于 TF.js 的内容……
如果我告诉一个项目团队,我正在使用 TensorFlow in JS 解决一个业务问题,我将不得不仔细而有根据地为该决定辩护。我现在还不能做到。
您将如何为该决定辩护?
如上所述,基于浏览器的应用程序是某些未来 AI 应用程序的完美媒介。现在价值十亿美元的问题是,具体将开发什么以及在哪个领域。请看看谷歌或 Facebook 的故事。这些企业都是凭空开始的。这里也可能发生同样的情况。
看,我们有 2 个很棒的工具:
– 人工智能
– + 一个接触的媒介——Web 浏览器
现在这两个结合起来可以带来颠覆。最好的想法将得到回报。
阅读这篇文章让我想起了任何软件应用程序背后的内存都是数据库。同样,我们在生产中是否有任何数据库支持机器学习应用程序?在学习过程中,我们可能会将“种子”存储在源代码文件中,但种子存储在生产中的随机数的位置在哪里?
模型捕获了学习到的信息。例如,系数或权重。
感谢您的精彩教程!在我没有任何 Python 或机器学习经验的情况下,我能够成功地按照您的步骤取得了成功!
干得好!
嗨,Jason,
我正在做一个量子随机生成器相关的项目,并试图找出真正的随机数是否能给 AI 领域带来任何好处,但根据您对“真正的随机数会带来更好的结果吗?”的回答,似乎在大多数情况下,量子随机数与伪随机数相比没有优势?
可能不会,但可以测试这个假设。
非常感谢您的回复。我不是机器学习专家,但对 ML 有一些了解,并且有一些 scikit-learn 编程经验,所以我还计划进行一些比较测试(梅森旋转算法 vs. 量子随机数生成器),基于一些假设(在使用真正的随机数时),例如:
1. 模型性能是否会更好?
2. 收敛速度是否会更快?
3. 是否能更好地避免模型过拟合?
但由于我对 ML 的了解有限,所以我不太确定我做的工作是否毫无意义。
您能否给出一些建议?我应该尝试 ML 中所有可能的随机部分来查看结果吗?还是基于特定数据集或算法的测试更有意义?谢谢。
是的,我曾经从事过随机优化(如遗传算法和模拟退火),并且有关于真实随机数与伪随机数关系的经典论文。
也许它们可以作为良好的背景阅读材料?
太好了,是否可以在任何公开可用的数据集和算法的基础上进行这些测试?您能分享这些论文的 URL 吗?非常感谢。
这是几十年前的事情了,您可以在 scholar.google.com 上搜索。
非常感谢,我找到了它们,正计划进行一些类似的测试。
嗨,Jason,
在调整神经网络的超参数时,我同时遇到了数据不确定性方差(由于随机数生成器)和算法方差。我应该将我的随机种子生成器固定到一个固定值,还是这只是掩盖了问题?请指导我!
不,而是报告模型的平均性能——报告不确定性!
https://machinelearning.org.cn/randomness-in-machine-learning/
并查看此内容:
https://machinelearning.org.cn/evaluate-skill-deep-learning-models/
之后,您可以通过集成方法作为最终模型来尝试减少预测中的方差。
https://machinelearning.org.cn/start-here/#better
谢谢!我正在研究这个。
希望有所帮助。
嗨,Jason,
一如既往,又一篇很棒的文章。我有一个关于重复过程以应对算法不确定性的问题。
正如您提到的,我们应该在((相同的数据分割))上多次评估算法,所以我很想知道我们是否可以使用 sklearn.model_selection.RepeatedStratifiedKFold,例如 n_repeats>=30?因为我从您的话中理解的是,我们应该在每次重复时都拥有((相同的数据分割)),但当我们使用 RepeatedStratifiedKFold 时,在每次重复步骤中,我们会得到不同的数据 K 折。这有问题吗?如果有,有什么建议?
你好 Sadegh…以下是关于最佳实践的很棒的资源。
https://machinelearning.org.cn/training-validation-test-split-and-cross-validation-done-right/
谢谢!