R:set.seed()的奇怪行为

9

当我在R中执行set.seed(0)和set.seed(1)时,会出现奇怪的情况。

set.seed(0)
sample(1:100,size=10,replace=TRUE)
#### [1] 90 27 38 58 91 21 90 95 67 63


set.seed(1)
sample(1:100,size=10,replace=TRUE)
#### [1] 27 38 58 91 21 90 95 67 63  7

当将种子从0更改为1时,我得到了完全相同的序列,但是向右移动了一个单元格!

请注意,如果我使用set.seed(2),我确实获得了一个看起来完全不同的(随机?)向量。

set.seed(2)
sample(1:100,size=10,replace=TRUE)
#### [1] 19 71 58 17 95 95 13 84 47 55

有人知道这里发生了什么吗?


(注:不保留空格)

另外,seed需要一个大于整数is.integer(0) [1] FALSE - rawr
4
你被误导了:0 是一个双精度数,因此 is.integer(0) 返回 FALSE,但是 is.integer(0L) 返回 TRUE。然而,set.seed 会将浮点数的输入强制转换为整数,所以这不是问题所在。 - Carl Witthoft
有趣..谢谢卡尔 - rawr
2个回答

15

这适用于Mersenne-Twister随机数生成器的R实现。

set.seed()将提供的种子混合并扰乱(在C函数RNG_Init中):

for(j = 0; j < 50; j++)
  seed = (69069 * seed + 1);

那个被打乱的数字(seed)被再次打乱625次以填充Mersenne-Twister的初始状态:

for(j = 0; j < RNG_Table[kind].n_seed; j++) {
  seed = (69069 * seed + 1);
  RNG_Table[kind].i_seed[j] = seed;
}
我们可以使用.Random.seed来检查随机数生成器的初始状态:
set.seed(0)
x <- .Random.seed

set.seed(1)
y <- .Random.seed

table(x %in% y)

从表格中可以看出有很多重叠之处。与seed = 3进行比较:

set.seed(3)
z <- .Random.seed

table(z %in% x)
table(z %in% y)
回到0和1的情况,如果我们仅考虑状态本身(忽略向量的前两个元素,因为它们与我们所看的内容不相关),你可以看到该状态被偏移了一个位置:
x[3:10]
# 1280795612 -169270483 -442010614 -603558397 -222347416 1489374793  865871222
# 1734802815

y[3:10] 
# -169270483 -442010614 -603558397 -222347416 1489374793  865871222 1734802815
# 98005428

由于sample()函数选取的值是基于这些数字,因此会导致奇怪的行为。


谢谢!这确实为这个问题增加了一些清晰度。我将不得不更加仔细地查看这段代码,以了解为什么0和1会出现如此相似的情况。 - bigO6377
欢迎。请记住,最大整数为2^32-1,数字将溢出为负数。 - Christopher Louden
2
请注意,如果您 set.seed(69070),则会额外偏移1(考虑到上面的第一个 for 循环,这是有意义的)。我们可以扩展循环以找到下一个偏移量 1 等。0,1 组合只是因为它们相邻而有趣,如果没有看到循环,任何人都不太可能碰巧比较 1 和 69070。 - Greg Snow
@bigO6377 看起来 MT 的作者已经意识到了这个问题并进行了修复(“改进初始化” - 不知道确切的时间),所以你应该询问 R 版本的开发人员是否可以更新他们的版本。 - loreb
1
根据http://wellington.pm.org/archive/200704/randomness/mt19937.pl的说法,他们至少在7年前就已经修复了这个问题... - loreb

1

正如您从其他答案中所看到的那样,种子01会导致几乎相似的初始状态。此外,Mersenne Twister PRNG有一个严重限制 - "几乎相似的初始状态需要很长时间才能发散"

因此,建议使用替代方案,例如WELL PRNG(可以在randtoolbox软件包中找到)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接