我有一个包含1000个观测值和76个变量的数据集,其中大约20个是绝对的。我想在整个数据集上使用LASSO。我知道有因子变量在LASSO中通过lars或glmnet确实不起作用,但是变量太多而且有太多不同的,无序的值它们可以用来合理地重新编码它们。
可以在这种情况下使用LASSO吗?我该怎么做呢?创建预测变量矩阵会产生此响应:
hdy<-as.numeric(housingData2[,75])
hdx<-as.matrix(housingData2[,-75])
model.lasso <- lars(hdx, hdy)
Error in one %*% x : requires numeric/complex matrix/vector arguments
我意识到其他方法可能更容易或更合适,但挑战实际上是使用lars或glmnet来做到这一点,所以如果可能的话,我会很感激任何想法或反馈。
谢谢,
答案 0 :(得分:1)
您可以使用model.matrix
从您的因子中创建虚拟变量。
我创建了一个data.frame。 y是目标变量。
create_factor <- function(nb_lvl, n= 100 ){
factor(sample(letters[1:nb_lvl],n, replace = TRUE))}
df <- data.frame(var1 = create_factor(5),
var2 = create_factor(5),
var3 = create_factor(5),
var4 = create_factor(5),
var5 = rnorm(100),
y = create_factor(2))
# var1 var2 var3 var4 var5 y
# 1 a c c b -0.58655607 b
# 2 d a e a 0.52151994 a
# 3 a b d a -0.04792142 b
# 4 d a a d -0.41754957 b
# 5 a d e e -0.29887004 a
选择所有因子变量。我使用dplyr::select_if
然后解析
变量名称以获得类似y ~ var1 + var2 +var3 +var4
library(dplyr)
library(stringr)
library(glmnet)
vars_name <- df %>%
select(-y) %>%
select_if(is.factor) %>%
colnames() %>%
str_c(collapse = "+")
model_string <- paste("y ~",vars_name )
使用model.matrix
创建虚拟变量。不要忘记as.formula
强迫角色配方。
x_train <- model.matrix(as.formula(model_string), df)
适合你的模特。
lasso_model <- cv.glmnet(x=x_train,y = df$y, family = "binomial", alpha=1, nfolds=10)
代码可以简化。但这个想法就在这里。
答案 1 :(得分:1)
这里的其他答案指出了将类别因素重新编码为虚拟变量的方法。根据您的应用程序,它可能不是一个很好的解决方案。如果您只关心预测,那么可能很好,并且Flo.P提供的方法应该可以。 LASSO将为您找到一组有用的变量,并且您可能不会过拟合。
但是,如果您有兴趣解释模型或在事后讨论哪些因素很重要,那么您的位置就很奇怪。单独使用时,model.matrix的默认编码具有非常特定的解释。 model.matrix使用所谓的“虚拟编码”。 (我记得它是作为“参考编码”学习的;有关摘要,请参见here。)这意味着,如果包含了这些虚拟变量中的一个,则您的模型现在具有一个参数,其解释为“因子和该因子的任意选择的其他级别”。也许没有其他人选择该因素。您可能还会发现,如果因子水平的顺序发生变化,则最终会得到不同的模型。
有很多方法可以解决这个问题,但是我不想尝试将某些东西放在一起,而是尝试使用套索。以上面的Flo.P代码为基础:
install.packages("gglasso")
library(gglasso)
create_factor <- function(nb_lvl, n= 100 ){
factor(sample(letters[1:nb_lvl],n, replace = TRUE))}
df <- data.frame(var1 = create_factor(5),
var2 = create_factor(5),
var3 = create_factor(5),
var4 = create_factor(5),
var5 = rnorm(100),
y = rnorm(100))
y <- df$y
x <- model.matrix( ~ ., dplyr::select(df, -y))[, -1]
groups <- c(rep(1:4, each = 4), 5)
fit <- gglasso(x = x, y = y, group = groups, lambda = 1)
fit$beta
因此,由于我们未指定因子(var1,var2等)与y之间的关系,因此LASSO可以很好地完成工作并将所有系数设置为0,除非应用了最小化的正则化量。您可以尝试使用lambda值(调整参数),也可以将选项保留为空白,该函数将为您选择一个范围。