Распараллелить г скрипт - PullRequest
       13

Распараллелить г скрипт

0 голосов
/ 18 сентября 2018

Для начала, у меня есть элементарное знакомство с doparallel и параллельными пакетами в R, поэтому, пожалуйста, воздержитесь от предложения этих пакетов без примера кода.

В настоящее время я работаю с регрессионными моделями LASSO, сгенерированными с использованием пакета glmnet.Я полагаюсь на функцию cv.glmnet в этих пакетах, чтобы сказать мне, какова идеальная лямда ... все это барахло не относится к моему актуальному вопросу, но я надеюсь, что история поможет.Функция cv.glmnet делает то, что я хочу, но занимает слишком много времени.Я хочу распараллелить его.

Моя проблема заключается в том, что параллельные r-пакеты предназначены для получения списка, а затем применяют к этому списку операцию, поэтому при попытке передать полированную функцию, такую ​​как cv.glmnet (дажехотя это итеративно), я получаю одно ядро, обрабатывающее один набор данных, который я хочу обработать cv.glmnet, а не этот процесс распределяется по всем ядрам на моем сервере.

Можно ли распределить одно вычисление по нескольким процессорам / ядрам в r (какие пакеты, пример кода и т. Д.)?Или можно ли сделать распараллеливающие пакеты, такие как параллельные и допараллельные, распознать итеративную структуру функции cv.glmnet и затем распространить ее для меня?Я ловлю на рекомендации, любая помощь или понимание будут с благодарностью.

К сожалению, у меня нет разрешения на передачу данных, с которыми я работаю.Воспроизводимый пример см. В этом посте. Код ответа - качество копирования / вставки для генерации данных, регрессия лассо и пример использования функции cv.glmnet: https://stats.stackexchange.com/questions/72251/an-example-lasso-regression-using-glmnet-for-binary-outcome

Ответы [ 2 ]

0 голосов
/ 18 сентября 2018

Для меня это очень простое решение сработало:

Добавьте это перед вашей функцией. Здесь будьте осторожны, если вы включите это в функцию, у меня почти всегда заканчивается ОЗУ (и у меня 32 ГБ ОЗУ). Если я оберну его вокруг всего сценария, он будет работать нормально.

 library(doParallel)
 cl <- makeCluster(detectCores(), type='PSOCK')
 registerDoParallel(cl)
 # some function
 registerDoParallel()

Другой способ:

 library(doParallel)
 cores=detectCores()
 cl <- makeCluster(cores[1])

Затем измените вашу функцию применения на parApply

 parApply(cl,data,2,function(x){#your function})
0 голосов
/ 18 сентября 2018

cv.glmnet легко распараллеливается, задайте параметр параллели = TRUE

Пример того, как это сделать, можно найти в документации

https://www.rdocumentation.org/packages/glmnet/versions/2.0-16/topics/cv.glmnet

ЭтоВ примере используется doMC, но вы можете легко изменить его на параллельный пакет

require(doMC)
registerDoMC(cores=4)
x = matrix(rnorm(1e5 * 100), 1e5, 100)
y = rnorm(1e5)
system.time(cv.glmnet(x,y))                # not parallel
system.time(cv.glmnet(x,y,parallel=TRUE))  # this is parallel

параллельная версия будет выглядеть так:

library(doParallel)
library(glmnet)
no_cores <- detectCores() - 1
print(no_cores)
# Initiate cluster
cl <- makeCluster(no_cores)
registerDoParallel(cl)

x = matrix(rnorm(1e5 * 100), 1e5, 100)
y = rnorm(1e5)
system.time(cv.glmnet(x,y))                # not parallel
system.time(cv.glmnet(x,y,parallel=TRUE))  # this is parallel
stopCluster(cl)

Чтобы добавить к вашему вопросу есть категорияиз проблем, называемых «смущающей параллелью», которые можно тривиально распараллелить, эти пакеты чаще всего используют цикл foreach, так что код внутри этих циклов может быть распараллелен.Таким образом, все, что необходимо для этого случая, это включить параллелизацию (зарегистрировать параллельный бэкэнд), и цикл foreach будет выполняться параллельно.

...