使用set.seed函数的原因
在启动程序之前,我已经多次看到R中的set.seed
函数。 我知道它基本上用于随机数生成。 有没有特别需要设置这个?
需要的是可重复性结果的可能性,例如可能来自尝试debugging程序,或者尝试重做它的function:
这两个结果我们将“永不”重现,因为我只是要求“随机”的东西:
R> sample(LETTERS, 5) [1] "K" "N" "R" "Z" "G" R> sample(LETTERS, 5) [1] "L" "P" "J" "E" "D"
然而,这两者是相同的, 因为我设定了种子 :
R> set.seed(42); sample(LETTERS, 5) [1] "X" "Z" "G" "T" "O" R> set.seed(42); sample(LETTERS, 5) [1] "X" "Z" "G" "T" "O" R>
所有这些都有大量的文献。 维基百科是一个好的开始。 实质上,这些RNG被称为伪随机数生成器,因为它们实际上是完全algorithm的 :给定相同的种子,就得到相同的序列。 这是一个function,而不是一个错误。
每次你想得到一个可重现的随机结果,你必须设置种子。
set.seed(1) rnorm(4) set.seed(1) rnorm(4)
只需添加一些添加方面。 需要设置种子:在学术界,如果一个人声称他的algorithm达到了,在一次模拟中说98.05%的性能,其他人需要能够重现它。
?set.seed
通过这个函数的帮助文件,这些是一些有趣的事实:
(1)set.seed()返回NULL,不可见
(2)“最初没有种子,从当前时间和过程ID创build一个新的时间,因此不同的会话会默认给出不同的模拟结果,但是种子可以从如果以前保存的工作空间被恢复,那么就是前一个会话“。这就是为什么你要在下一次你想要一个随机序列的同一个序列时,用相同的整数值调用set.seed()。
当我们尝试优化一个涉及随机生成数字的函数时(例如,在基于模拟的估计中),固定种子是至关重要的。 松散地说,如果我们不修复种子,由于绘制不同的随机数而导致的变化可能会导致优化algorithm失败。
假设出于某种原因,您希望通过模拟来估计均值为零的正态分布的标准偏差(sd)。 这可以通过围绕步骤进行数值优化来实现
- (设置种子)
- 给定sd的值,生成正态分布的数据
- 评估数据给出模拟分布的可能性
一旦没有第一步,下面的function就可以做到这一点,一旦包含它:
# without fixing the seed simllh <- function(sd,y,Ns){ simdist <- density(rnorm(Ns,mean=0,sd=sd)) llh <- sapply(y,function(x){simdist$y[which.min((x-simdist$x)^2)]}) return(-sum(log(llh))) } # same function with fixed seed simllh.fix.seed <- function(sd,y,Ns){ set.seed(48) simdist <- density(rnorm(Ns,mean=0,sd=sd)) llh <- sapply(y,function(x){simdist$y[which.min((x-simdist$x)^2)]}) return(-sum(log(llh))) }
我们可以通过一个简短的蒙特卡罗研究来检查两个函数在发现真实参数值时的相对性能:
N <- 20; sd <- 2 # features of simulated data est1 <- rep(NA,1000); est2 <- rep(NA,1000) # initialize the estimate stores for(i in 1:1000){ as.numeric(Sys.time())-> t; set.seed((t - floor(t)) * 1e8 -> seed) # set the seed to random seed y <- rnorm(N,sd=sd) # generate the data est1[i] <- optim(1,simllh,y=y,Ns=1000,lower=0.01)$par est2[i] <- optim(1,simllh.fix.seed,y=y,Ns=1000,lower=0.01)$par } hist(est1) hist(est2)
得出的参数估计分布是:
- 不固定种子的参数估计直方图
- 固定种子的参数估计直方图
当我们修复种子时,数字search结果往往更接近真实的参数值2。
基本上set.seed()函数将有助于重复使用同一组随机variables,我们将来可能需要再次使用相同的随机variables来再次评估特定的任务
我们只需要在使用任何随机数生成函数之前声明它。