Shrinkage Method2(Elastic Net, LARS)

2021. 1. 24. 20:18머신러닝

반응형

앞선 포스팅(direction-f.tistory.com/76)에서 Shrinkage Method로 Ridge Regressio과 Lasso Regression을 다루었습니다.

Ridge Regression같은 경우에는 변수를 선택해주는 모형이라고 보기 어려우나 추정 계수가 Analytics Solution을 가지는 점, 그리고 변수간 상관관계가 있을 때도 상대적으로 잘 작동하는 점에 있어서 장점이 있습니다.

Lasso Regression과 같은 경우에는, Closed form solution을 가지고 있지 않기 때문에 해를 구하는데 상대적으로 큰 Resource가 소요될 수 있고 변수간 상관관계가 높으면 하나의 변수만 채택하고 나머지는 0으로 만들어 버리는 경우가 있어 상관관계가 높은 데이터 셋에 적용하기 어려운 단점이 있으나, 활용가능한 변수를 채택할 수 있다는 장점이 있습니다.

위와 같이 Ridge, Lasso 모두 장단점을 가지고 있다고 볼 수 있습니다. 따라서 Ridge와 Lasso를 모두 한번에 활용하는 Elastic Net이 나오게 됩니다.

[Elastic Net]

Elstic Net의 계수는 아래와 같습니다.

위 식에서 L1과 L2를 동시에 적용한 모습을 확인 할 수 있습니다. 일반적으로 Grid Search로 우리가 목표로하는 측정 Metric을 최적화는 $\lambda_1$과 $\lambda_2$를 결정하여 활용하게 됩니다.

Elastic Net의 Penalty를 나타내면 아래와 같습니다.

2차원에서의 그림으로 표현하면 아래와 같습니다.

https://web.stanford.edu/~hastie/TALKS/enet_talk.pdf

그림에서 Elastic Net의 Penelty는 정확한 원도 아니고 마름모 모양도 아닌 Ridge와 Lasso의 사이에 있다는 것을 확인해볼 수 있습니다.

Python을 Elastic Net을 실습해보겠습니다.

from sklearn.linear_model import Ridge
from sklearn.linear_model import Lasso
from sklearn.linear_model import ElasticNet
from sklearn.datasets import make_regression
import pandas as pd

## Making sample data 
X, y = make_regression(n_samples=1000, n_features=5, n_informative=2, n_targets=1, random_state=1, noise=0.5)
print(X.shape, y.shape)


elastic_net = ElasticNet(alpha = 0.1, l1_ratio = 0.5)
elastic_net.fit(X,y)
elastic_net.coef_
'''array([-0.        , 29.76652443, 68.9069331 ,  0.08349011, -0.        ])'''

sklearn ElastincNet Method의 Parameter alpha와 l1_ratio는 아래와 같이 표현됩니다.

alpha = $\lambda_1$ + $\lambda_2$, l1_ratio =  $\lambda_1$ /( $\lambda_1$+ $\lambda_2$) 

 

[LARS]

위에서 언급한 것과 같이 LASSO는 Closed form의 해를 가지고 있지 않기 때문에 계산할 때 Resource가 많이 소비되는 경우도 있습니다. Least Angle Regression(LARS)는 이러한 LASSO의 계산 측면에서의 단점을 극복하기 위해 활용됩니다.

LARS의 알고리즘은 아래와 같습니다.

1) 모든 계수 $\beta_i$를 0으로 설정합니다.

2) target 변수 y와 가장 correlated된 $x_j$를 찾습니다.

3) $\beta_j$를 y와 $x_j$가 correlation된 방향으로 증가시키면서, Residual $r$ (=$y$-$\widehat{y}$)를 계산하고 어떤 변수 $x_k$가 $x_j$보다 $r$과 correlation이 커지면 $x_k$를 포함시킵니다.

4) ($\beta_j$,$\beta_k$)를 joint least squares 방향으로 증가시키면서, 3)과 같이 Residual을 구하고 Residual과 가장 Correlation이 높은 변수를 포함시킵니다.

5) 모든 변수가 포함될 때까지 계속합니다.

 

위의 알고리즘으로 계수를 추정하면 LASSO로 계수를 추정하는 것과 유사한 Path를 따르게 됩니다.

The Element of Statistical Learning

다만, 계수가 0으로 떨어지게 되면 Path가 달라지게 되는데, 이때는 LARS에서 일단 변수를 제거하고 다시 포함하여 계수를 추정하게 됩니다.

Python에서도 LARS 추정을 위한 패키지를 제공하고 있습니다. LASSO와 한번 비교를 해보겠습니다.

from sklearn.linear_model import Ridge
from sklearn.linear_model import Lasso
from sklearn.linear_model import ElasticNet
from sklearn.linear_model import Lars
from sklearn.datasets import make_regression
import pandas as pd

## Making sample data 
X, y = make_regression(n_samples=1000, n_features=5, n_informative=2, n_targets=1, random_state=1, noise=0.5)
print(X.shape, y.shape)

##LASSO
lasso_reg = Lasso(alpha = 1)
lasso_reg.fit(X,y)
lasso_reg.coef_

'''array([ 0.        , 30.3600565 , 71.62485811,  0.        ,  0.        ])'''

## LARS
Lars_reg = Lars(n_nonzero_coefs=2)
Lars_reg.fit(X,y)
Lars_reg.coef_
'''array([ 0.        , 31.37110492, 72.70696923,  0.        ,  0.        ])'''

Python 결과를 보면 상당히 유사한 결과를 제공해줌을 확인할 수 있습니다.

반응형