在 R 中从 parallelSVM 重现结果的问题
Problem to reproduce results from parallelSVM in R
我无法设置种子值以从 parallelSVM()
获得可重现的结果。
library(e1071)
library(parallelSVM)
data(iris)
x <- subset(iris, select = -Species)
y <- iris$Species
set.seed(1)
model <- parallelSVM(x, y)
parallelPredictions <- predict(model, x)
set.seed(1)
model2 <- parallelSVM(x, y)
parallelPredictions2 <- predict(model2, x)
all.equal(parallelPredictions,parallelPredictions2)
我知道这不是为多核操作设置种子值的正确方法,但我不知道该怎么做。
我知道在使用 mclapply
时有一个选项,但这对我的情况没有帮助。
编辑:
我找到了一个解决方案,方法是将 parallelSVM
中的函数 trainSample()
更改为 trace
和 doRNG
种子包使用 foreach
循环。
有人知道更好的解决方案吗?
简而言之,parallelSVM
中没有实现方法来处理这个问题。然而,该包使用 foreach
和 doParallel
包来处理它的并行操作。在 Whosebug 上努力挖掘一个解决方案是可能的!
感谢 , on the usage of the doRNG
package, and this answer 让我想到了一个更简单的封闭式解决方案。
解决方案:
在 parallelSVM
包中,并行化通过 parallelSVM::registerCores
函数发生。此函数仅使用核心数调用 doParallel::registerDoParallel
,没有其他参数。我的想法是简单地更改 parallelSVM::registerCores
函数,使其在创建新集群后自动将种子设置为。
在执行并行计算时,需要并行种子,需要确保两件事
- 种子需要给集群中的每个节点
- 生成器需要是跨集群渐近随机的生成器。
幸运的是, 包处理了第一个,并使用了在 2 上可用的种子。使用 unlockNamespace
和 assign
的组合,我们可以覆盖 parallelSVM::registerCores
,这样它就包含了对 doRNG::registerDoRNG
的调用以及适当的种子(答案末尾的函数)。这样做我们实际上可以获得适当的再现性,如下图所示:
library(parallelSVM)
library(e1071)
data(magicData)
set.seed.parallelSWM(1) #<=== set seed as we would normally.
#Example from help(parallelSVM)
system.time(parallelSvm1 <- parallelSVM(V11 ~ ., data = trainData[,-1],
numberCores = 4, samplingSize = 0.2,
probability = TRUE, gamma=0.1, cost = 10))
system.time(parallelSvm2 <- parallelSVM(V11 ~ ., data = trainData[,-1],
numberCores = 4, samplingSize = 0.2,
probability = TRUE, gamma=0.1, cost = 10))
pred1 <- predict(parallelSvm1)
pred2 <- predict(parallelSvm2)
all.equal(pred1, pred2)
[1] TRUE
identical(parallelSvm1, parallelSvm2)
[1] FALSE
请注意,identical
没有能力正确评估 parallel::parallelSvm
输出的对象,因此预测更好地检查模型是否相同。
为了安全起见,让我们检查问题中的可重现示例是否也是这种情况
x <- subset(iris, select = -Species)
y <- iris$Species
set.seed.parallelSWM(1) #<=== set seed as we would normally (not necessary if above example has been run).
model <- parallelSVM(x, y)
model2 <- parallelSVM(x, y)
parallelPredicitions <- predict(model, x)
parallelPredicitions2 <- predict(model2, x)
all.equal(parallelPredicitions, parallelPredicitions2)
[1] TRUE
呼..
最后,如果我们完成了,或者如果我们再次想要随机种子,我们可以通过执行
来重置种子
set.seed.parallelSWM() #<=== set seed to random each execution (standard).
#check:
model <- parallelSVM(x, y)
model2 <- parallelSVM(x, y)
parallelPredicitions <- predict(model, x)
parallelPredicitions2 <- predict(model2, x)
all.equal(parallelPredicitions, parallelPredicitions2)
[1] "3 string mismatches"
(输出会有所不同,因为 RNNG 种子未设置)
set.seed.parallelSWM 函数
归功于 。请注意,我们可能不必将作业加倍,但在这里我只是简单地复制了答案,而没有检查代码是否可以进一步减少。
set.seed.parallelSWM <- function(seed, once = TRUE){
if(missing(seed) || is.character(seed)){
out <- function (numberCores)
{
cluster <- parallel::makeCluster(numberCores)
doParallel::registerDoParallel(cluster)
}
}else{
require("doRNG", quietly = TRUE, character.only = TRUE)
out <- function(numberCores){
cluster <- parallel::makeCluster(numberCores)
doParallel::registerDoParallel(cluster)
doRNG::registerDoRNG(seed = seed, once = once)
}
}
unlockBinding("registerCores", as.environment("package:parallelSVM"))
assign("registerCores", out, "package:parallelSVM")
lockBinding("registerCores", as.environment("package:parallelSVM"))
unlockBinding("registerCores", getNamespace("parallelSVM"))
assign("registerCores", out, getNamespace("parallelSVM"))
lockBinding("registerCores", getNamespace("parallelSVM"))
#unlockBinding("registerCores", as.environment("package:parallelSVM"))
invisible()
}
我无法设置种子值以从 parallelSVM()
获得可重现的结果。
library(e1071)
library(parallelSVM)
data(iris)
x <- subset(iris, select = -Species)
y <- iris$Species
set.seed(1)
model <- parallelSVM(x, y)
parallelPredictions <- predict(model, x)
set.seed(1)
model2 <- parallelSVM(x, y)
parallelPredictions2 <- predict(model2, x)
all.equal(parallelPredictions,parallelPredictions2)
我知道这不是为多核操作设置种子值的正确方法,但我不知道该怎么做。
我知道在使用 mclapply
时有一个选项,但这对我的情况没有帮助。
编辑:
我找到了一个解决方案,方法是将 parallelSVM
中的函数 trainSample()
更改为 trace
和 doRNG
种子包使用 foreach
循环。
有人知道更好的解决方案吗?
简而言之,parallelSVM
中没有实现方法来处理这个问题。然而,该包使用 foreach
和 doParallel
包来处理它的并行操作。在 Whosebug 上努力挖掘一个解决方案是可能的!
感谢 doRNG
package, and this answer 让我想到了一个更简单的封闭式解决方案。
解决方案:
在 parallelSVM
包中,并行化通过 parallelSVM::registerCores
函数发生。此函数仅使用核心数调用 doParallel::registerDoParallel
,没有其他参数。我的想法是简单地更改 parallelSVM::registerCores
函数,使其在创建新集群后自动将种子设置为。
在执行并行计算时,需要并行种子,需要确保两件事
- 种子需要给集群中的每个节点
- 生成器需要是跨集群渐近随机的生成器。
幸运的是,unlockNamespace
和 assign
的组合,我们可以覆盖 parallelSVM::registerCores
,这样它就包含了对 doRNG::registerDoRNG
的调用以及适当的种子(答案末尾的函数)。这样做我们实际上可以获得适当的再现性,如下图所示:
library(parallelSVM)
library(e1071)
data(magicData)
set.seed.parallelSWM(1) #<=== set seed as we would normally.
#Example from help(parallelSVM)
system.time(parallelSvm1 <- parallelSVM(V11 ~ ., data = trainData[,-1],
numberCores = 4, samplingSize = 0.2,
probability = TRUE, gamma=0.1, cost = 10))
system.time(parallelSvm2 <- parallelSVM(V11 ~ ., data = trainData[,-1],
numberCores = 4, samplingSize = 0.2,
probability = TRUE, gamma=0.1, cost = 10))
pred1 <- predict(parallelSvm1)
pred2 <- predict(parallelSvm2)
all.equal(pred1, pred2)
[1] TRUE
identical(parallelSvm1, parallelSvm2)
[1] FALSE
请注意,identical
没有能力正确评估 parallel::parallelSvm
输出的对象,因此预测更好地检查模型是否相同。
为了安全起见,让我们检查问题中的可重现示例是否也是这种情况
x <- subset(iris, select = -Species)
y <- iris$Species
set.seed.parallelSWM(1) #<=== set seed as we would normally (not necessary if above example has been run).
model <- parallelSVM(x, y)
model2 <- parallelSVM(x, y)
parallelPredicitions <- predict(model, x)
parallelPredicitions2 <- predict(model2, x)
all.equal(parallelPredicitions, parallelPredicitions2)
[1] TRUE
呼..
最后,如果我们完成了,或者如果我们再次想要随机种子,我们可以通过执行
来重置种子set.seed.parallelSWM() #<=== set seed to random each execution (standard).
#check:
model <- parallelSVM(x, y)
model2 <- parallelSVM(x, y)
parallelPredicitions <- predict(model, x)
parallelPredicitions2 <- predict(model2, x)
all.equal(parallelPredicitions, parallelPredicitions2)
[1] "3 string mismatches"
(输出会有所不同,因为 RNNG 种子未设置)
set.seed.parallelSWM 函数
归功于
set.seed.parallelSWM <- function(seed, once = TRUE){
if(missing(seed) || is.character(seed)){
out <- function (numberCores)
{
cluster <- parallel::makeCluster(numberCores)
doParallel::registerDoParallel(cluster)
}
}else{
require("doRNG", quietly = TRUE, character.only = TRUE)
out <- function(numberCores){
cluster <- parallel::makeCluster(numberCores)
doParallel::registerDoParallel(cluster)
doRNG::registerDoRNG(seed = seed, once = once)
}
}
unlockBinding("registerCores", as.environment("package:parallelSVM"))
assign("registerCores", out, "package:parallelSVM")
lockBinding("registerCores", as.environment("package:parallelSVM"))
unlockBinding("registerCores", getNamespace("parallelSVM"))
assign("registerCores", out, getNamespace("parallelSVM"))
lockBinding("registerCores", getNamespace("parallelSVM"))
#unlockBinding("registerCores", as.environment("package:parallelSVM"))
invisible()
}