set.seed(123) # 设置随机种子, 让结果可重现
while(TRUE) {
x = rnorm(1)
print(x)
if(x > 1) break
}
在学习的过程中,看到了函数set.seed(...),对于例子set.seed(123),为什么要取123(后边把这个整体统一称为种子)以及这个函数的作用到底是什么?一句“设置随机种子,让结果可重现”让我很迷糊,通过查找R的帮助文档和查看R社区里其他人的诸多回答,解答了我的疑惑,现在整理如下:
问题一 :如何取种子值?取种子值时需要注意哪些要求?
从两种可能的情景来考虑,第一种,针对普通的问题,值并不重要。按照这样的说法,可以随便取,比如说,生日,单纯的数字排列123,等等。与此同时,为了防止有人质疑我们对随机种子的选择时,可以这样做:首先随机生成一个种子,然后使用它。代码如下:
seed <- sample(.Machine$integer.max, size=1) ;
seed ;
set.seed(seed);
这样做得好处还有一个,那就是可以避免使用相同的种子。
第二种,当我们尝试优化涉及随机生成数字的函数时,例如在基于模拟的估计中,固定种子是必不可少的。笼统地说,如果我们不固定种子,由于抽取不同的随机数而产生的变化很可能会导致优化算法失败。
问题二 在R版本一致的前提下,使用相同的种子,会得到相同的结果吗?
在类似的硬件和类似的 R 版本上,使用相同的种子,你会得到相同的结果。但一般来说,可再现性set.seed(...)
是为了确保在同一台(或几乎相同的)机器上的可再现性。有时软件会发生变化(R 在一两个版本之前修复了一个著名的错误,因此在同一台机器上“旧”R 版本和当前版本之间的结果会有所不同
问题三 控制台对种子有很长的记忆吗?某颗种子是否会持续到下一个随机函数?
答案是 :每次想要获得可重现的随机结果时,都必须设置种子。看例子:
set.seed(1)
rnorm(4)
set.seed(1)
rnorm(4)
问题四 set.seed(...)的作用是什么,它到底应该怎么用?
set.seed() 函数主要用于重新启用同一组随机变量,也许在这之后的某一天,我们需要再次使用相同的随机变量去评估某个特定任务。
set.seed
是一个基函数,它能够与其他函数,如:rnorm
, runif
, sample
一起生成相同的随机值。因此我们只需要在使用任何随机数生成函数之前声明它即可。
下面是一个没有 set.seed的例子
> set.seed(NULL)
> rnorm(5)
[1] 1.5982677 -2.2572974 2.3057461 0.5935456 0.1143519
> rnorm(5)
[1] 0.15135371 0.20266228 0.95084266 0.09319339 -1.11049182
> set.seed(NULL)
> runif(5)
[1] 0.05697712 0.31892399 0.92547023 0.88360393 0.90015169
> runif(5)
[1] 0.09374559 0.64406494 0.65817582 0.30179009 0.19760375
> set.seed(NULL)
> sample(5)
[1] 5 4 3 1 2
> sample(5)
[1] 2 1 5 4 3
下面是一个有set.seed的例子
> set.seed(123)
> rnorm(5)
[1] -0.56047565 -0.23017749 1.55870831 0.07050839 0.12928774
> set.seed(123)
> rnorm(5)
[1] -0.56047565 -0.23017749 1.55870831 0.07050839 0.12928774
> set.seed(123)
> runif(5)
[1] 0.2875775 0.7883051 0.4089769 0.8830174 0.9404673
> set.seed(123)
> runif(5)
[1] 0.2875775 0.7883051 0.4089769 0.8830174 0.9404673
> set.seed(123)
> sample(5)
[1] 3 2 5 4 1
> set.seed(123)
> sample(5)
[1] 3 2 5 4 1