#!/usr/bin/env python3


Lasso


Lasso는 linear regression에 regularization을 적용하는 Ridge의 대안으로 사용됩니다.

Ridge와는 coefficient를 0에 가깝게 만들지만 Lasso는 coefficient를 0으로 만듭니다.

이 것을 L2 Regularization이라 합니다.

Lasso는 model을 이해하기 쉬워지고, 이 model의 가장 중요한 특성이 무엇인지 파악하기가 쉽습니다.

Lasso model을 통한 데이터분석은 다음과 같습니다.

from mglearn.datasets import load_extended_boston

from sklearn.model_selection import train_test_split

from sklearn.linear_model import Lasso, Ridge

import numpy as np


boston_data, boston_target = load_extended_boston()


x_train, x_test, y_train, y_test = train_test_split(boston_data, boston_target,

                                                    random_state=0, test_size=0.3)


lasso = Lasso().fit(x_train, y_train)


print('{:.3f}'.format(lasso.score(x_train, y_train)))

# 0.265


print('{:.3f}'.format(lasso.score(x_test, y_test)))

# 0.214


print(lasso.coef_)

# array([-0.        ,  0.        , -0.        ,  0.        , -0.        ,

#         0.        , -0.        ,  0.        , -0.        , -0.        ,

#        -0.        ,  0.        , -4.38009987, -0.        ,  0.        ,

#        -0.        ,  0.        , -0.        , -0.        , -0.        ,

#        -0.        , -0.        , -0.        , -0.        , -0.        ,

#        -0.        ,  0.        ,  0.        ,  0.        ,  0.        ,

#         0.        ,  0.        ,  0.        ,  0.        ,  0.        ,

#         0.        ,  0.        ,  0.        , -0.        ,  0.        ,

#        -0.        , -0.        , -0.        , -0.        , -0.        ,

#        -0.        , -0.        , -0.        , -0.        ,  0.        ,

#         0.        ,  0.        ,  0.        ,  0.        ,  0.        ,

#         0.        ,  0.        ,  0.        ,  0.        , -0.        ,

#        -0.        , -0.        , -0.        , -0.        , -0.        ,

#        -0.        , -0.        , -0.        ,  0.        ,  0.        ,

#         0.        , -0.        , -0.        , -0.        ,  0.        ,

#        -0.        , -0.        ,  0.        , -0.        , -0.        ,

#        -4.39984433, -0.        , -0.        ,  0.        , -0.        ,

#        -0.        , -0.        ,  0.        , -0.        , -0.44131553,

#        -0.        , -0.        , -0.        , -0.        , -0.        ,

#        -0.        , -0.        , -0.        , -0.        , -0.        ,

#        -0.        ,  0.        , -0.        , -0.        ])


print(np.sum(lasso.coef_ != 0))

# 3

Lasso는 train set와 test set 모두 결과가 좋지 않습니다. 즉 underfitting 되었다고 볼 수 있습니다.

105개의 특성중 3개만 사용했음을 알 수 있습니다.



Lasso에서 regularization parameter는 alpha입니다.

alpha를 줄이면 가장 낮은 오차를 찾아가는 반복횟수가 늘어나야 합니다. 따라서 max_iter를 증가시켜야 합니다.

alpha와max_iter값에 따른 Lasso결과를 시각화 해보겠습니다.

import matplotlib.pyplot as plt


alpha_set = [0.0001, 0.01, 1]

max_inter_set = [10000000, 100000, 1000]


train_score = []

test_score = []

used_feature = []


for a, m in zip(alpha_set, max_inter_set):

    lasso = Lasso(alpha=a, max_iter=m).fit(x_train, y_train)

    la_tr_score = round(lasso.score(x_train, y_train), 3)

    la_te_score = round(lasso.score(x_test, y_test), 3)

    number_used = np.sum(lasso.coef_ != 0)


    train_score.append(la_tr_score)

    test_score.append(la_te_score)

    used_feature.append(number_used)


index = np.arange(len(alpha_set))

