当使用随机数生成器在Python代码中重现性时,推荐的方法似乎是构造单独的RandomState对象。不幸的是,像scipy.stats这样的基本软件包不能(据我所知)设置为使用特定的RandomState,而只使用numpy.random的当前状态。 我目前的解决方法是使用上下文管理器来保存RNG的状态,然后在退出时重置它,如下所示:
class FixedSeed:
def __init__(self, seed):
self.seed = seed
self.state = None
def __enter__(self):
self.state = rng.get_state()
np.random.seed(self.seed)
def __exit__(self, exc_type, exc_value, traceback):
np.random.set_state(self.state)
文档中有很多关于以任何方式更改状态的警告 - 上述方法一般是安全的吗? (从某种意义上说,更改是上下文的本地更改,而我的其余代码将不受影响)
答案 0 :(得分:2)
set_state和get_state不需要使用任何随机 NumPy中的分布。如果手动改变内部状态,则 用户应该确切地知道他/她在做什么。
这听起来很吓人。在一个公开的,有文件记录的界面上对这一警告的可能解释是“确切地知道”意味着“知道无缘无故地重新接种PRNG会严重降低随机性”。但是你知道你想要在你的上下文期间非常具体地减少随机性。
为了支持这个猜想,我查看了包含以下代码的numpy/test_random.py:
class TestSeed(TestCase):
def test_scalar(self):
s = np.random.RandomState(0)
assert_equal(s.randint(1000), 684)
s = np.random.RandomState(4294967295)
assert_equal(s.randint(1000), 419)
因为他们确实需要确定性的结果。请注意,他们创建了np.random.RandomState
的实例,但我在代码中找不到set_state()
会破坏任何内容的指示。
如果有疑问,请编写一个
的测试套件