多次使用 set.seed 的奇怪行为

Weird behavior of using set.seed multiple times

我在用 R 做作业时得到了一个奇怪的结果,谁能给我解释一下这是怎么回事?

指令告诉我设置种子 1 以保持一致性。

起初,我设置了两次seed(1)

set.seed(1)
x <- rnorm(100, mean = 0, sd = 1)
set.seed(1)
epsilon <- rnorm(100, mean = 0, sd = 0.25)
y <- 0.5 * x + epsilon -1
plot(x,y,main = "Scatter plot between X and Y", xlab = "X", ylab = "Y")

我得到这样的散点图: The plot with two set seed

我只使用一组种子后代码是:

set.seed(1)
x <- rnorm(100, mean = 0, sd = 1)
epsilon <- rnorm(100, mean = 0, sd = 0.25)
y <- 0.5 * x + epsilon -1
plot(x,y,main = "Scatter plot between X and Y", xlab = "X", ylab = "Y")

剧情变得合理了: The plot with one set seed

谁能通过添加额外的 "set.seed(1)" 向我解释为什么两个结果不同?

Set.seed()决定了之后生成的随机数。通常它用于创建可重现的示例,因此如果我们 运行 相同的代码,我们会得到相同的结果。举例说明:

set.seed(1234)
runif(3)
[1] 0.1137034 0.6222994 0.6092747

set.seed(1234)
runif(3)
[1] 0.1137034 0.6222994 0.6092747

set.seed(12345)
runif(3)
[1] 0.7209039 0.8757732 0.7609823

因此,如您所见,当您使用相同的数字两次 set.seed(x) 时,您将从那时起生成相同的随机数。 (对于具有相同分布的变量。对于其他变量,请参见下面的详细说明)。 所以你在第一个图中得到一条直线的原因是因为

y <- 0.5 * x + epsilon -1

实际上变成了

y <- 0.5 * x + x -1

因为您两次使用相同的随机数序列。减少到

y <- 1.5 * x -1

这是一个简单的线性方程。

所以一般来说,您应该只在脚本开头执行一次 set.seed(x)


对评论的阐述:"But I generated the Epsilon with different sd, why would that still be the same x, although the plot seems to agree with the explanation?"

这实际上是一个非常有趣的问题。分布为~N(mean,sd)的随机数通常生成如下:

  1. 生成随机统一编号。
  2. 对这些数字进行转换,通常是the Box-Muller transformation.,我们称这些数字为X。
  3. 这些数字通过应用变换再次变换 sd * X + mean

当你运行这两次使用相同的种子但均值和标准差不同时,前两步将产生完全相同的结果,因为生成的随机数是相同的,均值和标准差还没有使用。只有在第三步 mean 和 sd 才会发挥作用。我们可以很容易地验证这一点:

set.seed(1)
rnorm(4, mean = 0, sd = 1)
[1] -0.6264538  0.1836433 -0.8356286  1.5952808
set.seed(1)
rnorm(4, mean = 0, sd = 0.25)
[1] -0.15661345  0.04591083 -0.20890715  0.39882020

果然,第二次生成的随机数正好是第一次生成的随机数的0.25倍

所以在我上面的解释中,epsilon 实际上是 0.25*x,而你得到的函数是 y <- 0.75 * x - 1,它仍然只是一个线性函数。

为什么结果不同 - 当设置一次 set.seed 和设置两次 运行 -

set.seed(123)
runif(3)
[1] 0.2875775 0.7883051 0.4089769
runif(3)
[1] 0.8830174 0.9404673 0.0455565

而当再次设置 set.seed 时,结果为 -

set.seed(123)
runif(6)
[1] 0.2875775 0.7883051 0.4089769 0.8830174 0.9404673 0.0455565

因此,当只设置一次种子时,程序会使用下一组可用数来生成下一组随机数