bar_width = 0.35

plt.bar(index, train_score, width=bar_width, label='train')

plt.bar(index+bar_width, test_score, width=bar_width, label='test')

plt.xticks(index+bar_width/2, alpha_set) # bar그래프 dodge를 하기 위해 기준값에 보정치를 더해줍니다.


for i, (ts, te) in enumerate(zip(train_score, test_score)):

    plt.text(i, ts+0.01, str(ts), horizontalalignment='center')

    plt.text(i+bar_width, te+0.01, str(te), horizontalalignment='center')


plt.legend(loc=1)

plt.xlabel('alpha')

plt.ylabel('score')

plt.show()

alpha와 max_iter값에 따른 test 점수



사용된 특성은 다음과 같습니다.

index = np.arange(len(alpha_set))

plt.bar(index, used_feature)

plt.xticks(index, alpha_set)

for i, u in enumerate(used_feature):

    plt.text(i, u+1, str(u), horizontalalignment='center')

plt.xlabel('alpha')

plt.ylabel('used_feature')

plt.show()

alpha값에 따른 특성 사용 수

alpha 값을 낮추면 model의 complexity는 증가하여 train set의 성능이 좋아집니다.

그러나 너무 낮추게 되면 regularization의 효과가 없어져 overfitting 되므로 liner regression과 비슷해집니다.

Ridge의 alpha 범위는 0 < alpha < Inf

Lasso의 alpha 범위는 0 < alpha ≦ 1 과 같습니다.



다음으로 alpha 값이 다른 model들의 coefficient를 시각화 해보겠습니다.

n_feature = boston_data.shape[1]

line = np.linspace(0, n_feature, num=n_feature)

alpha_set = [0.0001, 0.01, 1]

max_iter_set = [10000000, 100000,1000]

marker_set = ['v', '^', 's']


ridge = Ridge(alpha=0.01).fit(x_train, y_train)

plt.scatter(line, ridge.coef_, marker='o', label='Ridge alpha={}'.format(0.01))


for a, i, m in zip(alpha_set, max_iter_set, marker_set):

    param = {'alpha':a, 'max_iter':i}

    lasso = Lasso(**param).fit(x_train, y_train) # **kwargs parameter

    plt.scatter(line, lasso.coef_, marker=m, label='Lasso alpha={}'.format(a))

    

plt.legend(ncol=2, loc=(0, 1.05))

plt.ylim(-25, 25)

plt.hlines(y=0, xmin=0, xmax=n_feature)

plt.xlabel('coef_ list')

plt.ylabel('coef_ size')

plt.show()

alpha와 Ridge의 alpha값에 따른 특성의 값


Lasso alpha=1(빨강 정사각형)_일 때 계수 대부분이 0에 근접하였습니다.  ==> Regularization을 많이 했음을 의미합니다.

Lasso alpha=0.01(초록 정삼각형)일때 Regularization이 완화되어 분포가 약간 넓어진 것을 볼 수 있습니다.

Lasso alpha=0.00001(주황 역삼각형)일 때 Regularization이 거의 없어져 분포가 매우 넓어지는 것을 확인할 수 있습니다.

Ridge alapha=0.01(빨강 원)은 Lasso alpha=0.01과 분포가 비슷하지만 어떠한 계수도 0이 되지 않습니다.


보통은 Ridge Regression을 선호하지만 특성이 많고 일부분만 중요하다면 Lasso가 더 좋은 선택입니다.

분석하기 쉬운 model을 원하면 Lasso가 특성 중 일부만 사용하므로 쉡게 해석할 수 있는 model을 만듭니다.




참고 자료: 

[1]Introduction to Machine Learning with Python, Sarah Guido

'python 머신러닝 -- 지도학습 > Regression' 카테고리의 다른 글

Decision Tree Regressor  (0) 2018.03.14
Ridge  (0) 2018.03.12
LinearRegression  (0) 2018.03.12
k_NN(k-최근접 이웃) Regression  (1) 2018.03.12

+ Recent posts