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

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

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

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

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

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


person Phil_T    schedule 18.09.2018    source источник


Ответы (1)


cv.glmnet легко распараллеливается, установите параметр parallel = 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 будет выполняться параллельно.

person Carlos Santillan    schedule 18.09.2018
comment
НИ ЗА ЧТО?!!! Он встроен?! Я так счастлив, и мне так стыдно. Я попробую это, когда вернусь домой. - person Phil_T; 18.09.2018
comment
Просто гениально. Доля исходного времени. - person Phil_T; 19.09.2018