Regression(04) - Ridge and Lasso

회귀 게수를 축소해야 하는 이유

  • 먼저, 회귀 분석하기 좋은 데이터의 조건에 대해서 이야기 해 볼 것이다. X와 Y의 관계가 명확해야하며 선형성을 가지면 가장 좋을 것이다. 또한, 독립변수의 개수가 많다면 학습의 시간도 상대적으로 오래걸리며 과적합이 될 확률이 높다. 이러한 문제들이 발생되기 때문에 Y와의 상관성은 높아야 하지만 독립변수들끼리의 상관성은 적은 데이터 세트가 회귀 분석을 사용하기 좋은 데이터 일 것이다.
  • 실제로 Domain에 가보면 우리가 분석하기 좋은 데이터 세트로 만들어진 데이터는 거의 찾아보기 힘들 것이다. 특히 Y값(회귀뿐 아니라 분류문제에서도)에 대한 annotation이 거의 없이 진행되어질 것이기 때문이다. 실제로 반도체 분야에서는 해당 반도체가 정상인지 불량인지 검사를 하지않고 넘어가는 경우가 대부분이다.

회귀 분석하기 좋은 데이터의 조건

  • Y에 대한 변동성은 중복되어 공유되어 질 수 없기 때문에 아래와 같이 Y의 변동성을 잘 설명하면서 X들끼리는 상관관계가 없는 변수들이 좋은 변수이다.

회귀분석시 좋은 변수는

  • 영향력이 없는 입력 변수의 계수를 0에 가깝게 가져간다면, 모형에 포함되는 입력 변수의 수를 줄일 수 있다.

회귀계수를 축소하는 이유

  • 회귀 계수 축소법은 다음과 같이 크게 3가지의 방법이 존재한다.

회귀계수 축소법의 종류

  • Ridge Regression은 아래와 같이 objective function에 회귀계수의 제곱합의 term을 추가해 제한조건을 걸어주는 방법이다. 원래의 objective function에 포함되어있던 오차제곱합(Sum of Squared Error)을 최소화하는 것과 동시에 회귀계수의 제곱합도 최소화시켜 주는 것이다.

Ridge Regression - 01

  • Ridge regression에서의 회귀계수를 유도하는 방법은 아래와 같다.

Ridge Regression - 02

  • Ridge regression에서의 회귀 계수를 유도하는 과정을 생각해보면, 아래와 같이 $ X^{T} X $ 의 diagonal term에 $ \lambda $ 를 추가한 것을 확인해 볼 수 있다. 이렇게 diagonal term에 $ \lambda $ 를 더해줌으로써, 기존의 $ X^{T} X $ 행렬이 linearly independent하지 않을 경우 조금 더 orthogonal하게 만들어 역행렬을 구할 수 있게 해주는 일종의 trick인 것이다.

Ridge Regression - 03

Ridge Regression - 04

  • Ridge regression은 아래와 같은 objective function을 갖는데 이는 아래 그림과 같이 벡터들을 수직하게 만들어 주는 의미를 갖는다.

Ridge regression의 기하하적 의미

실습


1
2
3
4
5
6
7
8
9
10
11
12
13
# 분석에 필요한 패키지 불러오기
import os
import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn import metrics
from sklearn.metrics import confusion_matrix
from sklearn.metrics import accuracy_score, roc_auc_score, roc_curve
import statsmodels.api as sm
import matplotlib.pyplot as plt
import itertools
import time

  • 기존의 로지스틱 모델을 실습할 떄와 동일한 데이터를 가지고 진행할 것이다.

data info

  • Experience : 경력
  • Income : 수입
  • Famliy : 가족단위
  • CCAvg : 월 카드사용량
  • Education : 교육수준 (1: undergrad; 2, Graduate; 3; Advance )
  • Mortgage : 가계대출
  • Securities account : 유가증권계좌유무
  • CD account : 양도예금증서 계좌 유무
  • Online : 온라인계좌유무
  • CreidtCard : 신용카드유무

1
2
3
4
5
6
ploan = pd.read_csv("../data/Personal Loan.csv")

# 의미없는 변수 제거
ploan_processed = ploan.dropna().drop(['ID','ZIP Code'], axis=1, inplace=False)

ploan_processed = sm.add_constant(ploan_processed, has_constant='add')

설명변수(X), 타켓변수(Y) 분리 및 학습데이터와 평가데이터


