gpt4 book ai didi

r - Seed 和 clusterApply - 如何选择特定运行?

转载 作者:行者123 更新时间:2023-12-02 09:19:23 25 4
gpt4 key购买 nike

我正在大型数据集(636,688 行 x 7 列)上执行 k 均值,因此转向并行化。我的结果需要可重复。我可以使用 parallel 包中的 clusterSetRNGStream 来完成此操作。以下是使用 MASS 库中的 Boston 数据集的示例:

library(parallel)
cl <- makeCluster(detectCores())
clusterSetRNGStream(cl, iseed = 1234)
clusterEvalQ(cl, library(MASS))
results <- clusterApply(cl, rep(25, 4), function(nstart) kmeans(Boston, 4, nstart = nstart))
check.results <- sapply(results, function(result) result$size)
stopCluster(cl)

每个 check.results 列表示 k 均值算法给定运行过程中每个相应簇的观测值数量。我的 check.results 看起来像这样:

     [,1] [,2] [,3] [,4]
[1,] 38 268 102 102
[2,] 268 98 98 38
[3,] 98 102 38 268
[4,] 102 38 268 98

如果我更改 results 变量以包含 rep(25, 2) 而不是 rep(25, 4),我会得到:

     [,1] [,2]
[1,] 38 268
[2,] 268 98
[3,] 98 102
[4,] 102 38

完美 - 前 2 次运行的大小保持不变,无论我运行 4 次迭代还是只运行 2 次。如果继续更改迭代次数,您将看到每次运行都保持不变。

我的问题 - 我如何挑选,例如特别是第四次运行而不需要运行前 3 次运行?底层 iseed clusterSetRNGStream下是否保存了特定的种子?

最佳答案

clusterSetRNGStream 函数不支持您非常想要的那种可重复性。问题在于,它只是初始化每个集群工作人员以从不同的随机数流中抽取随机数,当对给定数量的工作人员使用 clusterApply 时,这是可重现的。但是要执行特定任务,您必须在正确的工作线程上执行它才能获得正确的流,并在该流中快进,即使您知道每个任务消耗的随机数的确切数量,也不支持此操作任务。

相反,我建议您使用较低级别的函数为每个任务分配不同的随机数子流。您可以通过使用 nextRNGSubStream 函数生成任务种子来实现此目的:

library(parallel)
# This is based on the clusterSetRNGStream function from
# the parallel package, copyrighted by The R Core Team
getseeds <- function(ntasks, iseed) {
RNGkind("L'Ecuyer-CMRG")
set.seed(iseed)
seeds <- vector("list", ntasks)
seeds[[1]] <- .Random.seed
for (i in seq_len(ntasks - 1)) {
seeds[[i + 1]] <- nextRNGSubStream(seeds[[i]])
}
seeds
}

由于我们没有使用clusterSetRNGStream,因此您需要在初始化工作线程时将随机数生成器设置为“L'Ecuyer-CMRG”:

cl <- makeCluster(detectCores())
clusterEvalQ(cl, { library(MASS); RNGkind("L'Ecuyer-CMRG") })

关键是从工作函数中设置“.Random.seed”的值,以便为每个任务使用正确的随机数子流:

worker <- function(nstart, seed, centers=4) {
assign(".Random.seed", seed, envir=.GlobalEnv)
kmeans(Boston, centers, nstart = nstart)
}

由于我们要迭代 nstartseed 值,因此您使用 clusterMap 而不是 clusterApply执行任务:

n <- 4
nstarts <- rep(25, n)
seeds <- getseeds(n, 1234)
results <- clusterMap(cl, worker, nstarts, seeds)

要重现第四个任务的结果,请指定第四个种子:

itasks <- c(4)
results <- clusterMap(cl, worker, nstarts[itasks], seeds[itasks])

使用此方法,即使通过 clusterMap .scheduling="dynamic" 参数进行负载平衡,您也可以获得可重现的结果,因为结果不依赖于运行的工作线程按照使用 clusterSetRNGStream 时的方式执行任务。

<小时/>

请注意,您可以使用 clusterMap MoreArgs 参数为 workercenters 参数指定值> 功能:

results <- clusterMap(cl, worker, nstarts, seeds, MoreArgs=list(centers=5))

关于r - Seed 和 clusterApply - 如何选择特定运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21560363/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com