【问题标题】:Using LASSO in R with categorical variables在 R 中将 LASSO 与分类变量一起使用
【发布时间】:2018-04-02 14:43:02
【问题描述】:

我有一个包含 1000 个观察值和 76 个变量的数据集,其中大约 20 个是分类变量。我想在整个数据集上使用 LASSO。我知道通过 lars 或 glmnet 在 LASSO 中使用因子变量并不能真正起作用,但是变量太多了,并且它们可以采用太多不同的无序值来合理地对它们进行数字重新编码。

在这种情况下可以使用 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 来做到这一点,所以如果可能的话,我将不胜感激任何想法或反馈。

谢谢,

【问题讨论】:

  • 使用model.matrix 创建您的预测矩阵,它将使用虚拟变量重新编码您的因子变量。您可能还想查看组套索
  • 所以,使用 hdx
  • 到目前为止很好,但我们需要一个可重现的示例来帮助您更进一步。在下面的示例中使用lars(x=x_train,y=df$var5) 似乎可以正常工作。您的输入数据中有NA 值吗?
  • 是的,有很多 NA。当我使用 Flo.P 所做的(顺便谢谢你,这完全有道理)并使其适应我的数据时,我得到了错误:glmnet 中的错误(x,y,权重 = 权重,偏移 = 偏移,lambda = lambda, : y (1000) 中的观察数不等于 x (0) 的行数,当我执行 lars(x=x_train,y=housingData2$SalePrice) 时,我得到相同的 TRUE/FALSE 错误。
  • Flo.P 的方法最适合进一步阅读,请参阅:users.stat.umn.edu/~zouxx019/Papers/gglasso-paper.pdf 澄清一下,输入给 gglasso 的“组”变量中的组变量是指虚拟变量组。例如。哪些虚拟变量组曾经是单个变量。这很重要,因为如果其他虚拟变量不重要,那么在模型中包含一个虚拟变量是没有意义的。

标签: r regression glmnet lasso-regression lars


【解决方案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(一个调整参数)的值,或者将选项留空,该函数将为您选择一个范围。

【讨论】:

    【解决方案2】:

    您可以使用 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)
    

    代码可以简化。但想法就在这里。

    【讨论】:

    • 所以这一切都有效,直到最后一部分。当我这样做时,我得到错误“glmnet中的错误(x,y,权重=权重,偏移=偏移,lambda = lambda,:y(1000)中的观察数不等于x的行数(0 )" 这在我看来是有道理的,因为 x_train 似乎是一个 num[0,1:128] 的矩阵。对吗?
    • 好的,所以您的所有行都至少有一个 NA。您需要通过估算缺失值来处理它们。也许您有一些可以删除的包含很多 NA' 的列。当您有一个包含足够完整行的数据集时,它可以使用:lasso_model &lt;- cv.glmnet(x=x_train,y = na.omit(df$y), family = "binomial", alpha=1, nfolds=10)(我添加了na.omit df$y)
    猜你喜欢
    • 2010-11-13
    • 1970-01-01
    • 2020-06-17
    • 1970-01-01
    • 1970-01-01
    • 2014-09-05
    • 2011-09-16
    • 1970-01-01
    • 2019-02-13
    相关资源
    最近更新 更多