Set seed с параллельным cv.glmnet дает разные результаты в R

Я использую параллельный пакет cv.glmnet из пакета glmnet для более чем 1000 наборов данных. В каждом прогоне я устанавливаю начальное значение, чтобы результаты были воспроизводимыми. Я заметил, что мои результаты отличаются. Дело в том, что когда я запускаю код в один и тот же день, то и результаты те же. Но на следующий день они отличаются.

Вот мой код:

model <- function(path, file, wyniki, faktor = 0.75) {

  set.seed(2)

  dane <- read.csv(file)

  n <- nrow(dane)
  podzial <- 1:floor(faktor*n)


  ########## GLMNET ############
  nFolds <- 3

  train_sparse <- dane[podzial,]
  test_sparse  <- dane[-podzial,]

  # fit with cross-validation
  tryCatch({
    wart <- c(rep(0,6), "nie")
    model <- cv.glmnet(train_sparse[,-1], train_sparse[,1], nfolds=nFolds, standardize=FALSE)

    pred <- predict(model, test_sparse[,-1], type = "response",s=model$lambda.min)

    # fetch of AUC value
    aucp1 <- roc(test_sparse[,1],pred)$auc

  }, error = function(e) print("error"))

  results <- data.frame(auc = aucp1, n = nrow(dane))
  write.table(results, wyniki, sep=',', append=TRUE,row.names =FALSE,col.names=FALSE)


}

path <- path_to_files
files <- list.files(sciezka, full.names = TRUE, recursive = TRUE)
wyniki <- "wyniki_adex__samplingfalse_decl_201512.csv"

library('doSNOW')
library('parallel')

#liczba watkow
threads <- 5

#rejestrujemy liczbe watkow
cl <- makeCluster(threads, outfile="")
registerDoSNOW(cl)

message("Loading packages on threads...")
clusterEvalQ(cl,library(pROC))
clusterEvalQ(cl,library(ROCR))
clusterEvalQ(cl,library(glmnet))
clusterEvalQ(cl,library(stringi))

message("Modelling...")
foreach(i=1:length(pliki)) %dopar% {
  print(i)
  model(path, files[i], wyniki)
}

Кто-нибудь знает, в чем причина? Я использую CentOS Linux версии 7.0.1406 (Core)/Red Hat 4.8.2-16.


person potockan    schedule 08.01.2016    source источник


Ответы (2)


Нашел ответ в документации функции cv.glmnet:

Обратите также внимание, что результаты cv.glmnet являются случайными, поскольку складки выбираются случайным образом.

Решение состоит в том, чтобы вручную задать складки, чтобы они не выбирались наугад:

nFolds <- 3
foldid <- sample(rep(seq(nFolds), length.out = nrow(train_sparse))
model <- cv.glmnet(x = as.matrix(x = train_sparse[,-1], 
                   y = train_sparse[,1], 
                   nfolds = nFolds,
                   foldid = foldid,
                   standardize = FALSE)
person potockan    schedule 12.07.2017
comment
Понятия не имею, почему вас за это проголосовали. Ваш код - это именно то, что делается внутри cv.glmnet, так что это кажется правильным решением. - person daknowles; 23.07.2018

Согласно Написание расширений R, Оболочка C необходима для вызова обычных случайных чисел R из FORTRAN. Я не вижу никакого кода C в исходном коде glmnet. Боюсь, это не выглядит реализованным:

6.6 Вызов C из FORTRAN и наоборот

person Zelazny7    schedule 08.01.2016