2013-04-30 3 views
4

Je crois comprendre que glmnet utilise des matrices où chaque colonne est une variable explicative.Estimation de nombreux termes d'interaction dans glmnet

J'ai un dataframe avec ~ 10 variables explicatives (dont certains sont des facteurs)

Comment pourrais-je prendre une formule telle que y ~ (x1 * x2 * x3) + (x4 * x5) + x6 et estimer cela en utilisant glmnet? Je crois que je devrais créer une matrice où chaque terme d'interaction a sa propre colonne, mais je ne sais pas comment prendre simplement les entrées la formule et les variables (dont certaines sont des facteurs) et obtenir la sortie une matrice I peut facilement mettre dans glmnet.

+3

Je pense que vous recherchez '? model.matrix' ... –

+0

merci Ben,? model.matrix est exactement ce dont j'avais besoin: P –

Répondre

11

Supposons que vous souhaitez un modèle de la forme y = b0 + b1*x1*x2 + b2*x3 + noise, où la variable cible y et toutes les variables explicatives x1, x2, x3 sont stockées dans la même trame de données. ...

Modifier: Merci @BenBolker pour l'indice à model.matrix.

En utilisant model.matrix le code suivant fournit une solution:

library(glmnet) 

# the original data frame and formula 
set.seed(23) 
dat <- data.frame(y=runif(5), x1=runif(5), x2=runif(5), x3=runif(5)) 
f <- as.formula(y~x1:x2+x3+0) 
# no intercept here ('+0') because glmnet adds intercept by default 

# transform dataframe to matrices as required by glmnet 
x <- model.matrix(f, dat) 
y <- as.matrix(dat$y, ncol=1) 

# fit glmnet model with penalty parameter 0.001 
g <- glmnet(x, y, lambda=0.001) 
print(coef(g)) 
# 3 x 1 sparse Matrix of class "dgCMatrix" 
#     s0 
# (Intercept) 0.3506450 
# x3   0.2308045 
# x1:x2  0.1016138 

seulement pour être complet, voici ma réponse originale sans utiliser model.matrix, ce qui nécessite un peu d'intervention manuelle:

library(glmnet) 

# the original data frame 
set.seed(23) 
dat <- data.frame(y=runif(5), x1=runif(5), x2=runif(5), x3=runif(5)) 

# transform dataframe to matrices as required by glmnet 
x <- with(dat, as.matrix(cbind("x1*x2"=x1*x2, "x3"=x3))) 
y <- with(dat, as.matrix(y, ncol=1)) 

# fit glmnet model with penalty parameter 0.001 
g <- glmnet(x, y, lambda=0.001) 
print(coef(g)) 
# 3 x 1 sparse Matrix of class "dgCMatrix" 
#     s0 
# (Intercept) 0.3506450 
# x1*x2  0.1016137 
# x3   0.2308045 
+0

Vous incluez le '(Intercept)' deux fois de cette façon dans le modèle. Ajoutez une non-interception à la formule ('... + 0'). Évitez également 'df' comme nom d'objet (c'est une fonction de base). Sinon, bonne réponse. –

+0

@ catastrophique-échec Merci, tout est fait. – sieste