gpt4 book ai didi

r - 在插入符号中并行操作的可重现结果的种子对象

转载 作者:行者123 更新时间:2023-12-04 00:40:21 24 4
gpt4 key购买 nike

我正在尝试将代码用于插入符号中完全可重现的并行模型,但不明白如何在种子对象中设置向量的大小。对于 gbm,我有 4 个调整参数,总共 11 个不同的级别,我的调整网格中有 54 行。如果我在下面的“for(i in 1:10)”行中指定任何值 < 18 作为最后一个值,我会收到一个错误:“坏种子:种子对象应该是长度为 11 的列表,其中包含 10 个整数向量大小为 18 且最后一个列表元素具有单个整数。”为什么是18?对于大于 18 的值(例如 54),它也可以正常运行 - 为什么?非常感谢您的帮助。以下基于http://topepo.github.io/caret/training.html ,添加了一些东西。

library(mlbench)
data(Sonar)
str(Sonar[, 1:10])
library(caret)
library(doParallel)

set.seed(998)
inTraining <- createDataPartition(Sonar$Class, p = .75, list = FALSE)
training <- Sonar[ inTraining,]
testing <- Sonar[-inTraining,]

grid <- expand.grid(n.trees = seq(50,150,by=50), interaction.depth = seq(1,3,by=1),
shrinkage = seq(.09,.11,by=.01),n.minobsinnode=seq(8,10,by=2))

# set seed to run fully reproducible model in parallel mode using caret
set.seed(825)
seeds <- vector(mode = "list", length = 11) # length is = (n_repeats*nresampling)+1
for(i in 1:10) seeds[[i]]<- sample.int(n=1000, 11) # ...the number of tuning parameter...
seeds[[11]]<-sample.int(1000, 1) # for the last model

fitControl <- trainControl(method = "cv",number = 10,seeds=seeds)

# run model in parallel
cl <- makeCluster(detectCores())
registerDoParallel(cl)

gbmFit1 <- train(Class ~ ., data = training,method = "gbm",
trControl = fitControl,tuneGrid=grid,verbose = FALSE)
gbmFit1

最佳答案

我将分两部分解决你的问题:

1 - 设置 seeds :

如你所说的那样做的代码:

set.seed(825)
seeds <- vector(mode = "list", length = 11)
for(i in 1:10) seeds[[i]]<- sample.int(n=1000, 54)
#for the last model
seeds[[11]]<-sample.int(1000, 1)

11seeds <- vector(mode = "list", length = 11)(n_repeats*nresampling)+1 ,所以在你的情况下,你正在使用 10-fold CV , 所以 10+1 = 11 .如果您使用 repeatedcvnumber=10 and repeats = 5您将替换 11(5*10)+1 = 51 .

10for(i in 1:10)(n_repeats*nresampling) .在你的情况下是 10因为您使用的是 10-fold CV .同样,如果您使用 repeatedcvnumber=10 and repeats = 5应该是 for(i in 1:50) .

54sample.int(n=1000, 54)number of tuning parameter combinations .在您的情况下,您有 4 parameters3,3,3 and 2 values .所以,它是 3*3*3*2 = 54 . 但是,我记得我在某处红色表示对于 gbm,该模型适合 max(n.trees)在网格中,并从中派生出具有较少树的模型,这解释了为什么 caret计算 seeds基于interaction.depth * shrinkage * n.minobsinnode在你的情况下3 * 3 * 2 = 18而不是 3*3*3*2 = 54我们稍后会看到。

但如果您使用的是 SVM带网格的模型 svmGrid <- expand.grid(sigma= 2^c(-25, -20, -15,-10, -5, 0), C= 2^c(0:5))你的值(value)是6 * 6 = 36

记住,使用 seeds 的目的是允许reproducible research通过在每次重采样迭代中设置适合模型的种子。

seeds[[11]]<-sample.int(1000, 1)用于设置适合整个数据集的最后一个(最佳)模型的种子。

2 - 为什么指定值 < 18 时会出现错误,但值 >= 18 时不会出现错误

我能够在我的机器上重现同样的错误:

Error in train.default(x, y, weights = w, ...) : 
Bad seeds: the seed object should be a list of length 11 with 10 integer vectors of size 18 and the last list element having a single integer

