Я столкнулся с реальной проблемой при анализе моих данных. Я надеюсь, что кто-то из вас сможет мне помочь.
У меня 18 переменных и двоичный результат. Я хочу попробовать все возможные комбинации переменных (т.е. 2 ^ 18 -1 = 262'143) и для каждой из них построить три модели (Logisti c, SVM, RandomForest) и вычислить AU C .
Одна итерация длится около 10 с, и у меня довольно неплохой компьютер (12 ядер + HT, 160 ГБ ОЗУ), поэтому я реализовал следующий код для l oop (fitData - это фрейм данных со всеми ковариатами и результат)
cl <- makeCluster(15, outfile="")
registerDoParallel(cl)
clinicalSweep3 <- foreach (kei= 1:(2^(length(varNames)) -1), .combine='rbind', .packages=c('e1071','pROC','randomForest')) %dopar% {
varNamesKei <- varNames[as.logical(intToBits(kei)[1:(length(varNames))])]
yString <- (paste(as.integer(intToBits(kei)[1:(length(varNames))]),collapse=""))
yLabel <- as.character(paste(varNamesKei,collapse="+"))
covPacket <- data.frame(t(strsplit(yString,"")[[1]]))
colnames(covPacket) <- varNames
AUC_Logit <- NA
AUC_SVM <- NA
AUC_RF <- NA
AUC_Logit2CV <- NA
AUC_SVM2CV <- NA
AUC_RF2CV <- NA
predLogit <- 1:dim(fitData)[1]
predSVM <- 1:dim(fitData)[1]
predRF <- 1:dim(fitData)[1]
for (k in 1:dim(fitData)[1]){
predLogit[k] <- predict(glm(as.formula(paste("outcome ~ ", paste(varNamesKei, collapse= "+"))),data = fitData[-k,], family=binomial(link='logit')),type="response", newdata = fitData[k,,drop=F])
predSVM[k] <- predict(svm(as.formula(paste("outcome ~ ", paste(varNamesKei, collapse= "+"))),data = fitData[-k,], kernel = "linear", cost = 10, type = "C-classification"), newdata = as.data.frame(fitData[k,,drop=F]))
predRF[k] <- predict(randomForest(as.formula(paste("outcome ~ ", paste(varNamesKei, collapse= "+"))),data = fitData[-k,], ntree=100),type="prob", newdata = fitData[k,,drop=F])[2]
}
AUC_Logit <- auc(fitData$outcome,predLogit,direction="<", levels = c(F,T))
AUC_SVM <- auc(fitData$outcome,predSVM,direction="<", levels = c(F,T))
AUC_RF <- auc(fitData$outcome,predRF,direction="<", levels = c(F,T))
predLogit <- 1:dim(fitData)[1]
predSVM <- 1:dim(fitData)[1]
predRF <- 1:dim(fitData)[1]
for (k in 1:(dim(fitData)[1]/2)){
predLogit[c(2*k-1,2*k)] <- predict(glm(as.formula(paste("outcome ~ ", paste(varNamesKei, collapse= "+"))),data = fitData[-c(2*k-1,2*k),], family=binomial(link='logit')),type="response", newdata = fitData[c(2*k-1,2*k),,drop=F])
predSVM[c(2*k-1,2*k)] <- predict(svm(as.formula(paste("as.numeric(outcome)-1 ~ ", paste(varNamesKei, collapse= "+"))),data = fitData[-c(2*k-1,2*k),], kernel = "linear", cost = 10, type = "eps-regression"), newdata = as.data.frame(fitData[c(2*k-1,2*k),,drop=F]))
predRF[c(2*k-1,2*k)] <- predict(randomForest(as.formula(paste("outcome ~ ", paste(varNamesKei, collapse= "+"))),data = fitData[-c(2*k-1,2*k),], ntree=100),type="prob", newdata = fitData[c(2*k-1,2*k),,drop=F])[,2]
}
AUC_Logit2CV <- auc(fitData$outcome,predLogit,direction="<", levels = c(F,T))
AUC_SVM2CV <- auc(fitData$outcome,predSVM,direction="<", levels = c(F,T))
AUC_RF2CV <- auc(fitData$outcome,predRF,direction="<", levels = c(F,T))
}
cat(as.character(Sys.time()),"combo",yString,"done! (",kei,")\n")
data.frame( yString, covPacket,
AUC_Logit, AUC_SVM,AUC_RF ,
AUC_Logit2CV, AUC_SVM2CV, AUC_RF2CV ,
yLabel)
}
Теперь код работает без проблем около 30 часов, хотя я заметил, что объем оперативной памяти постоянно увеличивается. Вчера я решил создать область подкачки объемом 100 ГБ, и, действительно, когда последний рабочий закончил, ситуация была следующей.
![RAMUsage](https://i.stack.imgur.com/GdVAF.png)
ЦП больше не было используется, но сеанс R все еще был заблокирован и работает. Я надеялся, что это закончится в одночасье, но сегодня утром ситуация не лучше.
Своппинг установлен на 50.
Теперь я понял, что foreach не должен использовать с таким количеством итераций.
Теперь вопросы:
1) Должен ли я остановить и переписать весь код, вложив нормальный l oop в foreach? (около 3000 итераций в foreach * 100 в норме для). Или я должен подождать (возможно, увеличить обмен)
clinicalSweep3 <- foreach (kei1= 0:floor((2^(length(varNames)) -1)/100), .combine='rbind', .packages=c('e1071','pROC','randomForest')) %dopar% {
for (kei2 in 1:min((2^(length(varNames)) -1) - kei1*100,100 ) ) {
kei <- kei1*100+kei2
# РЕДАКТИРОВАТЬ: я обнаружил, что, вероятно, foreach (kei = idiv (2 ^ (length (varNames))) -1, chunks = 100), .. .) надо делать работу
2) Почему это массовое использование ОЗУ и как его избежать? (это все в основной rsession, а не в рабочих). Должен ли я запускать g c () в начале / конце каждой итерации? (по умолчанию .export = NULL не должен импортировать все в рабочих формах основного потока)
3) Почему мое ядро (из Ubuntu 20.04 Desktop) недостаточно загружено? Может быть, потому что это один поток с 300 ГБ?
4) Если у вас есть предложения о том, как улучшить общую производительность кода, я буду рад их услышать!
Спасибо!