问题
I know that numpy.random.seed(seed)
will output the same numbers if I use the same seed. My question is, does this change over time? If I try to call it again tomorrow, will it still output the same set of random numbers as yesterday?
回答1:
The np.random documentation describes the PRNGs used. Apparently, there was a partial switch from MT19937 to PCG64 in the recent past. If you want consistency, you'll need to:
- fix the PRNG used, and
- ensure that you're using a local handle (e.g.
RandomState
,Generator
) so that any changes to other external libraries don't mess things up by callingnp.random
globals themselves.
In this example, we make use of the newer BitGenerator API, which provides a selection of various PRNGs.
from numpy.random import Generator, PCG64
rg = Generator(PCG64(1234))
Which may be used as follows:
>>> rg.uniform(0, 10, 10)
array([9.767, 3.802, 9.232, 2.617, 3.191, 1.181, 2.418, 3.185, 9.641,
2.636])
If we re-run this any number of times (even within the same REPL!), we will always obtain the same random number generator. PCG64, like MT19937, provides the following guarantee:
Compatibility Guarantee
PCG64 makes a guarantee that a fixed seed and will always produce the same random integer stream.
Though, as @user2357112 supports Monica noted, changes to the random API functions that use the random integer sequence (e.g. np.random.Generator.uniform
) are still technically possible, though unlikely.
In order to generate multiple generators, one can make use of SeedSequence.spawn(k)
to generate k
different SeedSequences. This is useful for consistent concurrent computations:
from numpy.random import Generator, PCG64, SeedSequence
sg = SeedSequence(1234)
rgs = [Generator(PCG64(s)) for s in sg.spawn(10)]
回答2:
The legacy RandomState
API and the module-level random generation functions (actually methods of a hidden RandomState) have a backward compatibility guarantee:
Compatibility Guarantee
A fixed bit generator using a fixed seed and a fixed series of calls to ‘RandomState’ methods using the same parameters will always produce the same results up to roundoff error except when the values were incorrect. RandomState is effectively frozen and will only receive updates that are required by changes in the the internals of Numpy. More substantial changes, including algorithmic improvements, are reserved for Generator.
Identical sequences of calls from an identical seed will produce identical-up-to-rounding-error results, unless there was something wrong with the old results (like if it turned out a method wasn't producing the distribution it was supposed to).
This comes at the expense of being locked into bad design choices. For example, numpy.random.choice
with replace=False
is atrociously slow due to a bad implementation that cannot be fixed without breaking backward compatibility. numpy.random.Generator.choice
does not have this problem, since it is not bound by the same compatibility guarantee.
来源:https://stackoverflow.com/questions/62309424/does-numpy-random-seed-always-give-the-same-random-number-every-time