因此,通过检查 train.default我能够找到它的来源。错误消息由 stop 触发在行 7 to 10基于测试badSeed在行 45 .

    else {
if (!(length(trControl$seeds) == 1 && is.na(trControl$seeds))) {
numSeeds <- unlist(lapply(trControl$seeds, length))
4 badSeed <- (length(trControl$seeds) < length(trControl$index) +
5 1) || (any(numSeeds[-length(numSeeds)] < nrow(trainInfo$loop)))
if (badSeed)
7 stop(paste("Bad seeds: the seed object should be a list of length",
8 length(trControl$index) + 1, "with", length(trControl$index),
9 "integer vectors of size", nrow(trainInfo$loop),
10 "and the last list element having a", "single integer"))
}
}

号码18来自nrow(trainInfo$loop) ,所以我们需要找到 trainInfo$loop 的值.对象trainInfo被赋值为 trainInfo <- models$loop(tuneGrid)在第 3 行:

    if (trControl$method != "none") {
if (is.function(models$loop) && nrow(tuneGrid) > 1) {
3 trainInfo <- models$loop(tuneGrid)
if (!all(c("loop", "submodels") %in% names(trainInfo)))
stop("The 'loop' function should produce a list with elements 'loop' and 'submodels'")
}

现在,我们需要找到对象 models .它被赋值为 models <- getModelInfo(method, regex = FALSE)[[1]]在第 2 行:

    else {
2 models <- getModelInfo(method, regex = FALSE)[[1]]
if (length(models) == 0)
stop(paste("Model", method, "is not in caret's built-in library"))
}

由于我们使用的是 method = "gbm" ,我们可以看到getModelInfo("gbm", regex = FALSE)[[1]]$loop的值并检查以下结果:

> getModelInfo("gbm", regex = FALSE)[[1]]$loop
function(grid) {
3 loop <- ddply(grid, c("shrinkage", "interaction.depth", "n.minobsinnode"),
function(x) c(n.trees = max(x$n.trees)))
submodels <- vector(mode = "list", length = nrow(loop))
for(i in seq(along = loop$n.trees)) {
index <- which(grid$interaction.depth == loop$interaction.depth[i] &
grid$shrinkage == loop$shrinkage[i] &
grid$n.minobsinnode == loop$n.minobsinnode[i])
trees <- grid[index, "n.trees"]
submodels[[i]] <- data.frame(n.trees = trees[trees != loop$n.trees[i]])
}
list(loop = loop, submodels = submodels)
}
>

loop (在上面的第 3 行)被赋值:

loop <- ddply(grid, c("shrinkage", "interaction.depth", "n.minobsinnode"),
function(x) c(n.trees = max(x$n.trees)))`

现在,让我们通过您的grid54 rows到上面的行并检查结果:

> nrow(grid)
[1] 54
>
> loop <- ddply(grid, c("shrinkage", "interaction.depth", "n.minobsinnode"),
+ function(x) c(n.trees = max(x$n.trees)))
> loop
shrinkage interaction.depth n.minobsinnode n.trees
1 0.09 1 8 150
2 0.09 1 10 150
3 0.09 2 8 150
4 0.09 2 10 150
5 0.09 3 8 150
6 0.09 3 10 150
7 0.10 1 8 150
8 0.10 1 10 150
9 0.10 2 8 150
10 0.10 2 10 150
11 0.10 3 8 150
12 0.10 3 10 150
13 0.11 1 8 150
14 0.11 1 10 150
15 0.11 2 8 150
16 0.11 2 10 150
17 0.11 3 8 150
18 0.11 3 10 150
>

啊!我们找到了。值 18来自nrow(trainInfo$loop)来自getModelInfo("gbm", regex = FALSE)[[1]]$loop如上所示,仅 18 rows .

现在,回到触发错误的测试:

badSeed <- (length(trControl$seeds) < length(trControl$index) + 
1) || (any(numSeeds[-length(numSeeds)] < nrow(trainInfo$loop)))

测试的第一部分(length(trControl$seeds) < length(trControl$index) + 1)FALSE , 但第二部分 (any(numSeeds[-length(numSeeds)] < nrow(trainInfo$loop)))TRUE对于所有小于 18 的值[来自nrow(trainInfo$loop) ] 和 FALSE对于所有大于 18 的值.这就是为值 <18 触发错误的原因。而不是>=18 .正如我上面所说,插入符号计算 seeds基于interaction.depth * shrinkage * n.minobsinnode在你的情况下3 * 3 * 2 = 18 (模型适合 max(n.trees) 并且其他模型是从它派生的,因此不需要 54 整数)。

关于r - 在插入符号中并行操作的可重现结果的种子对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32099991/

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