.Random.seed 中的前两个值对于不同的 set.seed() 总是相同的
First two values in .Random.seed are always the same with different set.seed()s
前言
我查看了描述 set.seed()
和 .Random.seed
的使用和功能的其他问题 (1, 2, 3),但找不到记录的这个特定问题,所以这里是一个问题:
初步观察
当我检查由 set.seed(1)
和 set.seed(2)
生成的 .Random.seed
时,我发现前两个元素始终相同(10403
& 624
) 而其余的似乎不是。请参阅下面的示例。
我的问题
- 这是预期的吗?
- 为什么会这样?
- 这会不会对我的任何随机模拟产生任何不良后果?
可以根据它做吗?
可重现的例子
f <- function(s1, s2){
set.seed(s1)
r1 <- .Random.seed
set.seed(s2)
r2 <- .Random.seed
print(r1[1:3])
print(r2[1:3])
plot(r1, r2)
}
f(1, 2)
#> [1] 10403 624 -169270483
#> [1] 10403 624 -1619336578
由 reprex package (v2.0.1)
于 2022-01-04 创建
请注意,每个 .Random.seed
的前两个元素相同,但其余部分不同。您可以在散点图中看到它只是预期的随机云。
将@r2evans 和@Dave2e 的有用评论扩展为答案。
1) .Random.seed[1]
来自?.Random.seed
,它说:
".Random.seed
is an integer vector whose first element codes the
kind of RNG and normal generator. The lowest two decimal digits are in
0:(k-1)
where k
is the number of available RNGs. The hundreds
represent the type of normal generator (starting at 0), and the ten
thousands represent the type of discrete uniform sampler."
因此,除非更改生成器方法 (RNGkind
),否则第一个值不会更改。
下面是每个可用 RNGkind
的一个小演示:
library(tidyverse)
# available RNGkind options
kinds <- c(
"Wichmann-Hill",
"Marsaglia-Multicarry",
"Super-Duper",
"Mersenne-Twister",
"Knuth-TAOCP-2002",
"Knuth-TAOCP",
"L'Ecuyer-CMRG"
)
# test over multiple seeds
seeds <- c(1:3)
f <- function(kind, seed) {
# set seed with simulation parameters
set.seed(seed = seed, kind = kind)
# check value of first element in .Random.seed
return(.Random.seed[1])
}
# run on simulated conditions and compare value over different seeds
expand_grid(kind = kinds, seed = seeds) %>%
pmap(f) %>%
unlist() %>%
matrix(
ncol = length(seeds),
byrow = T,
dimnames = list(kinds, paste0("seed_", seeds))
)
#> seed_1 seed_2 seed_3
#> Wichmann-Hill 10400 10400 10400
#> Marsaglia-Multicarry 10401 10401 10401
#> Super-Duper 10402 10402 10402
#> Mersenne-Twister 10403 10403 10403
#> Knuth-TAOCP-2002 10406 10406 10406
#> Knuth-TAOCP 10404 10404 10404
#> L'Ecuyer-CMRG 10407 10407 10407
由 reprex package (v2.0.1)
创建于 2022-01-06
2) .Random.seed[2]
至少对于默认的"Mersenne-Twister"
方法来说,.Random.seed[2]
是一个索引,表示当前在随机集中的位置。来自文档:
The ‘seed’ is a 624-dimensional set of 32-bit integers plus a current
position in that set.
这会在执行使用种子的随机过程时更新。然而,对于其他方法,文档没有提到类似的内容,并且似乎没有以相同的方式出现明显的趋势。
请参阅下面的 set.seed()
之后迭代随机过程中 .Random.seed[2]
变化的示例。
library(tidyverse)
# available RNGkind options
kinds <- c(
"Wichmann-Hill",
"Marsaglia-Multicarry",
"Super-Duper",
"Mersenne-Twister",
"Knuth-TAOCP-2002",
"Knuth-TAOCP",
"L'Ecuyer-CMRG"
)
# create function to run random process and report .Random.seed[2]
t <- function(n = 1) {
p <- .Random.seed[2]
runif(n)
p
}
# create function to set seed and iterate a random process
f2 <- function(kind, seed = 1, n = 5) {
set.seed(seed = seed,
kind = kind)
replicate(n, t())
}
# set simulation parameters
trials <- 5
seeds <- 1:2
x <- expand_grid(kind = kinds, seed = seeds, n = trials)
# evaluate and report
x %>%
pmap_dfc(f2) %>%
mutate(n = paste0("trial_", 1:trials)) %>%
pivot_longer(-n, names_to = "row") %>%
pivot_wider(names_from = "n") %>%
select(-row) %>%
bind_cols(x[,1:2], .)
#> # A tibble: 14 x 7
#> kind seed trial_1 trial_2 trial_3 trial_4 trial_5
#> <chr> <int> <int> <int> <int> <int> <int>
#> 1 Wichmann-Hill 1 23415 8457 23504 2.37e4 2.28e4
#> 2 Wichmann-Hill 2 21758 27800 1567 2.58e4 2.37e4
#> 3 Marsaglia-Multicarry 1 1280795612 945095059 14912928 1.34e9 2.23e8
#> 4 Marsaglia-Multicarry 2 -897583247 -1953114152 2042794797 1.39e9 3.71e8
#> 5 Super-Duper 1 1280795612 -1162609806 -1499951595 5.51e8 6.35e8
#> 6 Super-Duper 2 -897583247 224551822 -624310 -2.23e8 8.91e8
#> 7 Mersenne-Twister 1 624 1 2 3 4
#> 8 Mersenne-Twister 2 624 1 2 3 4
#> 9 Knuth-TAOCP-2002 1 166645457 504833754 504833754 5.05e8 5.05e8
#> 10 Knuth-TAOCP-2002 2 967462395 252695483 252695483 2.53e8 2.53e8
#> 11 Knuth-TAOCP 1 1050415712 999978161 999978161 1.00e9 1.00e9
#> 12 Knuth-TAOCP 2 204052929 776729829 776729829 7.77e8 7.77e8
#> 13 L'Ecuyer-CMRG 1 1280795612 -169270483 -442010614 4.71e8 1.80e9
#> 14 L'Ecuyer-CMRG 2 -897583247 -1619336578 -714750745 2.10e9 -9.89e8
由 reprex package (v2.0.1)
创建于 2022-01-06
在这里你可以看到,从 Mersenne-Twister
方法,.Random.seed[2]
从它的最大值 624
递增回到 1
并且 增加了随机抽取的大小 ,这与 set.seed(1)
和 set.seed(2)
相同。然而,在其他方法中没有看到相同的趋势。为了说明最后一点,请参阅 runif(1)
将 .Random.seed[2]
递增 1
而 runif(2)
将其递增 2
:
# create function to run random process and report .Random.seed[2]
t <- function(n = 1) {
p <- .Random.seed[2]
runif(n)
p
}
set.seed(1, kind = "Mersenne-Twister")
replicate(9, t(1))
#> [1] 624 1 2 3 4 5 6 7 8
set.seed(1, kind = "Mersenne-Twister")
replicate(5, t(2))
#> [1] 624 2 4 6 8
由 reprex package (v2.0.1)
创建于 2022-01-06
3) 顺序随机数
因为 .Random.seed
的索引或状态(显然对于所有 RNG 方法)根据 'random draw' 的大小(从 .Random.seed
生成的随机值的数量)前进,可以从相同种子以不同大小的增量生成相同系列的随机数。此外,只要你在设置相同种子后运行在序列中的相同点进行相同的随机过程,似乎你会得到相同的结果。观察以下示例:
# draw 3 at once
set.seed(1, kind = "Mersenne-Twister")
sample(100, 3, T)
#> [1] 68 39 1
# repeat single draw 3 times
set.seed(1, kind = "Mersenne-Twister")
sample(100, 1)
#> [1] 68
sample(100, 1)
#> [1] 39
sample(100, 1)
#> [1] 1
# draw 1, do something else, draw 1 again
set.seed(1, kind = "Mersenne-Twister")
sample(100, 1)
#> [1] 68
runif(1)
#> [1] 0.5728534
sample(100, 1)
#> [1] 1
由 reprex package (v2.0.1)
创建于 2022-01-06
4) 相关随机数
正如我们在上面看到的,设置相同种子后在同一点的两个随机过程 运行 预计会给出相同的结果。但是,即使您对结果的相似程度进行了限制(例如,通过更改 rnorm()
的 mean
或者甚至通过提供不同的函数),结果似乎仍然在各自的范围内完全相关.
# same function with different constraints
set.seed(1, kind = "Mersenne-Twister")
a <- runif(50, 0, 1)
set.seed(1, kind = "Mersenne-Twister")
b <- runif(50, 10, 100)
plot(a, b)
# different functions
set.seed(1, kind = "Mersenne-Twister")
d <- rnorm(50)
set.seed(1, kind = "Mersenne-Twister")
e <- rlnorm(50)
plot(d, e)
由 reprex package (v2.0.1)
创建于 2022-01-06
前言
我查看了描述 set.seed()
和 .Random.seed
的使用和功能的其他问题 (1, 2, 3),但找不到记录的这个特定问题,所以这里是一个问题:
初步观察
当我检查由 set.seed(1)
和 set.seed(2)
生成的 .Random.seed
时,我发现前两个元素始终相同(10403
& 624
) 而其余的似乎不是。请参阅下面的示例。
我的问题
- 这是预期的吗?
- 为什么会这样?
- 这会不会对我的任何随机模拟产生任何不良后果? 可以根据它做吗?
可重现的例子
f <- function(s1, s2){
set.seed(s1)
r1 <- .Random.seed
set.seed(s2)
r2 <- .Random.seed
print(r1[1:3])
print(r2[1:3])
plot(r1, r2)
}
f(1, 2)
#> [1] 10403 624 -169270483
#> [1] 10403 624 -1619336578
由 reprex package (v2.0.1)
于 2022-01-04 创建请注意,每个 .Random.seed
的前两个元素相同,但其余部分不同。您可以在散点图中看到它只是预期的随机云。
将@r2evans 和@Dave2e 的有用评论扩展为答案。
1) .Random.seed[1]
来自?.Random.seed
,它说:
"
.Random.seed
is an integer vector whose first element codes the kind of RNG and normal generator. The lowest two decimal digits are in0:(k-1)
wherek
is the number of available RNGs. The hundreds represent the type of normal generator (starting at 0), and the ten thousands represent the type of discrete uniform sampler."
因此,除非更改生成器方法 (RNGkind
),否则第一个值不会更改。
下面是每个可用 RNGkind
的一个小演示:
library(tidyverse)
# available RNGkind options
kinds <- c(
"Wichmann-Hill",
"Marsaglia-Multicarry",
"Super-Duper",
"Mersenne-Twister",
"Knuth-TAOCP-2002",
"Knuth-TAOCP",
"L'Ecuyer-CMRG"
)
# test over multiple seeds
seeds <- c(1:3)
f <- function(kind, seed) {
# set seed with simulation parameters
set.seed(seed = seed, kind = kind)
# check value of first element in .Random.seed
return(.Random.seed[1])
}
# run on simulated conditions and compare value over different seeds
expand_grid(kind = kinds, seed = seeds) %>%
pmap(f) %>%
unlist() %>%
matrix(
ncol = length(seeds),
byrow = T,
dimnames = list(kinds, paste0("seed_", seeds))
)
#> seed_1 seed_2 seed_3
#> Wichmann-Hill 10400 10400 10400
#> Marsaglia-Multicarry 10401 10401 10401
#> Super-Duper 10402 10402 10402
#> Mersenne-Twister 10403 10403 10403
#> Knuth-TAOCP-2002 10406 10406 10406
#> Knuth-TAOCP 10404 10404 10404
#> L'Ecuyer-CMRG 10407 10407 10407
由 reprex package (v2.0.1)
创建于 2022-01-062) .Random.seed[2]
至少对于默认的"Mersenne-Twister"
方法来说,.Random.seed[2]
是一个索引,表示当前在随机集中的位置。来自文档:
The ‘seed’ is a 624-dimensional set of 32-bit integers plus a current position in that set.
这会在执行使用种子的随机过程时更新。然而,对于其他方法,文档没有提到类似的内容,并且似乎没有以相同的方式出现明显的趋势。
请参阅下面的 set.seed()
之后迭代随机过程中 .Random.seed[2]
变化的示例。
library(tidyverse)
# available RNGkind options
kinds <- c(
"Wichmann-Hill",
"Marsaglia-Multicarry",
"Super-Duper",
"Mersenne-Twister",
"Knuth-TAOCP-2002",
"Knuth-TAOCP",
"L'Ecuyer-CMRG"
)
# create function to run random process and report .Random.seed[2]
t <- function(n = 1) {
p <- .Random.seed[2]
runif(n)
p
}
# create function to set seed and iterate a random process
f2 <- function(kind, seed = 1, n = 5) {
set.seed(seed = seed,
kind = kind)
replicate(n, t())
}
# set simulation parameters
trials <- 5
seeds <- 1:2
x <- expand_grid(kind = kinds, seed = seeds, n = trials)
# evaluate and report
x %>%
pmap_dfc(f2) %>%
mutate(n = paste0("trial_", 1:trials)) %>%
pivot_longer(-n, names_to = "row") %>%
pivot_wider(names_from = "n") %>%
select(-row) %>%
bind_cols(x[,1:2], .)
#> # A tibble: 14 x 7
#> kind seed trial_1 trial_2 trial_3 trial_4 trial_5
#> <chr> <int> <int> <int> <int> <int> <int>
#> 1 Wichmann-Hill 1 23415 8457 23504 2.37e4 2.28e4
#> 2 Wichmann-Hill 2 21758 27800 1567 2.58e4 2.37e4
#> 3 Marsaglia-Multicarry 1 1280795612 945095059 14912928 1.34e9 2.23e8
#> 4 Marsaglia-Multicarry 2 -897583247 -1953114152 2042794797 1.39e9 3.71e8
#> 5 Super-Duper 1 1280795612 -1162609806 -1499951595 5.51e8 6.35e8
#> 6 Super-Duper 2 -897583247 224551822 -624310 -2.23e8 8.91e8
#> 7 Mersenne-Twister 1 624 1 2 3 4
#> 8 Mersenne-Twister 2 624 1 2 3 4
#> 9 Knuth-TAOCP-2002 1 166645457 504833754 504833754 5.05e8 5.05e8
#> 10 Knuth-TAOCP-2002 2 967462395 252695483 252695483 2.53e8 2.53e8
#> 11 Knuth-TAOCP 1 1050415712 999978161 999978161 1.00e9 1.00e9
#> 12 Knuth-TAOCP 2 204052929 776729829 776729829 7.77e8 7.77e8
#> 13 L'Ecuyer-CMRG 1 1280795612 -169270483 -442010614 4.71e8 1.80e9
#> 14 L'Ecuyer-CMRG 2 -897583247 -1619336578 -714750745 2.10e9 -9.89e8
由 reprex package (v2.0.1)
创建于 2022-01-06在这里你可以看到,从 Mersenne-Twister
方法,.Random.seed[2]
从它的最大值 624
递增回到 1
并且 增加了随机抽取的大小 ,这与 set.seed(1)
和 set.seed(2)
相同。然而,在其他方法中没有看到相同的趋势。为了说明最后一点,请参阅 runif(1)
将 .Random.seed[2]
递增 1
而 runif(2)
将其递增 2
:
# create function to run random process and report .Random.seed[2]
t <- function(n = 1) {
p <- .Random.seed[2]
runif(n)
p
}
set.seed(1, kind = "Mersenne-Twister")
replicate(9, t(1))
#> [1] 624 1 2 3 4 5 6 7 8
set.seed(1, kind = "Mersenne-Twister")
replicate(5, t(2))
#> [1] 624 2 4 6 8
由 reprex package (v2.0.1)
创建于 2022-01-063) 顺序随机数
因为 .Random.seed
的索引或状态(显然对于所有 RNG 方法)根据 'random draw' 的大小(从 .Random.seed
生成的随机值的数量)前进,可以从相同种子以不同大小的增量生成相同系列的随机数。此外,只要你在设置相同种子后运行在序列中的相同点进行相同的随机过程,似乎你会得到相同的结果。观察以下示例:
# draw 3 at once
set.seed(1, kind = "Mersenne-Twister")
sample(100, 3, T)
#> [1] 68 39 1
# repeat single draw 3 times
set.seed(1, kind = "Mersenne-Twister")
sample(100, 1)
#> [1] 68
sample(100, 1)
#> [1] 39
sample(100, 1)
#> [1] 1
# draw 1, do something else, draw 1 again
set.seed(1, kind = "Mersenne-Twister")
sample(100, 1)
#> [1] 68
runif(1)
#> [1] 0.5728534
sample(100, 1)
#> [1] 1
由 reprex package (v2.0.1)
创建于 2022-01-064) 相关随机数
正如我们在上面看到的,设置相同种子后在同一点的两个随机过程 运行 预计会给出相同的结果。但是,即使您对结果的相似程度进行了限制(例如,通过更改 rnorm()
的 mean
或者甚至通过提供不同的函数),结果似乎仍然在各自的范围内完全相关.
# same function with different constraints
set.seed(1, kind = "Mersenne-Twister")
a <- runif(50, 0, 1)
set.seed(1, kind = "Mersenne-Twister")
b <- runif(50, 10, 100)
plot(a, b)
# different functions
set.seed(1, kind = "Mersenne-Twister")
d <- rnorm(50)
set.seed(1, kind = "Mersenne-Twister")
e <- rlnorm(50)
plot(d, e)
由 reprex package (v2.0.1)
创建于 2022-01-06