1
2
3
feature_columns = list(ploan_processed.columns.difference(["Personal Loan"]))
X = ploan_processed[feature_columns]
y = ploan_processed['Personal Loan'] # 대출여부: 1 or 0
결과
1
2
train_x, test_x, train_y, test_y = train_test_split(X, y, stratify=y,train_size=0.7,test_size=0.3,random_state=42)
print(train_x.shape, test_x.shape, train_y.shape, test_y.shape)

로지스틱회귀모형 모델링 y = f(x)


1
2
3
model = sm.Logit(train_y, train_x)
results = model.fit(method='newton')
print(results.summary())
결과
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
                            Logit Regression Results                           
==============================================================================
Dep. Variable: Personal Loan No. Observations: 1750
Model: Logit Df Residuals: 1738
Method: MLE Df Model: 11
Date: Sat, 13 Jun 2020 Pseudo R-squ.: 0.6030
Time: 17:45:48 Log-Likelihood: -229.35
converged: True LL-Null: -577.63
Covariance Type: nonrobust LLR p-value: 2.927e-142
======================================================================================
coef std err z P>|z| [0.025 0.975]
--------------------------------------------------------------------------------------
Age 0.0245 0.102 0.240 0.810 -0.175 0.224
CCAvg 0.0985 0.063 1.562 0.118 -0.025 0.222
CD Account 4.3726 0.568 7.703 0.000 3.260 5.485
CreditCard -1.2374 0.337 -3.667 0.000 -1.899 -0.576
Education 1.5203 0.190 7.999 0.000 1.148 1.893
Experience -0.0070 0.102 -0.069 0.945 -0.206 0.192
Family 0.7579 0.128 5.914 0.000 0.507 1.009
Income 0.0547 0.004 12.659 0.000 0.046 0.063
Mortgage -0.0001 0.001 -0.144 0.885 -0.002 0.002
Online -0.4407 0.263 -1.674 0.094 -0.957 0.075
Securities Account -1.8520 0.561 -3.299 0.001 -2.952 -0.752
const -13.9203 2.773 -5.021 0.000 -19.354 -8.486
======================================================================================


1
2
# performance measure
print("model AIC: ","{:.5f}".format(results.aic))
결과
1
model AIC:  482.69329


1
2
3
4
5
6
7
8
9
10
11
12
13
14
pred_y = results.predict(test_x)
def cut_off(y,threshold):
Y = y.copy() # copy함수를 사용하여 이전의 y값이 변화지 않게 함
Y[Y>threshold]=1
Y[Y<=threshold]=0
return(Y.astype(int))

def acc(cfmat) :
acc=(cfmat[0,0]+cfmat[1,1])/np.sum(cfmat) ## accuracy
return(acc)

pred_Y = cut_off(pred_y,0.5)
cfmat = confusion_matrix(test_y,pred_Y)
print(cfmat)
결과
1
2
[[661  12]
[ 28 49]]

임계값(cut-off)에 따른 성능지표 비교


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
threshold = np.arange(0,1,0.1)
table = pd.DataFrame(columns=['ACC'])
for i in threshold:
pred_Y = cut_off(pred_y,i)
cfmat = confusion_matrix(test_y, pred_Y)
table.loc[i] =acc(cfmat)
table.index.name='threshold'
table.columns.name='performance'

# sklearn ROC 패키지 제공
fpr, tpr, thresholds = metrics.roc_curve(test_y, pred_y, pos_label=1)

# Print ROC curve
plt.plot(fpr,tpr)

# Print AUC
auc = np.trapz(tpr,fpr)
print('AUC:', auc)

roc curve

  • 위의 로지스틱 결과를 통해 “Experience”, “Mortgage” 2 가지 변수도 추가적으로 제거한 후 적합시킬 것이다.

1
2
3
4
5
6
feature_columns = list(ploan_processed.columns.difference(["Personal Loan","Experience",  "Mortgage"]))
X = ploan_processed[feature_columns]
y = ploan_processed['Personal Loan'] # 대출여부: 1 or 0

train_x2, test_x2, train_y, test_y = train_test_split(X, y, stratify=y,train_size=0.7,test_size=0.3,random_state=42)
print(train_x.shape, test_x.shape, train_y.shape, test_y.shape)
결과
1
(1750, 12) (750, 12) (1750,) (750,)

  • 제거한 후의 회귀계수들의 큰 변동이 없는 것으로 보아 제거된 변수가 크게 Y를 예측하는데 설명력이 큰 변수가 아니였으며, 다른 변수들과의 연관성도 적었다고 생각할 수 있을 것이다.

