【问题标题】:What does happen if seed value is not declared throughout in a python code?如果没有在 python 代码中声明种子值会发生什么?
【发布时间】:2021-11-24 06:25:57
【问题描述】:
import random 
import matplotlib.pyplot as plt 
 
nums = [] 

mu = 0
sigma = 2
    
for i in range(100): 
    temp = random.gauss(mu, sigma)
    nums.append(temp) 
         
plt.plot(nums) 
plt.show()

在这里,我还没有声明种子值。那么,会不会考虑 i 的每次迭代都有不同的种子值?在这种 模拟,或者说在长蒙特卡罗模拟中,是否建议 选择不同的种子值而不是特定的固定种子 价值?

【问题讨论】:

  • 仅当您希望脚本在每次运行时产生相同的数字序列时才设置种子(在开头一次)。如果这无关紧要,请不要设置种子。
  • 您的问题听起来像是您对伪随机数生成器和播种有概念上的误解。有关播种作用的说明,请参阅here
  • 谢谢。 @hpaulj 先生,但是,我想知道为了编写诸如随机游走问题或噪声幅度生成之类的蒙特卡罗代码,在每次下一次迭代中选择不同的或新的种子值会更好吗?谢谢。
  • @pjs ;感谢您的友好建议。

标签: python-3.x numpy random random-seed


【解决方案1】:

如果您不使用 random.seed() 初始化伪随机生成器,那么 Python 将尝试从操作系统获取随机种子,但如果失败,它将使用系统时间。

没有种子的随机数列表:

import random
for i in range(5):
    print(random.randint(1,50))

输出:

19
44
33
12
42

如果您希望实验/模拟的结果可重现,建议使用已知种子值初始化伪随机数生成器。

使用种子值的可重现随机数列表:

import random
for i in range(5):
    random.seed(13)
    print(random.randint(1,50))

输出:

17
17
17
17
17

这表明 Python 的 random 模块不会产生真正的随机数,如果您知道种子值,这是可以预测的。

PCG(置换同余生成器)

PCG 是一组统计上很好的难以预测的随机数生成算法,可以在numpy.random 模块中找到。下面是一些使用由secrets 模块提供的不可预测值作为种子的生成器来生成正态分布的代码。生成器也可以用于probability distributions的范围。

import secrets
from numpy.random import Generator, PCG64

random_seed = secrets.randbits(64) # An integer with 64 random bits
random_gen = Generator(PCG64(random_seed))

data = random_gen.normal(size=10000)

【讨论】:

  • 似乎然后使用不固定的种子值(即在代码中根本不声明任何查看值)来制定关于随机游走或噪声幅度生成的蒙特卡罗数据会更好,对吧?
  • 伪随机数生成器中有一个模式,如果你有足够长的序列,模式就会出现。 secrets 模块生成加密性强的随机数,对于更多随机数来说是更好的选择。如果您想要真正的随机数,请使用麦克风或天线等外部输入源来测量无线电信号。计算机之外的世界是熵的最佳来源。
  • 我应该如何使用 to secrets 模块来生成特定类型的随机数分布?即secrets.random.gauss(mu, sigma) 之类的?
  • secrets 模型不适用于建模或模拟,它会生成不可预测的数据,因此它是一个很好的种子值。我已经更新了我的答案,以包含一个使用更好的随机数生成技术 PCG 的示例。
  • 非常感谢,但是请让我再问一件事,import random for i in range(5): random.seed(13) print(random.randint(1,50)) -- 如果我在代码开头设置 seed() 会怎样,也就是说,在“i”的范围之前?代码会在整个代码/编译过程中考虑特定的 seed() 值吗?
【解决方案2】:

不,random 不会重新播种,除非您告诉它这样做。

random 为其操作实现了Random 类。此类在初始化时自行播种 - 使用默认种子或您提供的种子。您可以使用 .seed 方法重新设定种子,但这通常不会使用您自己创建的 Random 对象来完成。

然后模块创建Random 的一个实例并将其方法分配给模块级变量。当您调用random.gauss 时,这实际上是该对象上的一个方法。该对象使用默认的种子算法。如果您不想要默认算法,或者如果您想使用已知值作为可重现随机数的种子,您可以致电random.seed(yourvalue)

但是在默认的随机对象上,整个可重复性的东西是不可靠的。您系统中的其他东西也调用随机数会弄乱您所谓的可重复数字。如果您想要重现性(也许是为了测试?),请创建您自己的 random.Random 对象。

【讨论】:

    猜你喜欢
    • 2018-05-01
    • 2011-07-06
    • 2019-06-02
    • 1970-01-01
    • 2019-06-10
    • 2019-01-19
    • 1970-01-01
    • 2015-08-30
    • 1970-01-01
    相关资源
    最近更新 更多