Numpy Randn 和 RandomState 之间的区别

Difference between Numpy Randn and RandomState

我对 np.random.randn(n) 的印象如果第二次执行会产生不同的样本。 np.random.RandomState(n_clusters).randn(n) 如果第二次执行会产生相同的样本。这个对吗?另外,np.random.seed() 有什么作用?

我的代码:

np.random.RandomState(2).randn(2)
Out[6]: array([-0.41675785, -0.05626683])

np.random.RandomState(4).randn(2)
Out[7]: array([0.05056171, 0.49995133])

np.random.RandomState(42).randn(2)
Out[8]: array([ 0.49671415, -0.1382643 ])

np.random.RandomState(42).randn(2)
Out[9]: array([ 0.49671415, -0.1382643 ])

np.random.RandomState(4).randn(2)
Out[10]: array([0.05056171, 0.49995133])

np.random.RandomState(2).randn(2)
Out[11]: array([-0.41675785, -0.05626683])

np.random.randn(2)
Out[12]: array([ 0.47143516, -1.19097569])

np.random.randn(2)
Out[13]: array([ 1.43270697, -0.3126519 ])

np.random 使用 Pseudorandom number generator(也称为 PRNG)生成看起来随机的数字序列。基本上它有一个内部“种子”号,它应用一些函数生成序列中的下一个数字。然后此函数更新内部种子,因此序列中的下一个数字可能会有所不同。

np.random.RandomState(2) 创建一个新的 PRNG,其内部种子设置为 2。此生成器将从固定序列中生成数字,这就是为什么每次调用 np.random.RandomState(2).randn(2) 时都会得到相同的 2 个数字。如果您改为保存 RandomState 对象并不断对其调用 randn(2),您将获得与另一个 RandomState(2).

相同的数字序列
>>> rs1 = np.random.RandomState(2)
>>> rs2 = np.random.RandomState(2)
>>> rs1.randn(2), rs2.randn(2)
(array([-0.41675785, -0.05626683]), array([-0.41675785, -0.05626683]))
>>> rs1.randn(2), rs2.randn(2)
(array([-2.1361961 ,  1.64027081]), array([-2.1361961 ,  1.64027081]))

np.random.seed(2) 会将种子设置为此 PRNG 的 全局 实例 2。通常它的种子是从进程开始时的时间戳之类的东西,所以每次你 运行 一个程序时你都会得到新的随机数。设置这个种子将使它成为一个确定的随机数序列,当调用像 np.random.randn(2) 这样的东西时,它使用全局 PRNG。

>>> np.random.seed(2)
>>> np.random.randn(2)
array([-0.41675785, -0.05626683])
>>> np.random.randn(2)
array([-2.1361961 ,  1.64027081])
  • randn returns 值来自使用随机数生成器的标准正态分布。它使用特定于您调用此函数的对象的数学算法,值取决于引擎的最后状态。
  • RandomState returns 一个伪随机数生成器引擎,根据您传递的整数使用 Mersenne Twister algorithm, initializing its state

你是对的,np.random.RandomState(n_clusters).randn(n) 中的 np.random.RandomState(n_clusters) 部分首先使用种子 n_clusters 创建了一个 prng 引擎。初始状态仅取决于种子,因此如果您稍后使用相同的种子创建引擎,它将处于相同的初始状态,生成相同的随机数。然后方法randn(n)使用底层的Mersenne Twister算法从正态分布中生成2个随机数(内部是32位整数,一共生成4个,转化为值)

prng 引擎的初始状态必须在开始时定义。您可以定义种子,或者如果您省略它,就像在 np.random.seed() 中一样,numpy 会根据时间或通过读取磁盘的某些部分来为您定义它以生成随机性的初始来源。函数 np.random.seed 定义了全局 prng 引擎的种子,与 np.random.RandomState 相比,您可以在其中保存 return 值并稍后再次使用该引擎,

myprng = numpy.random.RandomState(2)
myprng.randn(10)