1
2
3
model = sm.Logit(train_y, train_x2)
results2 = model.fit(method='newton')
print(results2.summary())
결과
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

Logit Regression Results
==============================================================================
Dep. Variable: Personal Loan No. Observations: 1750
Model: Logit Df Residuals: 1740
Method: MLE Df Model: 9
Date: Sat, 13 Jun 2020 Pseudo R-squ.: 0.6029
Time: 18:03:22 Log-Likelihood: -229.36
converged: True LL-Null: -577.63
Covariance Type: nonrobust LLR p-value: 3.817e-144
======================================================================================
coef std err z P>|z| [0.025 0.975]
--------------------------------------------------------------------------------------
Age 0.0174 0.011 1.569 0.117 -0.004 0.039
CCAvg 0.0997 0.062 1.596 0.111 -0.023 0.222
CD Account 4.3699 0.567 7.705 0.000 3.258 5.481
CreditCard -1.2350 0.337 -3.668 0.000 -1.895 -0.575
Education 1.5249 0.187 8.156 0.000 1.158 1.891
Family 0.7572 0.127 5.948 0.000 0.508 1.007
Income 0.0546 0.004 12.833 0.000 0.046 0.063
Online -0.4418 0.263 -1.678 0.093 -0.958 0.074
Securities Account -1.8526 0.561 -3.302 0.001 -2.952 -0.753
const -13.7465 1.164 -11.814 0.000 -16.027 -11.466
======================================================================================


1
2
3
4
pred_y = results2.predict(test_x2)
pred_Y = cut_off(pred_y,0.5)
cfmat2=confusion_matrix(test_y, pred_Y)
(cfmat2[0,0]+cfmat2[1,1])/len(pred_Y) ## accuracy
결과
1
0.944


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
threshold = np.arange(0,1,0.1)
table = pd.DataFrame(columns=['ACC'])
for i in threshold:
pred_Y = cut_off(pred_y,i)
cfmat = confusion_matrix(test_y, pred_Y)
table.loc[i] = (cfmat[0,0]+cfmat[1,1])/len(pred_Y)
table.index.name='threshold'
table.columns.name='performance'

# sklearn ROC 패키지 제공
fpr, tpr, thresholds = metrics.roc_curve(test_y, pred_y, pos_label=1)

# Print ROC curve
plt.plot(fpr,tpr)

# Print AUC
auc = np.trapz(tpr,fpr)
print('AUC:', auc)
결과

설명력이 낮은변수 2가지를 제외한 모형의 roc curve

변수선택법


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
feature_columns = list(ploan_processed.columns.difference(["Personal Loan"]))
X = ploan_processed[feature_columns]
y = ploan_processed['Personal Loan'] # 대출여부: 1 or 0

train_x, test_x, train_y, test_y = train_test_split(X, y, stratify=y,train_size=0.7,test_size=0.3,random_state=42)
print(train_x.shape, test_x.shape, train_y.shape, test_y.shape)

def processSubset(X,y, feature_set):
model = sm.Logit(y,X[list(feature_set)])
regr = model.fit()
AIC = regr.aic
return {"model":regr, "AIC":AIC}

'''
전진선택법
'''
def forward(X, y, predictors):
# 데이터 변수들이 미리정의된 predictors에 있는지 없는지 확인 및 분류
remaining_predictors = [p for p in X.columns.difference(['const']) if p not in predictors]
tic = time.time()
results = []
for p in remaining_predictors:
results.append(processSubset(X=X, y= y, feature_set=predictors+[p]+['const']))
# 데이터프레임으로 변환
models = pd.DataFrame(results)

# AIC가 가장 낮은 것을 선택
best_model = models.loc[models['AIC'].argmin()] # index
toc = time.time()
print("Processed ", models.shape[0], "models on", len(predictors)+1, "predictors in", (toc-tic))
print('Selected predictors:',best_model['model'].model.exog_names,' AIC:',best_model[0] )
return best_model

def forward_model(X,y):
Fmodels = pd.DataFrame(columns=["AIC", "model"])
tic = time.time()
# 미리 정의된 데이터 변수
predictors = []
# 변수 1~10개 : 0~9 -> 1~10
for i in range(1, len(X.columns.difference(['const'])) + 1):
Forward_result = forward(X=X,y=y,predictors=predictors)
if i > 1:
if Forward_result['AIC'] > Fmodel_before:
break
Fmodels.loc[i] = Forward_result
predictors = Fmodels.loc[i]["model"].model.exog_names
Fmodel_before = Fmodels.loc[i]["AIC"]
predictors = [ k for k in predictors if k != 'const']
toc = time.time()
print("Total elapsed time:", (toc - tic), "seconds.")

