1

我将glmnet在面板数据集上使用包中的惩罚回归模型。作为面板意味着我将不使用交叉验证而是使用滚动原点来测试模型,因此我不会使用cv.glmnet仅适用于交叉验证的功能。相反,我将使用默认glmnet函数。这个函数有两个参数需要优化,lambdaalphalambda允许为数组,如果是,则为数组中的每个元素拟合一个模型,但alpha必须是标量。我有兴趣为不同的alpha值运行模型。到目前为止,我正在使用 for 循环按顺序执行此操作,如下例所示(在此示例中,BostonHousing为了简单起见,我使用数据集,尽管不是面板数据)

# Load libraries
library(glmnet)
library(mlbench)
library(tidyverse)

# Load dataset
data(BostonHousing)

# Split into train / test
x_train = BostonHousing %>% slice(1:400) %>%  select(-c(medv, chas)) %>% as.matrix()
x_test = BostonHousing %>% slice(401:n()) %>% select(-c(medv, chas)) %>% as.matrix()

y_train = BostonHousing %>%  slice(1:400) %>%  select(medv) %>% as.matrix()
y_test = BostonHousing %>%  slice(401:n()) %>%  select(medv) %>% as.matrix()

# Define grid for parameters
lambda_param = 10^seq(-3, 1, by=0.5)
alpha_param = seq(0, 1, 0.1)

# Sequential approach
mse_sequential = matrix(NA,length(lambda_param), length(alpha_param))
for(i in seq_along(alpha_param))
{
  fit_seq = glmnet(x=x_train, y=y_train, family='gaussian', lambda=lambda_param, alpha=alpha_param[i])
  p = predict(fit_seq, newx=x_test)
  mse_sequential[,i] = map_dbl(seq_along(lambda_param), function(j){mean((p[,j]-y_test)^2)})
}

这种方法有效,但对我来说似乎效率很低,我考虑将它并行化。我尝试使用该furrr包(允许并行化purrr功能),但我面临两个问题:

问题 1

以下代码(假定)furrr按顺序运行:

library(furrr)
plan(sequential)
glmnet_alpha = partial(glmnet, x = x_train, y = y_train, family = "gaussian", weights = rep(1, nrow(x_train)), lambda=lambda_param)
fit = future_map(alpha_param, glmnet_alpha)

但是使用 for 循环实现的解决方案与使用furrr. 例如,查看 和 的lambda=10系数alpha=0

fit_seq = glmnet(x=x_train, y=y_train, family='gaussian', lambda=10, alpha=0)
as.vector(fit_seq$beta)
as.vector(fit[[1]]$beta[,1])

问题 2

如果我尝试furrr并行运行,我会收到一条错误消息:

plan(multiprocess)
glmnet_alpha = partial(glmnet, x = x_train, y = y_train, family = "gaussian", weights = rep(1, nrow(x_train)), lambda=lambda_param)
fit = future_map(alpha_param, glmnet_alpha)

Error in drop(y) : objeto 'y_train' no encontrado

因此,任何帮助理解这里发生的事情,或提供并行运行它的替代方法将不胜感激。

4

0 回答 0