#!/usr/bin/env python3


Ridge


Ridge는 linear model이므로 OLS(Ordinary Least Square)를 사용합니다.

Ridge Regression에서 가중치(w) 선택은 추가 제약 조건을 생성하여

가중치(w)의 절댓값을 가능학 작게 만드는 것(0으로 만드는 것이 아님)입니다.


기하학적으로 모든 특성의 기울기를 0에 가깝게 만드는 것이고 이 것을 regularization이라 합니다.

즉 model을 overfitting 하지 않도록 강제로 제한하는 것입니다.


Ridge Regression에 사용하는 regularization을 L2 regularization이라고도 합니다.


보스턴 주택가격으로 Ridge Regression과 linear regression을 사용하여 비교해보겠습니다.

from mglearn.datasets import load_extended_boston

from sklearn.linear_model import Ridge, LinearRegression

from sklearn.model_selection import train_test_split


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)


ridge = Ridge()

ridge.fit(x_train, y_train)

lr = LinearRegression()

lr.fit(x_train, y_train)


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

# 0.882

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

# 0.952

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

# 0.783

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

# 0.645

train set정확도는 Ridge Reg. < Linear Reg.

test set정확도는 Ridge Reg. > Linear Reg. 입니다.


Linear Reg는 train set과 test set의 차이가 많이나므로 overfittng이 되지만

Ridge Reg는 regularization이 적용되기 때문에 train set과 test set의 차이가 적습니다.

따라서 model의 complexity가 낮아지게 되고 test set의 정확도는 상승합니다.



다음으로 Ridge의 Regularization에 대해서 알아보겠습니다.

Ridge Reg.는 alpha parameter로 model을 얼마나 단순화할지를 결정합니다.

default 값은 1이며 높을수록 Regularization을 강화하여 계수를 0에 가깝게 만듭니다.


alpha값에 따른 정확도비교는 아래코드로 확인할 수 있습니다.

alpha_train_score = []

alpha_test_score = []

alpha_set = [0.1, 1 ,10]


for i in alpha_set:

    ridge=Ridge(alpha=i)

    ridge.fit(x_train, y_train)


    ridge_tr_score = round(ridge.score(x_train, y_train), 3)

    ridge_te_score = round(ridge.score(x_test, y_test), 3)


    alpha_train_score.append(ridge_tr_score)

    alpha_test_score.append(ridge_te_score)


print(alpha_set)

# [0.1, 1, 10]


print(alpha_train_score)

# [0.927, 0.882, 0.78]


print(alpha_test_score)

# [0.797, 0.783, 0.678]

alpha값이 커질수록(규제가 강화될수록) 정확도는 낮아지는 것을 볼 수 있습니다.



Ridge도 Linear_model이므로 속성(coef_, intercept_)가 존재합니다.

Ridge의 alpha값에 따른 coef_를 조사하면

import numpy as np

import matplotlib.pyplot as plt


n_feature = boston_data.shape[1]

line = np.linspace(0, n_feature, num=n_feature).reshape(-1, 1)


lr = LinearRegression().fit(x_train, y_train)

plt.scatter(line, lr.coef_, marker='s', label='Linear Reg.') # marker = 's'  => square


alpha_set = [0.1, 1 ,10]

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

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

    ridge = Ridge(alpha=i)

    ridge.fit(x_train, y_train)

    plt.scatter(line, ridge.coef_, marker=m, label='alpha={}'.format(i))


plt.ylim(-30, 30)

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

plt.legend(loc=(0.01, 1.01))

plt.show()

Linar Regression과 몇 가지 alpha 값을 가진 Ridge Regression의 coefficient 비교

x축은 coef_의 원소를 위치대로 나열한 것입니다. 즉 x=0, x=1은 각각 첫번째 특성과 두번째 특성을 나타내는 것입니다.

alpha=10일 때(빨강 역삼각형)은 대부분 y=0에 위치하며

alpha=1(초록 정삼각형)은 alpha=10일 때보다는 약간 퍼진 상태입니다.

alpha=0.1(주황 원)은 매우 크게 확장되었으며

Linear Reg.(파랑 정사각형)은 자유롭게 퍼져있는 것을 확인할 수 있습니다.



이번엔 learning curve(데이터셋의 크기에 따른 모델의 성능 변화)를 알아보겠습니다.

train_ridge_set = []

train_linear_set = []

test_ridge_set = []

test_linear_set = []


