Использование foreach для множественной оптимизации - PullRequest
0 голосов
/ 05 мая 2020

Итак, я пишу код на R и хочу распараллелить процедуру ограниченной оптимизации. Моя функция - это простая линейная регрессия, оцененная с помощью MLE. У параметров есть некоторые ограничения, поэтому constrOptim () - это оптимизатор общего назначения, который я использовал. Я не хочу использовать пакет optimParallel, поскольку мне придется проделать то же самое, что и с простой регрессией, с гораздо более сложной функцией, для которой я не могу предоставить градиент. То, что я делаю, можно рассматривать как регрессию скользящего окна с окном из 3000 ежедневных точек и +1 каждый раз, когда окно перемещается. Я хотел бы сделать сразу несколько оценок. По разным причинам я не могу использовать готовые пакеты для этой работы, так как мой профессор хотел бы, чтобы я делал это вручную.

#declare the constraints and the initial parameters for the optimization
constrain_matrix_olsgarch <- matrix(data = c(
                                             0,0,0,0,1,0,0,
                                             0,0,0,0,0,1,0,
                                             0,0,0,0,0,0,1,
                                             0,0,0,0,0,-1,-1),
                                             nrow=4, ncol=7, byrow = T)

constrain_vec_olsgarch <- c(0,0,0,-1)
start_params <- c(0.1,0.1,0.1,0.1,0.1,0.1,0.1)

#detect cores and start the backend
cores <- detectCores(logical = T)
cl <- makeCluster(cores)
registerDoParallel(cl, cores=cores)

#create a 3D array with the data needed for the regression as input for the function
#y_multivariate would be a 3000x4 matrix containing the observations for (y,x1,x2,x3)

data_test<- array(NA,dim = c(3000,4,8))
for (i in 1:8) {data_test[,,i] <- y_multivariate[(1+i):(3000+i),]}

#run the parallel version of the for cycle and save results, the output is a list of lists, which are the results of each estimation.
results_par <-foreach(i=1:8) %dopar% 
            {
                constrOptim(theta = start_params, f = MaxLikelihood_olsgarch,
                                    ui = constrain_matrix_olsgarch,
                                    ci = constrain_vec_olsgarch, 
                                    method = "Nelder-Mead",
                                    data = data_test[,,i],
                                    control = list(maxit = 1500,
                                    fnscale = 1))
}

В идеале, это код, который я хотел бы распараллелить:

alternative <- for(i in 1:8)
{
constrOptim(theta = start_params, f = MaxLikelihood_olsgarch,
            ui = constrain_matrix_olsgarch,
            ci = constrain_vec_olsgarch, 
            method = "Nelder-Mead",
            data = data_test[,,i],
            control = list(maxit = 1500,

                           fnscale = 1)) 
}

стоит отметить, что результаты вычисляются правильно и в обоих случаях ошибки не возвращаются. Дело в том, что параллельный подход намного медленнее, чем обычный цикл for (), чего не должно быть. Я также должен сказать, что у меня нет опыта работы с распараллеливанием и, возможно, я сделал что-то не так или пропустил важный шаг. Использование ЦП моего p c подскакивает до 100% при выполнении вычислений в параллельном режиме: это дает мне уверенность, что я, по крайней мере, что-то сделал правильно, но я не знаю, почему происходит замедление вычислений.

#system.tyme() of the normal for() cycle
   user  system elapsed 
 302.06    0.20  302.20 

system.time() of the foreach() cycle
user  system elapsed 
   0.39    0.28  565.56
...