【问题标题】:R - Which seed did this split?R - 这分裂了哪个种子?
【发布时间】:2016-09-16 22:10:04
【问题描述】:

通常我们会固定一个种子编号以在每次运行代码时产生相同的拆分。所以代码

set.seed(12345)
data <- (1:100)
train <- sample(data, 50)
test <- (1:100)[-train]

总是给出相同的训练集和测试集(因为我们固定了种子)。

现在,假设我有一个数据、训练和测试。有没有办法知道哪个种子号用于从数据中产生训练和测试??? 最佳。

【问题讨论】:

  • 您能否澄清一下:种子是使用set.seed 中的整数设置的,但您不知道数字?或者种子尚未设置,您正在尝试重现系统的随机状态?

标签: r


【解决方案1】:

不可能用绝对的数学知道确定性:但是如果您怀疑种子所在的范围,您可以通过“蛮力”检查该范围内的每个种子并查看如果它导致相同的结果。

例如,您可以使用以下代码检查从 1 到 100 万的种子:

tests <- sapply(1:1e6, function(s) {
  set.seed(s)
  this_train <- sample(data, 50)

  all(this_train == train)
})

which(tests)
# 12345

几点说明:

  • 如果您的数据集或样本小得多,您将开始发生冲突 - 多个种子提供相同的输出。例如,如果您从 10 中抽取 5 粒,而不是从 100 粒中抽取 50 粒,则 1:1e6 范围内的 34 粒种子会产生相同的结果。
  • 如果您完全不怀疑种子是如何设置的,则必须检查从 -.Machine$integer.max 到 .Machine$integer.max,在我的计算机上需要 42 亿次检查(这需要一段时间,您可能必须聪明地不要存储所有结果)。
  • 如果在set.seed() 之后生成了随机数,您需要在函数中的set.seed 和sample 行之间复制相同的行为。
  • 设置种子后sample 的行为可能是differ in very old versions of R,因此您可能无法重现在早期版本上创建的行为

【讨论】:

  • 如果在设置种子之后和提取样本之前生成了一些随机数会怎样?我尝试在train &lt;- sample(data, 50) 之前插入invisible(runif(50)),但无法通过您的程序找到种子。
  • @nicola 关于您的第二条评论,您当然是对的,我在考虑旧版本的 R (添加链接)之间。关于第一个,您必须在 set.seed 之后的函数中添加这些随机生成。
  • 确实如此。所以必须说明,上述方法只有在我们感兴趣的样本是在设置种子之后立即生成的,或者在种子和样本之间生成的随机数的数量已知的情况下才有效。在后一种情况下,您必须在解决方案中的 set.seed 部分之后添加类似 runif(n) 的内容。
  • @nicola 我查看了它并确认如果您不知道在这之间进行了哪些随机生成,您将无法在几次随机生成后重置状态。来自?set.seed 关于(默认)Mersenne-Twister:A twisted GFSR with period 2^19937 - 1 and equidistribution in 623 consecutive dimensions (over the whole period). The ‘seed’ is a 624-dimensional set of 32-bit integers plus a current position in that set。这将是不可能的蛮力并且会发生碰撞。
【解决方案2】:

不,这是不可能的。多个种子可以产生同一系列的数据。这是不可逆的。

【讨论】:

  • 不可能100%确定完美,但100个(choose(100, 50))中50个可能的样本数约为10^29。可能的种子数为.Machine$integer.max * 2 + 1 = 4294967295。如果它们是随机分布的(它们不会是完美的,但随机化器旨在接近这一点),因此另一个种子获得相同输出的可能性是 1/10^19。
  • 公平点。我承认我没有花时间做它背后的数学,只是逻辑。感谢您的评论。
猜你喜欢
  • 2021-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-15
  • 2021-06-04
  • 2011-11-02
相关资源
最近更新 更多