return(Fmodels['model'][len(Fmodels['model'])])


'''
후진소거법
'''
def backward(X,y,predictors):
tic = time.time()
results = []

# 데이터 변수들이 미리정의된 predictors 조합 확인
for combo in itertools.combinations(predictors, len(predictors) - 1):
results.append(processSubset(X=X, y= y,feature_set=list(combo)+['const']))
models = pd.DataFrame(results)

# 가장 낮은 AIC를 가진 모델을 선택
best_model = models.loc[models['AIC'].argmin()]
toc = time.time()
print("Processed ", models.shape[0], "models on", len(predictors) - 1, "predictors in",
(toc - tic))
print('Selected predictors:',best_model['model'].model.exog_names,' AIC:',best_model[0] )
return best_model


def backward_model(X, y):
Bmodels = pd.DataFrame(columns=["AIC", "model"], index = range(1,len(X.columns)))
tic = time.time()
predictors = X.columns.difference(['const'])
Bmodel_before = processSubset(X,y,predictors)['AIC']
while (len(predictors) > 1):
Backward_result = backward(X=train_x, y= train_y, predictors = predictors)
if Backward_result['AIC'] > Bmodel_before:
break
Bmodels.loc[len(predictors) - 1] = Backward_result
predictors = Bmodels.loc[len(predictors) - 1]["model"].model.exog_names
Bmodel_before = Backward_result['AIC']
predictors = [ k for k in predictors if k != 'const']

toc = time.time()
print("Total elapsed time:", (toc - tic), "seconds.")
return (Bmodels['model'].dropna().iloc[0])


'''
단계적 선택법
'''
def Stepwise_model(X,y):
Stepmodels = pd.DataFrame(columns=["AIC", "model"])
tic = time.time()
predictors = []
Smodel_before = processSubset(X,y,predictors+['const'])['AIC']
# 변수 1~10개 : 0~9 -> 1~10
for i in range(1, len(X.columns.difference(['const'])) + 1):
Forward_result = forward(X=X, y=y, predictors=predictors) # constant added
print('forward')
Stepmodels.loc[i] = Forward_result
predictors = Stepmodels.loc[i]["model"].model.exog_names
predictors = [ k for k in predictors if k != 'const']
Backward_result = backward(X=X, y=y, predictors=predictors)
if Backward_result['AIC']< Forward_result['AIC']:
Stepmodels.loc[i] = Backward_result
predictors = Stepmodels.loc[i]["model"].model.exog_names
Smodel_before = Stepmodels.loc[i]["AIC"]
predictors = [ k for k in predictors if k != 'const']
print('backward')
if Stepmodels.loc[i]['AIC']> Smodel_before:
break
else:
Smodel_before = Stepmodels.loc[i]["AIC"]
toc = time.time()
print("Total elapsed time:", (toc - tic), "seconds.")
return (Stepmodels['model'][len(Stepmodels['model'])])


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Forward_best_model = forward_model(X=train_x, y= train_y)
Backward_best_model = backward_model(X=train_x,y=train_y)
Stepwise_best_model = Stepwise_model(X=train_x,y=train_y)

pred_y_full = results2.predict(test_x2) # full model
pred_y_forward = Forward_best_model.predict(test_x[Forward_best_model.model.exog_names])
pred_y_backward = Backward_best_model.predict(test_x[Backward_best_model.model.exog_names])
pred_y_stepwise = Stepwise_best_model.predict(test_x[Stepwise_best_model.model.exog_names])

pred_Y_full= cut_off(pred_y_full,0.5)
pred_Y_forward = cut_off(pred_y_forward,0.5)
pred_Y_backward = cut_off(pred_y_backward,0.5)
pred_Y_stepwise = cut_off(pred_y_stepwise,0.5)

cfmat_full = confusion_matrix(test_y, pred_Y_full)
cfmat_forward = confusion_matrix(test_y, pred_Y_forward)
cfmat_backward = confusion_matrix(test_y, pred_Y_backward)
cfmat_stepwise = confusion_matrix(test_y, pred_Y_stepwise)

