numpy.random.seed(0)做了什么?

时间:2014-02-01 05:28:34

标签: python numpy

np.random.seed在Scikit-Learn教程的下面代码中做了什么?我对NumPy的随机状态生成器不太熟悉,所以我非常感谢外行人对此的解释。

np.random.seed(0)
indices = np.random.permutation(len(iris_X))

11 个答案:

答案 0 :(得分:370)

np.random.seed(0)使随机数可预测

>>> numpy.random.seed(0) ; numpy.random.rand(4)
array([ 0.55,  0.72,  0.6 ,  0.54])
>>> numpy.random.seed(0) ; numpy.random.rand(4)
array([ 0.55,  0.72,  0.6 ,  0.54])

种子重置(每次),每次都会出现相同的数字。

如果未重置随机种子,则每次调用都会出现不同的数字:

>>> numpy.random.rand(4)
array([ 0.42,  0.65,  0.44,  0.89])
>>> numpy.random.rand(4)
array([ 0.96,  0.38,  0.79,  0.53])

(伪)随机数通过从数字(种子)开始,将其乘以一个大数字,然后取该产品的模数来工作。然后将得到的数字用作种子以生成下一个“随机”数字。当您设置种子(每次)时,它每次都会执行相同的操作,为您提供相同的数字。

如果您想要看似随机的数字,请不要设置种子。但是,如果您的代码使用了要调试的随机数,那么在每次运行之前设置种子会非常有帮助,这样每次运行时代码都会执行相同的操作。

要获得每次运行的最随机数,请致电numpy.random.seed()This将导致numpy将种子设置为从/dev/urandom或其Windows模拟获得的随机数,或者,如果这两者都不可用,它将使用时钟。

答案 1 :(得分:23)

如果每次调用numpy的其他随机函数时设置np.random.seed(a_fixed_number),结果将是相同的:

>>> import numpy as np
>>> np.random.seed(0) 
>>> perm = np.random.permutation(10) 
>>> print perm 
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0) 
>>> print np.random.permutation(10) 
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0) 
>>> print np.random.permutation(10) 
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0) 
>>> print np.random.permutation(10) 
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0) 
>>> print np.random.rand(4) 
[0.5488135  0.71518937 0.60276338 0.54488318]
>>> np.random.seed(0) 
>>> print np.random.rand(4) 
[0.5488135  0.71518937 0.60276338 0.54488318]

但是,如果您只是调用一次并使用各种随机函数,结果仍然会有所不同:

>>> import numpy as np
>>> np.random.seed(0) 
>>> perm = np.random.permutation(10)
>>> print perm 
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0) 
>>> print np.random.permutation(10)
[2 8 4 9 1 6 7 3 0 5]
>>> print np.random.permutation(10) 
[3 5 1 2 9 8 0 6 7 4]
>>> print np.random.permutation(10) 
[2 3 8 4 5 1 0 6 9 7]
>>> print np.random.rand(4) 
[0.64817187 0.36824154 0.95715516 0.14035078]
>>> print np.random.rand(4) 
[0.87008726 0.47360805 0.80091075 0.52047748]

答案 2 :(得分:15)

如上所述,numpy.random.seed(0)将随机种子设置为0,因此从随机获得的伪随机数将从同一个点开始。在某些情况下,这可能适用于调试。但是,经过一些阅读后,这似乎是错误的方法,如果你有线程,因为它不是线程安全的。

来自differences-between-numpy-random-and-random-random-in-python

  

对于numpy.random.seed(),主要的困难是它不是   线程安全 - 也就是说,如果你有许多不同的东西,它是不安全的   执行的线程,因为如果两个,它不能保证工作   不同的线程同时执行该功能。如果   你没有使用线程,如果你可以合理地期待你   不需要在将来以这种方式重写你的程序,   numpy.random.seed()应该可以用于测试目的。如果有的话   任何理由怀疑你将来可能需要线程,它是   从长远来看,建议更安全,并使当地   numpy.random.Random类的实例。据我所知,   random.random.seed()是线程安全的(或者至少,我还没有找到任何东西   证据相反)。

如何解决这个问题的例子:

from numpy.random import RandomState
prng = RandomState()
print prng.permutation(10)
prng = RandomState()
print prng.permutation(10)
prng = RandomState(42)
print prng.permutation(10)
prng = RandomState(42)
print prng.permutation(10)

可能会给:

  

[3 0 4 6 8 2 1 9 7 5]

     

[1 6 9 0 2 7 8 3 5 4]

     

[8 1 5 0 7 2 9 4 3 6]

     

[8 1 5 0 7 2 9 4 3 6]

