경험을 비추어봤을때, R에서 LASSO를 application 시킬때는 난수 선택에서 생기는 난감한 점들이 존재합니다. 


1. 교차검정의 한계 : 최적의 shrinkage value(lambda)를 찾기위해 사용되는 cross-validation의 결과값이 그때 그때 다름.

2. 트레이닝셋 / 테스트셋 분류 할때 난수가 다름


그래서 주로 seed값을 정해두고 결과를 고정시키는것이 좋다고들 하죠. 하지만, 이 결과 또한 안정적으로 추정되었는지에 대한 의문이 생길때가 있습니다.


저는 bootstrap을 적용해 계수의 안정성을 도모해봤습니다.

1. LASSO with Bootstrap

최근에는 LASSO와 Bootstrap을 함께 사용할 수 있는 패키지까지 개발되었다고 합니다. 하지만, 기존에 있는 boot package와 glmnet package로도 얼마든지 구현할 수 있습니다.


library(glmnet)
library(boot)

set.seed(1000)
train = sample(1:nrow(dataSet), nrow(dataSet)*0.8)
test = -train

lasso = function(data, indices) {

	dx = model.matrix(dependent1 ~ . , data[indices,])[,-1]
	dy = data$dependent1[indices]
	cv.lasso = cv.glmnet(dx, dy, alpha=1)
	lasso.coef = predict(cv.lasso, type = "coefficients", s=cv.lasso$lambda.min)
	return(as.numeric(lasso.coef))
}

lasso.boot = boot(data = dataSet[train,], statistic = lasso, R=1000)
lasso.origin = lasso.boot$t0
lasso.mean = apply(lasso.boot$t,2,mean)
lasso.mean[which(lasso.origin==0)] = 0


seed값을 1000으로 고정해 난수를 통제한 뒤, Boot 패키지로 LASSO 모형을 1,000번 반복시키는 과정입니다. 부트스트랩 결과 LASSO 모형의 계수를 모두 추정할 수 있었고, 그에 대한 bias와 standard error를 도출할 수 있었습니다.



bias는 "original - 부트스트랩 평균"을 나타내며 standard error를 통해 original 계수의 신뢰구간을 형성할 수 있습니다.


2. 문제점...


일반적으로 추정량(평균 등) 에 대한 부트스트랩은 그에 대한 해석이 깔끔합니다. 왜냐하면 LASSO처럼 변수선택에 대한 부분이 고려되지 않기 때문이죠. 저 역시 이에대한 고민이 많이 있었습니다. 

부트스트랩 평균을 활용 하기 위해서 bias + original 의 결과를 사용한다면, 변수선택의 의미가 퇴색되기 때문이지요.

이 부분에서 논란이 있을 수 있겠다만은, 저는 original로 선택된 변수만 활용하기로 했습니다. 즉, lasso.mean[which(lasso.origin==0)] = 0 의 코드를 통해서, 나름대로 문제점을 해결했습니다.



3. 마치며...


정교한 모델링은 언제나 많은 고민과 학습의 과정을 요합니다. 부트스트랩은 그 정교함에 날을 세워줄 수 있는 강력한 방법임에 틀림없지만, 적용방법과 해석방법에 따라 강력한 무기가 될수도 있고 그렇지 않을 수도 있을듯 합니다.


저작자 표시 비영리
신고

티스토리 툴바