print(acc(cfmat_full))
print(acc(cfmat_forward))
print(acc(cfmat_backward))
print(acc(cfmat_stepwise))
결과
1
2
3
4
0.944
0.944
0.944
0.944

  • 성능면에서는 네 모델이 큰 차이가 없음기에 회귀계수를 축소한 모형성능과 비교해 볼 것이다.

Lasso & RIdge


1
2
3
4
5
6
7
8
9
10
11
12
13
from sklearn.linear_model import Ridge, Lasso, ElasticNet
ploan_processed = ploan.dropna().drop(['ID','ZIP Code'], axis=1, inplace=False)

feature_columns = list(ploan_processed.columns.difference(["Personal Loan"]))
X = ploan_processed[feature_columns]
y = ploan_processed['Personal Loan'] # 대출여부: 1 or 0

train_x, test_x, train_y, test_y = train_test_split(X, y, stratify=y,train_size=0.7,test_size=0.3,random_state=42)
print(train_x.shape, test_x.shape, train_y.shape, test_y.shape)

## lasso 적합
ll=Lasso(alpha=0.01)
ll.fit(train_x, train_y)

  • 아래 Lasso를 통해 적합시킨 모델의 회귀계수를 보면 ‘Age’, ‘CreditCard’, ‘Securities Account’, ‘Online’ 4가지 변수에 대해 0으로 만들어준 것을 확인할 수 있다. 회귀계수 축소법이 다중공선성을 완화시키는 기법이지 해결하는 방법은 아니다. 꼭 쓸모없는 변수를 0으로 수렴하거나 만드는 것은 아님을 주의하자. 아래 로지스틱회귀 분석 결과에서는 p-value가 낮아 중요한 변수라고 판단되는 변수들이 0으로 만들어지는 모습을 볼 수 있다.

1
2
## 회귀 계수 출력
ll.coef_
결과
1
2
3
array([ 0.00000000e+00,  2.04783983e-03,  1.14390390e-01, -0.00000000e+00,
6.58342418e-02, 4.76625359e-04, 3.13396711e-02, 3.55393865e-03,
1.31719530e-05, 0.00000000e+00, -0.00000000e+00])


1
print(results.summary())
결과
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Logit Regression Results                           
==============================================================================
Dep. Variable: Personal Loan No. Observations: 1750
Model: Logit Df Residuals: 1738
Method: MLE Df Model: 11
Date: Sat, 13 Jun 2020 Pseudo R-squ.: 0.6030
Time: 17:45:48 Log-Likelihood: -229.35
converged: True LL-Null: -577.63
Covariance Type: nonrobust LLR p-value: 2.927e-142
======================================================================================
coef std err z P>|z| [0.025 0.975]
--------------------------------------------------------------------------------------
Age 0.0245 0.102 0.240 0.810 -0.175 0.224
CCAvg 0.0985 0.063 1.562 0.118 -0.025 0.222
CD Account 4.3726 0.568 7.703 0.000 3.260 5.485
CreditCard -1.2374 0.337 -3.667 0.000 -1.899 -0.576
Education 1.5203 0.190 7.999 0.000 1.148 1.893
Experience -0.0070 0.102 -0.069 0.945 -0.206 0.192
Family 0.7579 0.128 5.914 0.000 0.507 1.009
Income 0.0547 0.004 12.659 0.000 0.046 0.063
Mortgage -0.0001 0.001 -0.144 0.885 -0.002 0.002
Online -0.4407 0.263 -1.674 0.094 -0.957 0.075
Securities Account -1.8520 0.561 -3.299 0.001 -2.952 -0.752
const -13.9203 2.773 -5.021 0.000 -19.354 -8.486
======================================================================================

  • 이전에 로지스틱 회귀분석을 통해 만든 모델에 비해 조금 성능이 떨어진 것으로 보아 Lasso를 통해 회귀계수를 너무 많이 0으로 수렴시킨것은 아닌지 생각해 볼 수 있다.

1
2
3
4
5
## 예측, confusionmatrix, acc계산
pred_y_lasso = ll.predict(test_x)
pred_Y_lasso = cut_off(pred_y_lasso, 0.5)
cfmat = confusion_matrix(test_y, pred_Y_lasso)
print(acc(cfmat))
결과
1
0.936


1
2
3
4
5
6
fpr, tpr, thresholds = metrics.roc_curve(test_y, pred_y_lasso, pos_label=1)
# Print ROC curve
plt.plot(fpr,tpr)
# Print AUC
auc = np.trapz(tpr,fpr)
print('AUC:', auc)
결과