for i in test_size_set:

    x_train, x_test, y_train, y_test = \

      train_test_split(boston_data, boston_target,

                       random_state=35, test_size=i)

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

    lr = LinearRegression(n_jobs=-1).fit(x_train, y_train) # n_jobs = 사용할 코어의 수, -1은 모든 코어사용


    rid_tr_score = ridge.score(x_train, y_train)

    rid_te_score = ridge.score(x_test, y_test)

    lr_tr_score = lr.score(x_train, y_train)

    lr_te_score = lr.score(x_test, y_test)


    train_ridge_set.append(rid_tr_score)

    train_linear_set.append(lr_tr_score)

    test_ridge_set.append(rid_te_score)

    test_linear_set.append(lr_te_score)


plt.plot(x_ticks, train_ridge_set, c='lightblue', ls='--', label='train ridge'# c = color, ls = linestyle

plt.plot(x_ticks, train_linear_set, c='orange', ls='--',label='train Linear_Reg')

plt.plot(x_ticks, test_ridge_set, c='lightblue', label='test ridge')

plt.plot(x_ticks, test_linear_set, c='orange', label='test Linear_Reg')


plt.legend(loc=(0.01, 1.01))

plt.ylim(0, 1.1)

plt.show()

보스턴 주택가격 데이터셋에 대한 Ridge vs Linear Reg,

train 데이터(점선)가 test 데이터(line)보다 높음을 알 수 있습니다.

Ridge에는 regularization이 적용되므로 Linear Reg보다 낮습니다.


일반화 데이터에서는 Ridge의 점수가 더 높으며, 데이터셋이 작을수록 두드러집니다.

데이터셋의 크기가 작을수록 Linear Reg.는 어떤 것도 학습하지 못합니다.


데이터가 충분히 크면 regularization이 덜 중요해지고(두 모델의 차이가 줄어듭니다.)

Linear_Reg의 경우 데이터셋이 클수록 train 데이터 성능이 감소합니다. 이는 데이터가 많아질수록 overfitting 하기가 어려움을 시사합니다




참고 자료: 

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

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

Decision Tree Regressor  (0) 2018.03.14
Lasso  (0) 2018.03.13
LinearRegression  (0) 2018.03.12
k_NN(k-최근접 이웃) Regression  (1) 2018.03.12
#!/usr/bin/env python3

LinearRegression


Linear Regression은 아래 식을 이용하여 추정합니다.

ŷ = w[i]*x + b 
w[i]는 기울기, b는 y절편에 해당하고 특성이 많아지면 w[i]는 각 특성에 해당하는 기울기를 모두 가집니다.

이해를 돕기위해 인위적 데이터셋으로 동작환경을 살펴보겠습니다.
import mglearn
import matplotlib.pyplot as plt

mglearn.plots.plot_linear_regression_wave()
plt.show()

wave 데이터셋에 대한 선형 모델의 예측

회귀를 위한 선형 모델은 특성이 하나일 땐 직선이고
특성이 두개일 땐 평면
더 높은 차원에서는 hyperpane초평면이 됩니다.


특성이 많은 데이터셋이라면 linear model은 매우 훌룡한 성능을 낼 수 있습니다.
보통 OLS(ordinary least squares)최소제곱법을 많이 사용합니다.
linear regression은 parameter가 없는 것이 장점이지만
model의 복잡도를 제어할 방법이 없는 것이 단점입니다.


linear regression을 이용하여 인위적 데이터를 학습해보겠습니다.
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from mglearn.datasets import make_wave

x, y = make_wave(n_samples=60)
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=0)

lr = LinearRegression()
lr.fit(x_train, y_train)

train_score = lr.score(x_train, y_train)
test_score = lr.score(x_test, y_test)
print('{:.3f}'.format(train_score))
# 0.659
print('{:.3f}'.format(test_score))
# 0.693
train set와 test set의 점수가 매우 비슷한 것으로 보아 overfitting된 것을 알 수 있습니다.


linear regression의 속성을 보는 코드는 다음과 같습니다.
coef_는 기울기를 나타내며, intercept_는 절편을 나타냅니다. 또한 '_'는 머신러닝에서 유도된 결과를 나타내는 기호입니다.
print('{s[0]:.3f}'.format(s=lr.coef_)) # lr.coef_는 리스트이므로 소숫점 3자리로 표현하기 위해서는 리스트 안에 원소를 이용합니다.
# 0.442
print('{:.3f}'.format(lr.intercept_))
# -0.017



참고 자료: 

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


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

