web-dev-qa-db-ja.com

カテゴリー変数を使用したRでのLASSOの使用

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を使用してこれを行うことが課題であるため、可能であれば、アイデアやフィードバックをいただければ幸いです。

ありがとうございました、

7
Alex

ここでの他の回答は、カテゴリー要素をダミーとして再コード化する方法を指摘しています。アプリケーションによっては、優れたソリューションではない場合があります。あなたが気にしているのが予測だけであれば、おそらくこれで問題ありません。Flo.Pが提供するアプローチは大丈夫です。 LASSOは、便利な変数のセットを見つけます。おそらく、やりすぎにはなりません。

ただし、モデルを解釈したり、事後に重要な要素について議論したりすることに興味がある場合は、奇妙なことに直面しています。 model.matrixのデフォルトのコーディングは、単独で解釈すると非常に特殊な解釈をしています。 model.matrixは、「ダミーコーディング」と呼ばれるものを使用します。 (私はそれを「参照コーディング」として学んだことを覚えています。要約については ここ を参照してください。)つまり、これらのダミーの1つが含まれている場合、モデルには、「1とこの因子のレベルおよびその因子の任意に選択された他のレベル」。そして、おそらくその要因の他のダミーはどれも選択されませんでした。また、因子レベルの順序が変更されると、異なるモデルになる可能性があります。

これに対処する方法はいくつかありますが、何かをまとめるのではなく、グループなげなわで試します。上記の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に設定します。ラムダ(調整パラメーター)の値をいじったり、オプションを空白のままにしておくと、関数が範囲を選択します。

3
mavery

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
Flo.P