У меня большой размер данных (~ 700 nx 36000 p) и планируете проводить анализы randomforest в R. Из-за бремени времени отправки полного кадра к randomForest (даже с параллельными вычислениями и 512 ГБ оперативной памяти), я хотел бы отправить различные случайные подвыборки данных (~ 5% p) на randomForest во многих независимых прогонах (Nruns). Для меньших кадров данных я создал цикл foreach, чтобы отправить весь фрейм данных в randomForest и вернуть матрицу важных результатов, которая является dim (p, Nruns) плюс 3 дополнительных строки, содержащих некоторую дополнительную информацию, сгенерированную в каждом Nrun. Тем не менее, мне не удается создать компонент foreach() скрипта для отправки другой подвыборки кадра данных в randomForest для каждого прогона. (Подвыборка состоит из двух шагов: Создайте сбалансированный набор данных (по исходному классу) с помощью выборки строк сначала (эта часть работает), затем выберите подмножество столбцов.) Желаемые результаты будут по-прежнему представлять собой блок данных dim (p + 3, Nruns), но каждый столбец будет содержать результаты только для переменных, которые были случайно выбраны в прогоне, представленном этим столбцом (т. Е. Отсутствовали значения для переменных, не выбранных для этого прогона). Когда я отправляю код ниже (используя поддельные данные, созданные ниже), я получаю следующую ошибку: «функция вызова вызова вызова: » Обратите внимание, что, как указано в коде, если я исключаю шаг выбора случайных столбцов, но сохраните шаг, на котором выполняется балансировка, я не получаю сообщение об ошибке, и выход такой же, как ожидалось (с dim (p + 3, Nruns), и все ячейки имеют ненулевые значения.) Таким образом, проблема находится в разделе кода, где выполняется выборка столбцов. Хотелось бы узнать, может ли кто-нибудь предложить средство для кода ниже, который будет выполнять новую случайную подвыборку столбцов (и строк) для каждого из 1: Nruns.R: использование foreach() с процедурами sample() в вызове randomForest()
Спасибо за любые предложения.
##########################################################################
# CREATE FAKE DATA
##########################################################################
FAKEinput <-
data.frame(A=sample(25:75,20, replace=T), B=sample(1:2,20,replace=T), C=as.factor(sample(0:1,20,replace=T,prob=c(0.3,0.7))),
D=sample(200:350,20,replace=T), E=sample(2300:2500,20,replace=T), F=sample(92000:105000,20,replace=T),
G=sample(280:475,20,replace=T),H=sample(470:550,20,replace=T),I=sample(2537:2723,20,replace=T),
J=sample(2984:4199,20,replace=T),K=sample(222:301,20,replace=T),L=sample(28:53,20,replace=T),
M=sample(3:9,20,replace=T),N=sample(0:2,20,replace=T),O=sample(0:5,20,replace=T),P=sample(0:2,20,replace=T),
Q=sample(0:2,20,replace=T), R=sample(0:2,20,replace=T), S=sample(0:7,20,replace=T))
##########################################################################
# set FOREST DATASET
##########################################################################
forestData <- FAKEinput
##########################################################################
# set Outcome
##########################################################################
Outcome <- "C"
##########################################################################
# set DV
#########################################################################
forestDV <- forestData$C
str(forestDV) #factor
##########################################################################
#set up number of runs:
##########################################################################
Nruns<-5
##########################################################################
#set up ntree
##########################################################################
ntree=100
###########################################################################
#set up mtry:
###########################################################################
mtry=round(sqrt(ncol(forestData))) #4
###########################################################################
## CREATE DATASET WITH ONLY THE PREDICTORS (I.E., OMIT OUTCOME).
###########################################################################
dropVars <- names(forestData) %in% c(Outcome)
forestPREDICTORS <- forestData[!dropVars]
###########################################################################
#set seed first to replicate the random draw of seeds
###########################################################################
set.seed(3456)
###########################################################################
# GENERATE Nruns RANDOMSEEDS
###########################################################################
randomseed<- sample(1:(length(forestData[,1])),Nruns, replace=TRUE) #16 16 18 8 11
##########################################
#Load necessary packages into R's memory
##########################################
require(iterators)
require(foreach)
require(parallel)
require(doParallel)
require(randomForest)
###########################################
# Get the number of available logical cores
###########################################
cores <- detectCores()
cores
###########################################
# Print info on computer, OS, cores
###########################################
print(paste('Processor: ', Sys.getenv('PROCESSOR_IDENTIFIER')), sep='')
print(paste('OS: ', Sys.getenv('OS')), sep='')
print(paste('Cores: ', cores, sep=''))
##################################################################################################
# Set up new function, called ’ImpOOBerr':
# 1)write in the set random seed part that uses the same ‘i’ from the ‘foreach’ loops
# 2) save the importance and summary measures output from the random forest run
# 3) combine all of the importance scores and OOB error summary results (as columns) into single matrix
# * other options tried to correct error commented out.
###################################################################################################
ImpOOBerr<-function(y,d) {
set.seed(randomseed[i])
out.model<-randomForest(y ~ .,
data=d,
ntree=ntree,
mtry=mtry,
nodesize=0.1*nrow(forestData),
importance=TRUE,
proximity=FALSE)
# create the frame before filling with values?
#out<-data.frame(matrix(nrow=ncol(forestPREDICTORS)+3, ncol=Nruns))
out<-rbind(importance(out.model, type=1, scale=FALSE),
mean(out.model$err.rate[,1]),
rbind(t(t(quantile(out.model$err.rate[,1], probs=c(0.025, 0.975))))))
#rownames(out) <- c(names(forestPREDICTORS),'meanOOB','oobL95CI', 'oobU95CI') # name all the rows
# OR name only newly-added rows since randomForest importance output preserves the variable names
rownames(out)[(nrow(out)-2):nrow(out)]<-c('meanOOB','oobL95CI', 'oobU95CI')
return(out)
}
###########################################################################
# SET UP THE CLUSTER
###########################################################################
#Setup clusters via parallel/DoParallel
cl.spec <- rep("localhost", 10)
cl <- makeCluster(cl.spec, type="SOCK")
registerDoParallel(cl, cores=10)
###########################################################################
# Employ foreach to carry out randomForest in parallel
##########################################################################
system.time(fakeRF <- foreach(i=1:Nruns, .combine='cbind', .packages='randomForest')
%dopar% { #<<change to %do% to see speed difference
######################################################################################################
# FIRST, BALANCE THE DATASET ON OUTCOME CLASS FOR INPUT TO randomForest CLASSIFICATION
######################################################################################################
dat1<-forestData[forestData$C==1,]
dat0<-forestData[forestData$C==0,]
####################################################
# RESET the seed to make sure it is updating and
# giving different samples for each run
####################################################
set.seed(randomseed[i])
####################################################
# OVERSAMPLE FROM SMALLER GROUP TO BALANCE DATASET
####################################################
rands=sample(1:dim(dat0)[1],dim(dat1)[1], replace=TRUE)
balancedCLASS<-rbind(dat0[rands,],dat1)
######################################################################################################
# NOW DO RANDOM SAMPLES OF THE COLUMNS (VARIABLES) TO CREATE NEW DATA SUBSETS TO SEND TO randomForest
# AT EACH RUN
# NOTE: TO TEST SCRIPT WITHOUT COLUMN SAMPLING, COMMENT OUT ALL SCRIPT BETWEEN TWO "#xxxxxxxxx.." ROWS
# AND UNCOMMENT THE NEXT THREE LINES
######################################################################################################
#forestData<-balancedCLASS
#forestDV<-balancedCLASS$C
#forestPREDICTORS <- balancedCLASS[!names(balancedCLASS) %in% c('C')]
##xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
##xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
####################################################
# PULL OUT PREDICTORS (i.e., exclue the outcome)
# before sampling the columns
####################################################
PREDICTORS <- balancedCLASS[!names(balancedCLASS) %in% c('C')]
####################################################
# from the row-balanced set created above,
# draw a 5-column subset for each run
####################################################
randsCOL= sample(1:dim(PREDICTORS)[2], 5, replace=FALSE)
####################################################
# BIND OUTCOME VAR BACK ONTO RANDOM COL SET
####################################################
Set_BALrandsCOL <- cbind(balancedCLASS$C, balancedCLASS[,randsCOL])
####################################################
# FIX OUTCOME NAME (was retained as "balancedCLASS$C")
####################################################
names(Set_BALrandsCOL)[names(Set_BALrandsCOL)=="balancedCLASS$C"] <- "C"
####################################################
# ASSIGN THE OUTCOME OF SAMPLING BACK TO
# forestData, forestDV and forestPREDICTORS for RF runs
####################################################
forestData<-Set_BALrandsCOL
forestDV<-Set_BALrandsCOL$C
forestPREDICTORS <- Set_BALrandsCOL[!names(Set_BALrandsCOL) %in% c('C')]
##xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
##xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
#############################################################################################
# CALL FUNCTION THAT WILL RUN randomForest AND COMBINE THE OUTPUT FROM EACH RUN
#############################################################################################
ImpOOBerr(forestDV, forestPREDICTORS)
})
##########################
# stop the cluster
##########################
stopCluster(cl)
#############################################################################################
# SAVE THE OUTPUT TO FILE
#############################################################################################
save(fakeRF, file="D:/RF/WORKING/fakeRF.rda")
Просто попробуйте это вручную с помощью 'i = 1' Я получу матрицу dim (8,1), в то время как' i = 2' дает dim (7,1). Если это известная вариация в выходе «ImpOOBerr», вам нужен другой комбайнер, так как для 'cbind' потребуется такое же количество строк. – r2evans
Благодарим за отзыв. – KDA
Спасибо за ваш ответ. ImpOOBerr() должен создавать матрицы одного размера и, если я исключаю часть скрипта, которая принимает произвольные выборки cols (т. Е. Часть между строками «#xxxx»). Мое намерение в произвольном выборе столбцов состояло в том, чтобы выбрать одинаковое количество столбцов в каждом отдельном прогоне. Поскольку #col selected задает матрицу #rows в выходной строке, каждый запуск должен создавать матрицу того же размера. Но, поскольку это случайная выборка, выбранные отдельные столбцы будут различаться в разных сериях. Является ли ошибка, потому что row.names для матриц, объединяемых ImpOOBerr, различны для каждого прогона? Предложения? – KDA