最后,请注意,由于xor的工作方式,可能会出现初始化为0(与没有所有位0的种子相反)可能导致少数第一次迭代的非均匀分布的情况,但这取决于关于算法,并且超出了我目前的担忧和这个问题的范围。

答案 3 :(得分:3)

想象一下,您正在向某人展示如何使用一堆“随机”数字进行编码。通过使用numpy种子,他们可以使用相同的种子编号并获得相同的“随机”编号集。

所以它不是完全随机的,因为算法会散出数字,但看起来像是随机生成的束。

答案 4 :(得分:1)

我在神经网络中经常使用它。众所周知,当我们开始训练神经网络时,我们会随机初始化权重。在特定数据集上对这些权重训练模型。经过数个时期后,您将获得一组训练有素的权重。

现在,假设您要从头开始再次训练,或者想将模型传递给其他人来重现结果,权重将再次初始化为随机数,该数字与以前的数字大多不同。在与先前相同的时期(保持相同的数据和其他参数)之后,获得的训练权重将有所不同。问题在于您的模型不再具有可复制性,因为每次您从头开始训练模型时,模型都会提供不同的权重集。这是因为每次都会使用不同的随机数来初始化模型。

如果每次您从头开始训练时,模型都会初始化为同一组随机初始化权重,该怎么办?在这种情况下,您的模型可以重现。这是通过numpy.random.seed(0)实现的。通过将seed()提到一个特定的数字,您将始终挂在同一组随机数上。

答案 5 :(得分:1)

以上所有答案均显示了代码中np.random.seed()的实现。我将尽力简要地解释它为什么会发生。计算机是基于预定义算法设计的计算机。计算机的任何输出都是在输入上实现的算法的结果。因此,当我们要求计算机生成随机数时,请确保它们是随机的,但计算机并不仅仅是随机地得出它们!

因此,当我们编写np.random.seed(any_number_here)时,该算法将输出一组特定于参数any_number_here的数字。如果我们传递正确的参数,几乎就像可以获得一组特定的随机数。但是,这将要求我们了解算法的工作方式,这非常繁琐。

因此,例如,如果我写np.random.seed(10),即使我在10年后执行同一行,除非算法发生变化,否则我获得的特定数字集将保持不变。

答案 6 :(得分:1)

我希望给出一个简短的答案:

seed使(下一个系列)随机数可预测。您可以考虑每次调用seed后,它都会预定义序列号,而numpy random会保留它的迭代器,然后每次您获得一个随机数时,它都会调用get next。

例如:

np.random.seed(2)
np.random.randn(2) # array([-0.41675785, -0.05626683])
np.random.randn(1) # array([-1.24528809])

np.random.seed(2)
np.random.randn(1) # array([-0.41675785])
np.random.randn(2) # array([-0.05626683, -1.24528809])

您会注意到,当我设置相同的种子时,无论您每次从numpy请求多少个随机数,它总是给出相同的数字序列,在这种情况下为array([-0.41675785, -0.05626683, -1.24528809])

答案 7 :(得分:0)

随机种子指定计算机生成随机数序列的起点。

例如,假设您要在Excel中生成一个随机数(请注意:Excel将种子的上限限制为9999)。在此过程中,如果您在“随机种子”框中输入数字,则可以再次使用同一组随机数字。如果在框中键入“ 77”,并在下次运行随机数生成器时键入“ 77”,则Excel将显示同一组随机数。如果您输入“ 99”,则会得到一组完全不同的数字。但是,如果您恢复为77的种子,那么您将获得与开始时相同的一组随机数。

例如,“取一个数字x,加900 + x,然后减去52。”为了开始该过程,您必须指定一个起始数字x(种子)。让我们以77开头:

加900 + 77 = 977 减52 = 925 按照相同的算法,第二个“随机”数将是:

900 + 925 = 1825 减52 = 1773 这个简单的示例遵循一个模式,但是计算机数字生成背后的算法要复杂得多

答案 8 :(得分:0)

在所有平台/系统上,设置特定种子值后生成的所有随机数都相同。

答案 9 :(得分:0)

Numpy文档中有一个很好的解释: https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.random.RandomState.html 它指的是 Merenne Twister伪随机数生成器。有关该算法的更多详细信息,请点击此处:https://en.wikipedia.org/wiki/Mersenne_Twister

答案 10 :(得分:0)

numpy.random.seed(0)
numpy.random.randint(10, size=5)

这将产生以下输出: array([5, 0, 3, 3, 7]) 同样,如果我们运行相同的代码,我们将获得相同的结果。

现在,如果我们将种子值0更改为1或其他值:

numpy.random.seed(1)
numpy.random.randint(10, size=5)

这将产生以下输出:array([5 8 9 5 0]),但是现在输出与上面的不一样。