【4.2】R--关于set.seed()

计算机并不能产生真正的随机数,如果你不设种子,计算机会用系统时钟来作为种子,如果你要模拟什么的话,每次的随机数都是不一样的,这样就不方便你研究,如果你事先设置了种子,这样每次的随机数都是一样的,便于重现你的研究,也便于其他人检验你的分析结果。

如果说函数中出现set.seed(3000),那就是说程序运行3000次,都是从同一个种子产生的随机数,还是从不同的种子产生的?

另外,这个3000,指的是3000“个”随机数,还是3000“批”(一批里面可能有若干个)随机数呢?

如果我每循环一次,让set.seed(N)中的N增加一个常数,那会有什么作用?

set.seed(3000),不是运行3000次,而是把种子设置为3000。

计算机的程序,都是通过确定的算法,根据确定的输入,算出确定的输出。想要得到真正的随机,需要通过外接物理随机数发生器,通过把随机的物理过程转变为随机值,才能实现。因此我们平常使用的计算机的随机数,其实都只是通过算法模拟得到,也就是伪随机。一般采用的办法是线性同余(参见http://en.wikipedia.org/wiki/Linear_congruential_generator)。

X[n+1] = (a * X[n] + c) mod m

为简单起见,我取简单的参数(a = 1, c = 3, m = 5),得到一个简单的算式:

X[n+1] = (X[n] + 3) mod 5

这时,把X[0]视为种子,于是:

若种子为0,得到数列:0, 3, 1, 4, 2, 0, …
若种子为1,得到数列:1, 4, 2, 0, 3, 1, …
若种子为2,得到数列:2, 0, 3, 1, 4, 2, …
若种子为3,得到数列:3, 1, 4, 2, 0, 3, …
若种子为4,得到数列:4, 2, 0, 3, 1, 4, …

对于每个种子,所得到的数列看起来都是随机的(每个数值出现的频率都是相同的)。而一旦种子给定,每次调用随机数函数,函数都会根据上次得到的数列的某个值,计算出数列的下一个值并返回回来。而对于随机浮点数,一般是用随机产生的整数除以最大整数得到。

所以,随机数的种子一般只需要在调用随机函数之前设置一次,不建议设置多次。

另外,我一直没有搞明白一件事:设置多次种子,在算法上会不会对最终生成的随机数的分布造成影响?不知道有人了解么?http://cos.name/cn/topic/15925

可以重复得到同一组伪随机数很重要。比如,你的程序有一个很隐蔽的错误,导致你用某些初始值会得到错误的结果,如果你没有设定种子,运行完程序一看结果错了,这时你肯定想再用刚才的数据做一次debug,但永远不可能得到它了。再比如,写论文的时候,你的结果要给别人看,那么一个可重复使用的数据就很重要,你要让别人运行你的code也能得到你的结果就必须要设定种子,等等。

今天查了一下R语言中set.seed(),该命令的作用是设定生成随机数的种子,种子是为了让结果具有重复性。如果不设定种子,生成的随机数无法重现。

> x<-rnorm(10) #随机生成10个随机数 > x
[1] 0.3897943 -1.2080762 -0.3636760 -1.6266727 -0.2564784 1.1017795 0.7557815
[8] -0.2382336 0.9874447 0.7413901

> x<-rnorm(10) #再次随机生成10个随机数 > x
[1] 0.08934727 -0.95494386 -0.19515038 0.92552126 0.48297852 -0.59631064 -2.18528684
[8] -0.67486594 -2.11906119 -1.26519802

>set.seed(5) #设定种子
> x<-rnorm(10) # 在设定种子的前提下生成10个随机数 > x
[1] -0.84085548 1.38435934 -1.25549186 0.07014277 1.71144087 -0.60290798 -0.47216639
[8] -0.63537131 -0.28577363 0.13810822

>set.seed(5) # 设定种子
> y<-rnorm(10) > y
[1] -0.84085548 1.38435934 -1.25549186 0.07014277 1.71144087 -0.60290798 -0.47216639
[8] -0.63537131 -0.28577363 0.13810822
> x == y
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE

从上面的例子可以发现,前两次生成的10个随机数都不一样。后两次在设定了相同的种子前提下,生成的随机数是相同的。

记得每次生成的对象前面都加set.seed,这样才能提醒用的是可重复的样本; 用途是给定伪随机数的seed,在同样的seed下,R生成的伪随机数序列是相同的。这样的话,别人的模拟就是可以重复的

参考资料:

http://www.douban.com/note/274702270/

http://blog.sina.com.cn/s/blog_729ca6a60102uxl9.html

http://blog.sina.com.cn/s/blog_71f3890901017y1i.html

http://cos.name/cn/topic/106976

药企,独角兽,苏州。团队长期招人,感兴趣的都可以发邮件聊聊:tiehan@sina.cn
个人公众号,比较懒,很少更新,可以在上面提问题,如果回复不及时,可发邮件给我: tiehan@sina.cn