Lasso 적합시킨 로지스틱 회귀모형

ridge 적합

  • Lasso는 완전히 0으로 만들어 주지만, Ridge는 0에 가까이에 수렴하는 것을 다시 한번 확인 할 수 있다.

1
2
3
4
5
rr = Ridge(alpha=0.01)
rr.fit(train_x, train_y)

## ridge result
rr.coef_
결과
1
2
3
array([-3.71283678e-03,  7.37570775e-03,  3.54973975e-01, -5.28579506e-02,
7.83404224e-02, 4.12823466e-03, 3.62504712e-02, 3.27385112e-03,
1.73105480e-06, -1.91297381e-02, -8.77388670e-02])


1
2
## lasso result
ll.coef_
결과
1
2
3
array([ 0.00000000e+00,  2.04783983e-03,  1.14390390e-01, -0.00000000e+00,
6.58342418e-02, 4.76625359e-04, 3.13396711e-02, 3.55393865e-03,
1.31719530e-05, 0.00000000e+00, -0.00000000e+00])


1
2
3
4
5
6
## ridge y예측, confusion matrix, acc계산
## 예측, confusionmatrix, acc계산
pred_y_ridge = rr.predict(test_x)
pred_Y_ridge = cut_off(pred_y_lasso, 0.5)
cfmat = confusion_matrix(test_y, pred_Y_lasso)
print(acc(cfmat))
결과
1
0.932


1
2
3
4
5
6
fpr, tpr, thresholds = metrics.roc_curve(test_y, pred_y_ridge, pos_label=1)
# Print ROC curve
plt.plot(fpr,tpr)
# Print AUC
auc = np.trapz(tpr,fpr)
print('AUC:', auc)
결과

Ridge 모델 roc curve

lambda 값에 따른 회귀 계수 / accuracy 계산


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
## labmda값 0.001 ~ 10까지 범위 설정
alpha=np.logspace(-3, 1, 5)

data = []
acc_table=[]
for i, a in enumerate(alpha):
lasso = Lasso(alpha=a).fit(train_x, train_y)
data.append(pd.Series(np.hstack([lasso.intercept_, lasso.coef_])))
pred_y = lasso.predict(test_x) # full model
pred_y= cut_off(pred_y,0.5)
cfmat = confusion_matrix(test_y, pred_y)
acc_table.append((acc(cfmat)))


df_lasso = pd.DataFrame(data, index=alpha).T
df_lasso
acc_table_lasso = pd.DataFrame(acc_table, index=alpha).T
acc_table_lasso
결과

람다값에 따른 Lasso 정확도


1
2
3
4
5
6
7
8
9
10
11
12
13
14
data = []
acc_table=[]
for i, a in enumerate(alpha):
ridge = Ridge(alpha=a).fit(train_x, train_y)
data.append(pd.Series(np.hstack([ridge.intercept_, ridge.coef_])))
pred_y = ridge.predict(test_x) # full model
pred_y= cut_off(pred_y,0.5)
cfmat = confusion_matrix(test_y, pred_y)
acc_table.append((acc(cfmat)))


df_ridge = pd.DataFrame(data, index=alpha).T
acc_table_ridge = pd.DataFrame(acc_table, index=alpha).T
acc_table_ridge
결과

람다값에 따른 Ridge 정확도

labmda값의 변화에 따른 회귀계수 축소 시각화


1
2
3
4
5
6
7
8
9
10
11
import matplotlib.pyplot as plt
ax1 = plt.subplot(121)
plt.semilogx(df_ridge.T)
plt.xticks(alpha)

ax2 = plt.subplot(122)
plt.semilogx(df_lasso.T)
plt.xticks(alpha)
plt.title("Lasso")

plt.show()
결과

람다값에 따른 Lasso와 Ridge의 변화

  • 해당 데이터는 변수가 많지 않아 전부 사용해도 상관은 없지만, 해석을 함에 있어서 문제가 발생될 수 있으니 p-value가 높은 변수들을 제외한 모델을 사용하거나 변수 선택법을 통해 나온 모데을 사용하는 것이 좋을 것이다.
  • Lasso의 경우에는 $ \lambda $ 값에 따라서 성능의 변화가 심하고 좋은 변수라고 p-value를 보고 판단한 변수가 오히려 0으로 가버리는 현상들 때문에 이러한 경우에는 기본적인 모형을 사용하는 것이 좋다.

1
2


결과
1
2