我正在使用R,我在复制以下输出时遇到一些问题:
mod1 <- glm(TVAR ~ .,data = df, family = "binomial")
y <- predict.glm(mod1)
由于它依赖于set.seed()
。
我有一些关于这个的问题。
我知道,如果我初步使用
set.seed(123)
(或任何其他种子),随机世代将始终在同一水平开始,因此我将实现可复制的结果。尽管如此,假设我想逆向工程种子,从一个好的结果开始,然后检索种子,以便下一次复制那个好的结果。换句话说,让我们假设我运行相同的代码n
多次,而没有初步设置一个种子,目的是找到最适合我的结果,然后检索使用的种子。这可能吗?这听起来像是一种欺骗,但它确实不是,因为我只是试图把代码的结果固定在它的种子依赖上,假设代码背后的整体思想是被感知的,只需要实现可复制的状态。只是为了我的理解:一个新的种子只在我删除环境中的所有变量时使用?事实上,如果我多次运行相同的代码,但没有清理环境,结果是相同的,因此使用了相同的种子。我希望你能把这件事说清楚。
最后:是否有一种方法来理解当一个函数是依赖于
set.seed()
?例如,在CRAN手册中,我找不到这方面的任何指示,这似乎是一个关键问题。
@KonradRudolph给出了一个很好的答案。我想补充一点:
有三种方法来设置随机种子,它们是不一样的:
- 使用
set.seed(n)
将其设置为易于再现的状态。 - 调用任何内部随机数生成器也会以一种确定性但不可预测的方式改变它。
- 保存并稍后恢复将其设置为先前的状态。
一般来说,set.seed()
只能输出随机种子可能值的一小部分,而调用RNG应该(最终)循环遍历所有这些值。有大约2^20000
种不同的随机种子,但set.seed()
只能产生大约2^32
种。(这两个数字都高估了,但比例大致正确。)
您可以保存并恢复.Random.seed
变量,或者调用set.seed(n)
将随机种子设置为已知状态。复制特定状态的唯一可行方法是从已知状态开始,并重复导致所需状态的调用。
依次回答你的观点:
[从计算结果逆向工程种子]可能吗?
这取决于实际使用的随机数生成器,但通常这很难,因为一个好的RNG的状态空间是巨大的,你可能必须彻底搜索它。这可能需要的不是几个小时,而是几年。
一个新的种子只在我删除环境中的所有变量时使用?
当你调用set.seed
时,一个新的种子被使用。实际的当前种子值存储在全局环境中的隐藏变量.Random.seed
中。但是,删除种子不会使您的最后一次计算重现,因为R会根据不确定的值(实际上是当前操作系统时间)重新初始化该种子的值。
如果我多次运行相同的代码,但没有清理环境,结果是相同的,因此使用了相同的种子。
否:消费随机值(通过调用随机函数)改变随机种子。因此,在不清理环境的情况下连续运行多个计算,和不会产生相同的结果。事实上,那将是可怕的。您可以自己轻松查看:
〉rnorm(1)
[1] -0.3156453
〉rnorm(1)
[1] 0.7345465
显然,连续两次调用随机函数(这里是rnorm
)并没有产生相同的结果,即使我没有在调用之间清理环境。
是否有一种方法可以理解函数何时依赖于
set.seed()
?
您可以设置不同的随机种子,重新运行该函数,并查看输出是否发生变化。
除此之外,没有通用的、直接的方法来做到这一点。如果该函数没有记录其对set.seed
的依赖,那么您唯一的办法就是仔细查看该函数(以及它依次调用的所有函数)的源代码。
奖励(Roland在评论中指出):
glm
和predict.glm
是非随机函数,非不依赖于set.seed
。