2013-09-20 4 views
2

У меня есть проблема с запуском randomForest в parrallel с использованием fore each. См. Этот пример, я создаю некоторые данные, а затем формулу. Формула работает на randomForest сама по себе. Но не получается, когда используется в петле forrack parrallel ...?Ошибка R foreach при использовании обозначения формул в randomForest

# rf on big training set 
# use parallel foreach 
library(foreach) 

library(doMC) 
registerDoMC(4) #change the 2 to your number of CPU cores 
# info on parrallell backend 
getDoParName() 
getDoParWorkers() 

# bogus data 
set.seed(123) 
ssize <- 100000 
x1 <- sample(LETTERS[1:9], ssize, replace=TRUE, prob=c(0.1, 0.2, 0.15, 0.05,0.1, 0.2, 0.05, 0.05,0.1)) 
x2 <- rlnorm(ssize,0,0.25) 
x3 <- rlnorm(ssize,0,0.5) 
y <- sample(c("Y","N"), ssize, replace=TRUE, prob=c(0.05, 0.95)) 
df <- data.frame(x1,x2,x3,y) 
df$p_y <- as.numeric(df$y)-1 

# use strata to sample whole dataset 
library(sampling) 

s1 = strata(df,stratanames = "y", size = c(2500,2500)) 
s2 = strata(df,stratanames = "y", size = c(2500,2500)) 
s3 = strata(df,stratanames = "y", size = c(2500,2500)) 
s4 = strata(df,stratanames = "y", size = c(2500,2500)) 

s_list <- list(s1$ID_unit, s2$ID_unit, s3$ID_unit, s4$ID_unit) 

# model function 
rf.formula <- as.formula(paste("y","~",paste("x1","x2",sep="+"))) 

library(randomForest) 

# simple stuff works but takes some time 
model.rf <-randomForest(y ~ x1 + x2, df, ntree=100, nodesize = 50) 

# build rf with dopar on explicit formula works and is quick 
model.rf.dopar <- foreach(subset=s_list, .combine=combine, .packages='randomForest') %dopar% 
    randomForest(y ~ x1 + x2, df, ntree=100, nodesize = 50, subset=subset) 

# build rf with dopar on rf.formula fails 
model.rf.s.b2 <- foreach(subset=s_list, .combine=combine, .packages='randomForest') %dopar% 
    randomForest(rf.formula, df, ntree=100, nodesize = 50, subset=subset) 

# > model.rf.s.b2 <- foreach(subset=s_list, .combine=combine, .packages='randomForest') %dopar% 
# + randomForest(rf.formula, df, ntree=100, nodesize = 50, subset=subset) 
# Error in randomForest(rf.formula, df, ntree = 100, nodesize = 50, subset = subset) : 
# task 1 failed - "invalid subscript type 'closure'" 

Ошибка:

model.rf.s.b2 <- foreach(subset=s_list, .combine=combine, .packages='randomForest') %dopar% 
    + randomForest(rf.formula, df, ntree=100, nodesize = 50, subset=subset) 

Error in randomForest(rf.formula, df, ntree = 100, nodesize = 50, subset = subset) : 
task 1 failed - "invalid subscript type 'closure'" 

Любые предложения?

Tx

+0

Что-то не так с вашим подмножеством. Попробуйте добавить 'print (subset)' или что-то вдоль этих строк в цикле 'foreach', чтобы узнать, находится ли он в том формате, который вы ожидаете. –

ответ

2

Проблема, как представляется, в связи с операцией индексации происходит не так глубоко в функции model.frame.default, которая косвенно наречено randomForest.formula. Я не уверен, что запуск этой проблемы, потому что есть много хитрого Evals происходит в model.frame.default, но изменяя окружение формулы, кажется, решить эту проблему:

r <- foreach(subset=s_list, .combine='combine', .multicombine=TRUE, 
      .packages='randomForest') %dopar% { 
    environment(rf.formula) <- environment() 
    randomForest(rf.formula, df, ntree=100, nodesize = 50, subset=subset) 
} 

В частности, это приводит к subset для оценки корректно, в противном случае он вычисляет функцию subset. Я попытался переименовать переменную итерации, но это не помогло.

Обратите внимание, что я также установил .multicombine в TRUE, так как функция randomForest combine принимает несколько объектов и может значительно повысить производительность.

Update

Проблема может быть воспроизведена с:

fun <- function(subset) { 
    randomForest(rf.formula, df, ntree=100, nodesize = 50, subset=subset) 
} 
fun(s_list[[1]]) 

Если переменная subset изменяется на s, например, это также не удается, но с сообщением менее недостоверной ошибки:

> fun <- function(s) { 
> randomForest(rf.formula, df, ntree=100, nodesize = 50, subset=s) 
> } 
> fun(s_list[[1]]) 
Error in eval(expr, envir, enclos) : object 's' not found 
Calls: fun ... eval -> model.frame -> model.frame.default -> eval -> eval 
Execution halted 

Как с примером foreach, сброс Похоже, что окружающая среда формулы работает вокруг проблемы.

+0

Отличный ответ, спасибо. Хотя это обходной путь, он работает для меня. –