使用set.seed函数的原因


Answers:


264

需要可能的结果是可重复的结果,例如,可能来自尝试调试程序,或者当然来自尝试重做其功能:

这两个结果我们将“永不”重现,因为我只是想问一些“随机”问题:

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称为伪随机数生成器,因为它们实际上是完全算法的:给定相同的种子,您将获得相同的序列。那是功能,而不是错误。


5
感谢Dirk,举了这么漂亮的例子。.我已经用99%的权限清除了它,但仍然有疑问。1.在您的答案中,您使用了set.seed和42作为参数。选择此值是否有任何相关原因?
Vignesh 2012年

43
对于质量一般的RNG,其价值并不重要。“ 42”是指一本著名的书;其他人使用生日或“ 123”或“ 1”。
德克·埃德比布特尔

7
char2seedTeachingDemos软件包中的函数允许您set.seed基于字符串设置种子(或选择要传递的种子)。例如,您可以让学生使用他们的名字作为种子,然后每个学生都有一个唯一的数据集,但教师也可以创建相同的数据集进行评分。
格雷格·斯诺

8
可以使用不同的种子重新运行相同的代码,直到获得“最佳”结果为止(我已经举例说明了)。为了防止这样做的指控,最好选择具有明显含义的种子,该种子要么总是相同的种子,要么是日期,或者我char2seed在项目中使用的是主要调查员的姓氏。
格雷格·斯诺

5
@DirkEddelbuettel种子值可能由于非计算原因而影响,我的一个朋友在发布他的基于模拟的结果时遇到了问题,因为代码始于set.seed(666)并且评论者不喜欢代码中的Devils种子...
Tim

33

每次要获得可重现的随机结果时,都必须设置种子。

set.seed(1)
rnorm(4)
set.seed(1)
rnorm(4)

17

仅添加一些其他方面。需要设置种子:在学术界,如果有人声称自己的算法可以在一种模拟中达到98.05%的性能,那么其​​他人就需要能够重现它。

?set.seed

浏览此功能的帮助文件,这些是一些有趣的事实:

(1)set.seed()返回NULL,不可见

(2)“最初没有种子;需要时从当前时间和进程ID创建一个新种子。因此,默认情况下,不同的会话将提供不同的模拟结果。但是,可以从如果恢复了先前保存的工作空间,则返回上一个会话。”,这就是为什么您下次要使用相同的随机序列序列时,想要使用相同的整数值调用set.seed()的原因。


7

当我们尝试优化涉及随机生成数字的函数时(例如,在基于仿真的估计中),修复种子至关重要。松散地说,如果我们不修复种子,则由于绘制不同的随机数而导致的变化可能会导致优化算法失败。

假设由于某种原因,您想给定一个样本,通过仿真来估计均值零正态分布的标准偏差(sd)。这可以通过围绕步骤进行数值优化来实现

  1. (设置种子)
  2. 给定sd的值,生成正态分布的数据
  3. 给定模拟分布,评估数据的可能性

如果没有步骤1,则以下功能会执行此操作,一旦包含步骤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。


6

基本上set.seed()函数将有助于重用同一组随机变量,我们将来可能需要使用相同的随机变量再次评估特定任务

我们只需要在使用任何随机数生成函数之前声明它即可。


详细说明答案
Spry Techies 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.