Как получить те же результаты, используя l oop и параллельно в R? - PullRequest
1 голос
/ 30 апреля 2020

Я проверяю влияние тренировочных данных на точность классификации. Например, я использую данные радужной оболочки. Я заметил, что получаю лучшую точность из 33 итераций. Я хотел бы использовать тренировочный набор (iristrain) из итерации для дальнейшего анализа. Я не знаю, как воспроизвести это. Я не хочу сохранять тренировочный набор каждую итерацию, потому что он большой. Я хотел бы только получить этот набор из 33 итераций. Я попытался это: clusterSetRNGStream () Затем я использовал тот же начальный в al oop, и он не дал те же результаты

library(randomForest)
library(caret)
library(foreach)
library(doParallel)

results_overall <- data.frame()

cores = detectCores()
cl = makeCluster(cores - 1)

registerDoParallel(cl)
res <- foreach(i = 1:50, .packages = c("caret", "randomForest"), .combine = rbind) %dopar% {

trainIndex <- caret::createDataPartition(iris$Species, p = 0.5, list = FALSE)
irisTrain <- iris[ trainIndex,]
irisTest  <- iris[-trainIndex,]

model <- randomForest(x = irisTrain[,c(1:4)], y = irisTrain[,5], importance = TRUE,
                                            replace = TRUE, mtry = 4, ntree = 500, na.action=na.omit,
                                            do.trace = 100, type = "classification")

pred_test <- predict(model, irisTest[,c(1:4)])
con.mat_test <- confusionMatrix(pred_test, irisTest[,5], mode ="everything")

results_overall <- rbind(results_overall, con.mat_test[["overall"]])

return(tibble::tribble(~iteration, ~overall, 
                       i, results_overall))
}
stopCluster(cl)

Ответы [ 2 ]

2 голосов
/ 01 мая 2020

Ваши итерации дают различия, основанные на случайной выборке, выполненной caret::createDataPartition. Чтобы сделать это воспроизводимым, вы можете использовать пакет doRNG, написанный для этой цели - большое спасибо @HenrikB за то, что он меня проинформировал!

Редактировать: исправил функцию foreach (сделал не изменить результат)

invisible(suppressPackageStartupMessages(
    lapply(c("data.table", "randomForest", "caret", "foreach", 
             "doRNG", "rngtools", "doParallel"),
           require, character.only = TRUE)))
cores = detectCores()
cl = makeCluster(cores - 1)
registerDoParallel(cl)
res <- foreach(i = 1:50, .packages = c("caret", "randomForest", "data.table"), .combine = rbind,
               .options.RNG=1234) %dorng% {
                   trainIndex <- caret::createDataPartition(iris$Species, p = 0.5, list = FALSE)
                   irisTrain <- iris[ trainIndex,]
                   irisTest  <- iris[-trainIndex,]
                   model <- randomForest(x = irisTrain[,c(1:4)], y = irisTrain[,5], importance = TRUE,
                                         replace = TRUE, mtry = 4, ntree = 500, na.action=na.omit,
                                         do.trace = 100, type = "classification")
                   pred_test <- predict(model, irisTest[,c(1:4)])
                   con.mat_test <- confusionMatrix(pred_test, irisTest[,5], mode ="everything")
                   return(data.table(Iteration=i, t(con.mat_test[["overall"]])))
               }
stopCluster(cl)
seeds <-  attr(res, 'rng')
res[which.min(Accuracy),]
#>    Iteration  Accuracy Kappa AccuracyLower AccuracyUpper AccuracyNull
#> 1:         6 0.9066667  0.86     0.8171065     0.9616461    0.3333333
#>    AccuracyPValue McnemarPValue
#> 1:    4.39803e-25           NaN

best.seed <- res[which.min(Accuracy),]$Iteration

rngtools::setRNG(seeds[[best.seed]])
trainIndex <- caret::createDataPartition(iris$Species, p = 0.5, list = FALSE)
irisTrain <- iris[ trainIndex,]
irisTest  <- iris[-trainIndex,]

model <- randomForest(x = irisTrain[,c(1:4)], y = irisTrain[,5], importance = TRUE,
                      replace = TRUE, mtry = 4, ntree = 500, na.action=na.omit,
                      do.trace = 100, type = "classification")
#> ntree      OOB      1      2      3
#>   100:   4.00%  0.00%  4.00%  8.00%
#>   200:   2.67%  0.00%  4.00%  4.00%
#>   300:   2.67%  0.00%  4.00%  4.00%
#>   400:   2.67%  0.00%  4.00%  4.00%
#>   500:   4.00%  0.00%  4.00%  8.00%
pred_test <- predict(model, irisTest[,c(1:4)])
con.mat_test <- confusionMatrix(pred_test, irisTest[,5], mode ="everything")
con.mat_test[["overall"]]
#>       Accuracy          Kappa  AccuracyLower  AccuracyUpper   AccuracyNull 
#>   9.066667e-01   8.600000e-01   8.171065e-01   9.616461e-01   3.333333e-01 
#> AccuracyPValue  McnemarPValue 
#>   4.398030e-25            NaN

Создано в 2020-05-05 пакетом Представление (v0.3.0)

0 голосов
/ 30 апреля 2020

Попробуйте это set.seed(1) и установите его перед training моделью. Для получения дополнительной информации позвоните в R эту команду ?set.seed(), она там довольно хорошо описана. seed number является отправной точкой генерации последовательности случайных чисел. Для получения дополнительной информации здесь

...