R语言 我能得到.seed()吗?

fykwrbwg  于 2023-02-17  发布在  其他
关注(0)|答案(5)|浏览(174)

对于set.seed()语句,如果我没有显式地设置种子,我可以在运行一些代码之后获得它吗?
我重新运行了一些代码(交互式/在控制台上)包含随机化输入数据样本的函数(该函数是kohonen包的一部分).用它玩了一段时间后,看看输出的各种(这是一个“不稳定”的问题),我注意到一个结果相当有趣。我当然没有使用set.seed(),但是我想知道在运行代码后是否可以得到种子来重现结果?
?set.seed中我看到
.Random.seed保存均匀随机数生成器的种子集
但我不知道这有什么用。

y3bcpkx1

y3bcpkx11#

如果你没有保留种子,那么在你观察到随机抽取之后,没有通用的方法可以将随机数生成器“回滚”到之前的状态。接下来,你可能想做的是保存.Random.seed的值沿着你的计算结果,类似于这样。

x <- .Random.seed
result <- <your code goes here>
attr(result, "seed") <- x

然后,您可以按如下方式重置PRNG:result2应与result相同。

.Random.seed <- attr(result, "seed")
result2 <- <your code goes here>
6tr1vspr

6tr1vspr2#

Hong的回答是可靠的。对于快速和肮脏的解决方案,我只是重新执行整个脚本,直到我得到有趣的行为,我随机选择一个整数,打印出来,然后使用它作为种子。如果我的特定运行有有趣的行为,我注意到种子:

eff_seed <- sample(1:2^15, 1)
print(sprintf("Seed for session: %s", eff_seed))
set.seed(eff_seed)
pengsaosao

pengsaosao3#

为了补充mpettis给出的答案,如果您不想手动重新执行脚本--每次迭代都生成新的随机种子--您可以执行以下操作:

# generate vector of seeds
eff_seeds <- sample(1:2^15, runs)

# perform 'runs' number of executions of your code
for(i in 1:runs) {
    print(sprintf("Seed for this run: %s", eff_seeds[i]))
    set.seed(eff_seeds[i])

    # your code here
    # don't forget to save your outputs somehow
}

其中变量“runs”是一个正整数,指示要运行代码的次数。
通过这种方式,您可以快速生成大量输出,并为每个迭代提供单独的种子以实现可重复性。

bis0qfac

bis0qfac4#

> rnorm(5)
[1] -0.17220331 -0.31506128 -0.35264299  0.07259645 -0.15518961
> Seed<-.Random.seed
> rnorm(5)
[1] -0.64965000  0.04787513 -0.14967549  0.12026774 -0.10934254
> set.seed(1234)
> rnorm(5)
[1] -1.2070657  0.2774292  1.0844412 -2.3456977  0.4291247
> .Random.seed<-Seed
> rnorm(5)
[1] -0.64965000  0.04787513 -0.14967549  0.12026774 -0.10934254
zynd9foi

zynd9foi5#

下面是修复setSeed函数没有反getSeed函数的问题的尝试。大约十二小时前,我在Using R, how to get.seed()?上发布了一个类似的问题,该问题被关闭,因为它被归类为“重复”。
我“破解”了一个带有种子内存的解决方案,它需要一个全局变量.random.seed.memory

utils::globalVariables(c(".random.seed.memory"));

计时非常重要,因为我必须使用set.seed“生成种子

github.monte = "https://raw.githubusercontent.com/MonteShaffer/";
include.me = paste0(github.monte, "humanVerse/main/humanVerse/R/functions-str.R");  
source(include.me); # trimMe function

include.me = paste0(github.monte, "humanVerse/main/humanVerse/R/functions-random.R");  
source(include.me); # getSeed, setSeed, and so on.

函数setSeed的行为通常与set.seed类似,但传递给set.seed的任何超出整数(种类、正常种类、样本种类)的自定义参数都需要在args.set中列出,因为setSeed的省略号...用于将参数传递给initSeed(...)initSeed(...)是一个内部函数,使setSeedgetSeed能够工作。
我还编写了一个C标准的rand()函数,它传入min,max,n方法,这就是我如何生成一个“整数”以提供给setSeed并存储在内存中。我使用Sys.time()作为默认种子生成的最小值/最大值(min = -1*as.integer(Sys.time())max = as.integer(Sys.time()))。sample是个坏主意因为它必须在该范围内创建一个向量来计算单个值,但它是rand()的一个方法选项,它馈送initSeed。我发现默认的“高-低”比“地板”稍快。

用法

### VERBOSITY is HIGH AT THE MOMENT ###

print("random 5"); rnorm(5);

setSeed(NULL);  # this will automatically call initSeedMemory() if necessary
setSeed(.random.seed.memory$last); rnorm(5);
setSeed(getSeed()); rnorm(5);

print("random 5"); rnorm(5);

setSeed(getSeed()); rnorm(5);

默认情况下,它将种子值存储到全局列表中名为“last”的元素中...这使您能够根据正在运行的进程跟踪不同的内存种子。在下面的示例中,我专门访问“last”和“nsim”...存储在内存中的第二个种子...

### VERBOSITY is HIGH AT THE MOMENT ###

initSeedMemory( purge.memory = TRUE);
setSeed(NULL); 
setSeed(.random.seed.memory$last); rnorm(5);
setSeed(getSeed()); rnorm(5);
getSeed(); # accessor to .random.seed.memory
.random.seed.memory;

print("random 5"); rnorm(5);

setSeed(NULL, key="nsim"); rnorm(5);
setSeed(.random.seed.memory$nsim, key="nsim"); rnorm(5);
setSeed(getSeed("nsim"), key="nsim"); rnorm(5);
getSeed("nsim"); # accessor to .random.seed.memory
.random.seed.memory;

print("random 5"); rnorm(5);

setSeed(.random.seed.memory$last); rnorm(5);
setSeed(getSeed()); rnorm(5);
.random.seed.memory;

set.seed(.random.seed.memory$last); rnorm(5);
set.seed(.random.seed.memory$nsim); rnorm(5);

.random.seed.memory;

print("random 5"); rnorm(5);

当然,它可能有错误,我将感谢任何建议或错误发现。
--太平洋标准时间2021年2月19日凌晨5点左右--
当然,传递固定种子的能力也是可能的。

setSeed(NULL, "nsim"); rnorm(5);  # randomly generated seed under the hood, but stored
setSeed(123, "z5"); rnorm(5);     # you can still fix the seed manually yourself, still stored and accessible in the list
setSeed(getSeed("nsim"), "nsim"); rnorm(5);
setSeed(getSeed("z5"), "z5"); rnorm(5);

相关问题