2016-09-16 10 views
7

Я хочу распараллелить процесс подгонки модели для xgboost при использовании каретки. Из того, что я видел в xgboost's documentation, параметр nthread управляет количеством потоков, используемых при установке моделей, в смысле создания параллельных деревьев. Функция Caret's train будет выполнять распараллеливание в смысле, например, выполнения процесса для каждой итерации в k-кратном CV. Является ли это понимание правильно, если да, то лучше:Параллельная обработка с помощью xgboost и каретки

  1. Зарегистрируйте число ядер (например, с doMC пакета и функции registerDoMC), установите nthread=1 с помощью функции поезда CARET так, чтобы он передает этот параметр xgboost, установите allowParallel=TRUE в trainControl, и пусть caret обрабатывает распараллеливание для перекрестной проверки; или
  2. Отключить каретную распараллеливание (allowParallel=FALSE и отсутствие параллельной регистрации на заднем плане) и установить nthread на количество физических ядер, поэтому распараллеливание содержится исключительно в xgboost.

Или нет «лучшего» способа выполнения распараллеливания?

Edit: Я побежал код, предложенный @topepo, с tuneLength = 10 и search="random", и указав nthread=1 на последней строке (в противном случае я понимаю, что xgboost будет использовать многопоточность). Есть результаты, которые я получил:

xgb_par[3] 
elapsed 
283.691 
just_seq[3] 
elapsed 
276.704 
mc_par[3] 
elapsed 
89.074 
just_seq[3]/mc_par[3] 
elapsed 
3.106451 
just_seq[3]/xgb_par[3] 
elapsed 
0.9753711 
xgb_par[3]/mc_par[3] 
elapsed 
3.184891 

В конце концов, оказалось, что и для моих данных и для этого теста, выпускающего кареткой обрабатывать распараллеливание был лучшим выбором с точки зрения выполнения.

+1

Избежание тот факт, что перекрестная проверка не является «подгонки модели», нет никаких причин, эти параметры должны быть взаимоисключающими. Независимо от того, вопрос основан на мнениях, и я голосую, чтобы закрыть. Вы не определили «лучше»; но, я полагаю, вы имеете в виду меньше времени выполнения ... Вы всегда можете профилировать свой код. Для этого я предлагаю 'library (microbenchmark). –

+0

Возможно, есть недоразумение в терминологии. Конечно, конечной целью кросс-валидации является проверка модели, но то, что я подразумевал под «подгонкой модели», заключается в том, что на каждой итерации вам нужно подгонять модель по сложениям (k-1). Причина этого вопроса заключается в том, что я не знаю, по строительству, есть теоретически лучший способ сделать распараллеливание (например, может быть больше накладных расходов при росте большего количества потоков на итерацию, чем распараллеливание цикла повторной выборки), и было интересно, если кто-то более опытный мог бы посоветовать в этом. Но это правда, что это может быть зависимым от случая. – drgxfs

ответ

6

Непросто спроектировать, какой будет лучшая стратегия. Моя (предвзятая) мысль заключается в том, что вы должны распараллелить процесс, который занимает самое большое время. Здесь это будет цикл передискретизации, так как открытый поток/работник будет многократно ссылаться на эту модель. Противоположный подход к распараллеливанию подгонки модели начнется и перестанет работать многократно и теоретически замедлит работу. Ваш пробег может отличаться.

У меня нет OpenMP, но есть код ниже, чтобы проверить (если бы вы могли сообщить о своих результатах, это было бы полезно).

library(caret) 
library(plyr) 
library(xgboost) 
library(doMC) 

foo <- function(...) { 
    set.seed(2) 
    mod <- train(Class ~ ., data = dat, 
       method = "xgbTree", tuneLength = 50, 
       ..., trControl = trainControl(search = "random")) 
    invisible(mod) 
} 

set.seed(1) 
dat <- twoClassSim(1000) 

just_seq <- system.time(foo()) 


## I don't have OpenMP installed 
xgb_par <- system.time(foo(nthread = 5)) 

registerDoMC(cores=5) 
mc_par <- system.time(foo()) 

Мои результаты (без OpenMP)

> just_seq[3] 
elapsed 
326.422 
> xgb_par[3] 
elapsed 
319.862 
> mc_par[3] 
elapsed 
102.329 
> 
> ## Speedups 
> xgb_par[3]/mc_par[3] 
elapsed 
3.12582 
> just_seq[3]/mc_par[3] 
elapsed 
3.189927 
> just_seq[3]/xgb_par[3] 
elapsed 
1.020509