scipy.stats 种子?
Posted
技术标签:
【中文标题】scipy.stats 种子?【英文标题】:scipy.stats seed? 【发布时间】:2013-04-07 16:08:19 【问题描述】:我正在尝试使用不同的种子生成 scipy.stats.pareto.rvs(b, loc=0, scale=1, size=1)。
在 numpy 中,我们可以使用 numpy.random.seed(seed=233423) 播种。
有没有办法播种 scipy stats 生成的随机数。
注意:我没有使用 numpy pareto,因为我想给出不同的比例值。
【问题讨论】:
对于 Generator 类更方便、更健壮的现代世界,请参阅@Abhinav 的回答 【参考方案1】:scipy.stats
只是使用numpy.random
来生成它的随机数,所以numpy.random.seed()
也可以在这里工作。例如,
import numpy as np
from scipy.stats import pareto
b = 0.9
np.random.seed(seed=233423)
print pareto.rvs(b, loc=0, scale=1, size=5)
np.random.seed(seed=233423)
print pareto.rvs(b, loc=0, scale=1, size=5)
将打印两次[ 9.7758784 10.78405752 4.19704602 1.19256849 1.02750628]
。
【讨论】:
有没有 no 方法给 scipy.stats 一个 numpy.random.RandomState 对象?我真的不想碰默认的随机流。 显然不是(就像现在一样),由 Robert Kern 在 scipy-users 邮件列表中确认! 更好的是,您可以这样做:scipy.stats.ortho_group.rvs(dim=5, random_state=N)
【参考方案2】:
对于那些在 7 年后偶然发现这个问题的人来说,numpy 随机状态生成器函数发生了重大变化。根据文档here 和here,RandomState
类被替换为Generator
类。 RandomState
保证与旧版本/代码兼容,但不会收到任何实质性更改,包括算法改进,这些更改是为 Generator
保留的。
为了说明如何在同一实验中将现有的基于 Numpy 的随机流传递给 Scipy 函数,下面给出了一些示例和推理,哪些情况是可取的以及为什么。
from numpy.random import Generator, PCG64
from scipy.stats import binom
n, p, size, seed = 10, 0.5, 10, 12345
# Case 1 : Scipy uses some default Random Generator
numpy_randomGen = Generator(PCG64(seed))
scipy_randomGen = binom
print(scipy_randomGen.rvs(n, p, size))
print(numpy_randomGen.binomial(n, p, size))
# prints
# [6 6 5 4 6 6 8 6 6 4]
# [4 4 6 6 5 4 5 4 6 7]
# NOT DESIRABLE as we don't have control over the seed of Scipy random number generation
# Case 2 : Scipy uses same seed and Random generator (new object though)
scipy_randomGen.random_state=Generator(PCG64(seed))
numpy_randomGen = Generator(PCG64(seed))
print(scipy_randomGen.rvs(n, p, size))
print(numpy_randomGen.binomial(n, p, size))
# prints
# [4 4 6 6 5 4 5 4 6 7]
# [4 4 6 6 5 4 5 4 6 7]
# This experiment is using same sequence of random numbers, one is being used by Scipy
# and other by Numpy. NOT DESIRABLE as we don't want repetition of some random
# stream in same experiment.
# Case 3 (IMP) : Scipy uses an existing Random Generator which can being passed to Scipy based
# random generator object
numpy_randomGen = Generator(PCG64(seed))
scipy_randomGen.random_state=numpy_randomGen
print(scipy_randomGen.rvs(n, p, size))
print(numpy_randomGen.binomial(n, p, size))
# prints
# [4 4 6 6 5 4 5 4 6 7]
# [4 8 6 3 5 7 6 4 6 4]
# This should be the case which we mostly want (DESIRABLE). If we are using both Numpy based and
#Scipy based random number generators/function, then not only do we have no repetition of
#random number sequences but also have reproducibility of results in this case.
【讨论】:
非常有帮助!这是新常态,最好的答案:) 对于案例 3,这是否会改变所有使用 binom 的随机状态,即使是其他模块?这是否意味着在其他模块中更改 binom 的使用会破坏其在此处使用的可重复性?将您的方法与 Scotty1- 的答案结合起来,将 numpy_randomGen 显式传递给本地分布实例会更好吗? 如果我正确理解了您的问题,我认为 Scipy.binom 在同一范围/模块内的所有使用状态都会发生变化,或者我们明确传递 scipy_randomgen 对象的位置。 我认为它会超出当前的模块和范围。导入 binom 的任何代码不会获取更改的状态,包括您无法控制的第三方代码吗? IE。将 scipy_randomgen 对象传递给 binom 也会将其传递给导入 binom 的其他代码。但我还没有测试过....【参考方案3】:对于四年后看到这篇文章的人,Scipy 确实提供了一种将np.random.RandomState
对象传递给其随机变量类的方法,请参阅rv_continuous 和rv_discrete 了解更多详细信息。 scipy 文档是这样说的:
seed : None 或 int 或 numpy.random.RandomState 实例,可选
此参数定义用于绘制随机变量的 RandomState 对象。如果没有(或 np.random),则使用全局 np.random 状态。如果是整数,则用于播种本地 RandomState 实例。默认为无。
不幸的是,在连续/离散 rvs 子类 rv_continuous
或 rv_discrete
之后,此参数似乎不可用。但是,random_state
属性确实属于 sublass,这意味着我们可以在实例化之后使用 np.random.RandomState
的实例来设置种子,如下所示:
import numpy as np
import scipy.stats as stats
alpha_rv = stats.alpha(3.57)
alpha_rv.random_state = np.random.RandomState(seed=342423)
【讨论】:
我认为这是更好的答案,see 使用numpy.random.seed
时可能遇到的问题,RandomState
更健壮imo...跨度>
【参考方案4】:
除了 user5915738 的答案之外,我认为这通常是最好的答案,我想指出最方便的方法来播种 scipy.stats
分布的随机生成器。
您可以在使用rvs
方法生成分布时设置种子,方法是将种子定义为整数,用于在内部播种np.random.RandomState
:
uni_int_seed = scipy.stats.uniform(-.1, 1.).rvs(10, random_state=12)
或者直接定义np.random.RandomState
:
uni_state_seed = scipy.stats.uniform(-.1, 1.).rvs(
10, random_state=np.random.RandomState(seed=12))
这两种方法是等价的:
np.all(uni_int_seed == uni_state_seed)
# Out: True
与将其分配给rv_continuous
或rv_discrete
的random_state
相比,此方法的优势在于,您始终可以显式控制rvs
的随机状态,而使用my_dist.random_state = np.random.RandomState(seed=342423)
,种子是在每次调用 rvs
后丢失,在丢失分布跟踪时可能导致不可重现的结果。
也照The Zen of Python:
显式优于隐式。
:)
【讨论】:
以上是关于scipy.stats 种子?的主要内容,如果未能解决你的问题,请参考以下文章