2 min read

Group Lasso

importing data

happy data는 서울 주민 가구원 행복도 조사 데이터로, Target variable은 Q48로 개인의 행복도를 나타낸다.

library(readr)
library(tidyverse)
happy <- read_csv("https://raw.githubusercontent.com/YonseiESC/ESC-20SPRING/master/%ED%8C%8C%EC%9D%B4%EB%84%90%20%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8/6%EC%A1%B0/data/Seoul_Happiness_2014_train_dummies_06032141.csv")
happy <- happy %>% 
  dplyr::select(Q4B, everything(), -X1)
dim(happy)
## [1] 31848   180

outlier 처리

선형회귀를 통해 target에서 residual이 높은 행을 제거했다. 참고 이후, target의 skewness를 줄이기 위해 제곱변환을 실시하고, target의 정보를 저장했다.

linmodel = lm(Q4B~.,happy) #basic linear model
studresid = rstandard(linmodel)


happy = happy[-which(abs(studresid)>3),] 
dim(happy)
## [1] 31476   180

mn = mean(happy$Q4B^2)
sd = sd(happy$Q4B^2)
happy$Q4B = happy$Q4B^2

Group Lasso model

Lasso model은 더미변수가 하나의 범주형에서 왔다는 사실을 고려하지 않는다. 따라서, group lasso를 통해 이 점을 보완한 model을 사용했다.

generate list

group lasso에서는 modeling을 위해 data를 list 형식으로 바꾸는 것이 편리하다.

happy = scale(happy)

nominal_list=c('HTYP','HLIV','RLI','Q1','Q2B','Q14A1','Q17A1','Q17A2','Q18','Q21A','Q25A1','Q26','Q31A1','Q39','Q44','Q47C','DE1','DE6','DE9')

group_col <- colnames(happy)[-1]
group_col <- str_split_fixed(group_col, "_", n =2)[,1]

happy_list <- list(X = as.matrix(happy[,-1]), 
                   Y = happy[,1], 
                   group = factor(group_col))

X <- happy_list$X
y <- happy_list$Y
group <- happy_list$group

cross-validation

group lasso에서도 gel(group exponential lasso)기법을 이용하여 cross validation을 하여 최적의 parameter을 찾아냈다.

library(grpreg)

cvfit <- cv.grpreg(X, y, group, penalty="gel")
plot(cvfit)

summary(cvfit)
## gel-penalized linear regression with n=31476, p=179
## At minimum cross-validation error (lambda=0.0001):
## -------------------------------------------------
##   Nonzero coefficients: 179
##   Nonzero groups: 97
##   Cross-validation error of 0.63
##   Maximum R-squared: 0.37
##   Maximum signal-to-noise ratio: 0.58
##   Scale estimate (sigma) at lambda.min: 0.796

calculate MSE

predict(cvfit, X, type="link")[1:20]
##  [1] -0.23653584  0.01161311  0.11580404  0.27915286 -0.15381748 -0.01617231
##  [7] -0.87905521 -0.04353528  0.17534470  0.05915935 -0.13230062 -0.32136765
## [13]  0.47868006  0.74251972  0.36152241 -0.05428723 -0.12275725  0.03647137
## [19]  1.05679567  0.62272234

test_vars <- predict(cvfit, type="vars")

y_hat <- sqrt(predict(cvfit, X, type="link")*sd + mn)
y_real <-  sqrt(y * sd + mn)
MSE_lasso = mean((y_hat- y_real)^2) ; MSE_lasso 
## [1] 75.17317

결과적으로 MSE가 75.1731672인 모델을 생성했다.