Decision Tree Regressor  (0) 2018.03.14
Lasso  (0) 2018.03.13
Ridge  (0) 2018.03.12
k_NN(k-최근접 이웃) Regression  (1) 2018.03.12
#!/usr/bin/env python3

k_NN(k-최근접 이웃) Regression


k-NN 회귀모델을 알아보겠습니다.
k-NN regression의 동작환경은 다음과 같습니다.

import mglearn

import matplotlib.pyplot as plt

mglearn.plots.plot_knn_regression(n_neighbors=1)
plt.show()

n_neighbors=1 일때 algorithm

x축에 3개의 테스트 데이터를 녹색 별로 표시합니다.
최근접 이웃을 한 개만 사용할 때 예측은 가장 가까운 데이터 포인트의 값으로 인식합니다.

다음은 이웃의 수가 3일 때 knn algorithm의 동작 환경입니다.
mglearn.plots.plot_knn_regression(n_neighbors=3)
plt.show()

n_neighbors=3 일때 algorithm

마찬가지로 3개의 녹색 테스트 데이터를 기준으로 가장 이웃한 3개의 최근접 데이터 포인트를 구합니다.
그리고 나서 각 데이터포인트사이의 거리의 역수를 가중치로 타겟 값을 산정합니다.


이해를 돕기위해 인위적 데이터를 사용하여 k-NN Regression을 사용해보겠습니다.
from mglearn.datasets import make_wave
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsRegressor

x, y = make_wave(n_samples=40)

x_train, x_test, y_train, y_test = \
  train_test_split(x, y, 
                   random_state=0, test_size=0.3)

knn_reg = KNeighborsRegressor(n_neighbors=3, n_jobs=-1) n_jobs = 사용할 코어의 수, -1 => 모든 코어 사용
knn_reg.fit(x_train, y_train)

print('{:.3f}'.format(knn_reg.score(x_test, y_test)))
# 0.697


1차원 데이터 셋이므로 시각화가 가능하므로 n_neighbors의 값에 따라 어떻게 변하는지 확인해보겠습니다.
import numpy as np
_, axes = plt.subplots(1, 3)

line = np.linspace(-5, 5, num=1000)
line = line.reshape(-1, 1)

for i, ax in zip([1, 3, 9], axes.ravel()):
    knn_reg = KNeighborsRegressor(n_neighbors=i, n_jobs=-1)
    knn_reg.fit(x_train, y_train)

    prediction = knn_reg.predict(line)
    ax.plot(line, prediction, label='model predict', c='k'
    ax.scatter(x_train, y_train, marker='^', c='darkred', label='train target')
    ax.scatter(x_test, y_test, marker='v', c='darkblue', label='test target')
    
    train_score = knn_reg.score(x_train, y_train)
    test_score = knn_reg.score(x_test, y_test)
    ax.set_title('k={}\ntest score={:.3f}\ntrain score={:.3f}'.format(i, train_score, test_score))
    ax.set_xlabel('feature')
    ax.set_ylabel('target')
axes[0].legend(loc=2)
plt.show()

n_neighbors 값에 따라 최근접 이웃 회귀로 만들어진 예측 회귀 비교

이웃을 하나만 사용할 때는 훈련 세트의 각 데이터 포인트가 모든 선을 통과합니다. 이 것은 너무 복잡하게 모델이 짜여져 있는 것을 말하며 실제로 예측할 때는 그 결과가 좋지 못합니다. 반대로 이웃을 많이 사용할 수록 훈련 데이터에는 잘 안맞을 수 있지만 높은 정확도를 얻게 됩니다.


k-NN은 이해하기 매우 쉬운 모델입니다. 그러나 수백 개 이상의 많은 특성을 가진 데이터 셋에는 잘 동작하지 않으며 특성값이 0이 많은 데이터셋이는 잘 작동하지 않습니다.
또한 예측이 느리고, 많은 특성을 처리하는 능력이 부족하여 현업에서는 잘 쓰지 않습니다.
KNeighborsRegressor와 KNeighborsClassifier의 객체를 생성할 때 'metric' parameter를 사용하여 거리 측정 방식을 변경할 수 있습니다. 'metric' parameter의 기본값은 'minkowski', 거듭제곱의 크기를 정하는 parameter느 'p'입니다.
metric='minkowski', p=2는 metric='euclidean'과 같습니다.



참고 자료: 

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


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

Decision Tree Regressor  (0) 2018.03.14
Lasso  (0) 2018.03.13
Ridge  (0) 2018.03.12
LinearRegression  (0) 2018.03.12

+ Recent posts