很多时候,在启动程序之前,我在R中看到了set.seed
函数。我知道它基本上用于随机数生成。有没有具体需要设置这个?
答案 0 :(得分:242)
需要可能的重复结果,例如可能来自尝试调试程序,或者当然是尝试重做它的作用:
这两个结果我们将“永远不会”重现,因为我只是要求“随机”:
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被称为伪随机数生成器,因为它们实际上是完全算法:给定相同的种子,您将得到相同的序列。 是一个功能,而不是一个错误。
答案 1 :(得分:29)
每次想要获得可重现的随机结果时,都必须设置种子。
set.seed(1)
rnorm(4)
set.seed(1)
rnorm(4)
答案 2 :(得分:16)
添加一些额外的方面。 需要设置种子:在学术界,如果有人声称他的算法可以实现,比如说在一次模拟中有98.05%的性能,那么其他人需要能够重现它。
?set.seed
通过这个函数的帮助文件,这些是一些有趣的事实:
(1)set.seed()返回NULL,不可见
(2)"最初,没有种子;当需要时,从当前时间和进程ID创建一个新的。因此默认情况下,不同的会话将提供不同的模拟结果。但是,如果先前保存的工作空间已恢复,则可能会从之前的会话中恢复种子。",这就是为什么您希望在下次需要相同的序列时调用具有相同整数值的set.seed()的原因。随机序列。
答案 3 :(得分:6)
基本上set.seed()函数将有助于重用同一组随机变量,我们将来可能需要再次使用相同的随机变量再次评估特定任务
我们只需要在使用任何随机数生成函数之前声明它。
答案 4 :(得分:6)
当我们尝试优化涉及随机生成的数字的函数时(例如,在基于模拟的估计中),修复种子是必要的。松散地说,如果我们不修复种子,由于绘制不同的随机数而导致的变化可能会导致优化算法失败。
假设由于某种原因,您希望在给定样本的情况下通过模拟估计平均零正态分布的标准偏差(sd)。这可以通过围绕步骤
运行数值优化来实现以下功能执行此操作,一旦没有步骤1,一旦包含它:
# 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)
参数估计的结果分布为:
当我们修复种子时,数字搜索最终会更接近2的真实参数值。
答案 5 :(得分:0)
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
答案 6 :(得分:0)
只是进一步补充......如果你想要一致性,你需要在每次做一些随机的事情时设置种子。种子不会保持固定。
set.seed(0)
rnorm(3)
set.seed(0)
rnorm(3)
[1] 1.2629543 -0.3262334 1.3297993
[1] 1.2629543 -0.3262334 1.3297993
set.seed(0)
rnorm(3)
rnorm(3)
[1] 1.2629543 -0.3262334 1.3297993
[1] 1.2724293 0.4146414 -1.5399500