본문 바로가기

머신러닝

[파이썬] Ridge,Lasso Regression and Confusion matrix

728x90

1. Ridge, Lasso Regression

 

Bias는 예측 값(prediction)과 실제 값(actual value, target)의 차이입니다.

 

Bias는 값을 예측하기 위한 모델(회귀, 분류)에 중요한 정보를 충분하게 제공하지 못한

경우 값이 커지게 됩니다.

 

학습데이터가 적은 경우, 비선형 데이터에 선형 모델을 적용할 경우 Bias값이 커지며

이는 Underfitting이라고 할 수 있습니다.

 

Variance는 데이터 변동에 대한 모델의 민감도로,

모델이 불필요한 데이터(noise)까지 학습하는 경우 Variance가 커지게 됩니다.

 

Overfitting의 경우이며 학습에 적용된 데이터에 대한 예측은 정확하지만,

학습에 사용되지 않은 데이터(test/validation data)에 대한 예측은 부정확합니다.

 

때문에 simple model은 높은 biias값과 낮은 variance값을 가지며,

complex model은 낮은 bias, 높은 variance값을 가지게 됩니다.

 

이런 문제를 해결하기 위해서는 적절한 degree로 최적의 모델을 만들 필요성이 있습니다.

 

특정 독립변수를 삭제하여 차원을 줄이는 대신, 가중치의 크기를 최소화하여

해당 가중치에 대응하는 독립변수의 영향을 줄여 과적합을 방지합니다.

 

MSE에 Regularization을 추가하여 가중치의 크기를 최소화합니다.

출처: COSS 빅데이터
출처: COSS 빅데이터

 

즉, 최소화 조건에 w_j^2를 포함해 예측값과 실제값 차의 제곱과 함께 가중치의

크기를 최소화해줍니다. (편향은 정규화하지 않음)

 

위 식은 Ridge regression이며 Lasso regression은 위 식에서

마지막 w_j^2를 |w_j|로 바꿔 계산합니다.

 

또한 위 식의 학습률 Parameter a는 오차 제곱과 가중치 크기 최소화에 대한 중요도를 결정합니다.

이 값이 클 수록, 최적 w를 찾을 때 가중치 크기의 영향이 커집니다.

 

Ridge, Lasso regression을 파이썬으로 구현해 보겠습니다.

 

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

dataset = pd.read_csv('C:/data/boston_housing.csv')
dataset

 

데이터 셋은 boston housing 데이터를 사용하겠습니다.

 

X와 y를 분리합니다.

 

dataset = dataset.values
x = dataset[:,:-1]
y = dataset[:,-1]
print(x.shape)
print(y.shape)

 

다음 train_test_split을 통해 train 데이터와 test 데이터로 나눠줍니다.

 

from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x,y,test_size=0.2,random_state=1)
print(x_train.shape)
print(x_test.shape)
print(y_train.shape)
print(y_test.shape)

 

비교를 위해 Linear, Ridge, Lasso regression을 모두 import합니다.

 

from sklearn.linear_model import LinearRegression,Ridge,Lasso

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

ridgeR = Ridge(alpha=2) # alpha값을 지정해 under,overfitting이 되지 않도록 조정함
ridgeR.fit(x_train,y_train)

lassoR = Lasso(alpha=0.01)
lassoR.fit(x_train,y_train)

 

위 ridge와 lasso에 들어가는 매개 변수 alpha는 위에서 설명한 학습률,

parameter a입니다.

 

Under, Overfitting이 되지 않게 적절한 임의의 값을 넣어줍니다.

 

from sklearn.metrics import mean_squared_error,mean_absolute_error,r2_score

y_pred_linear = linearR.predict(x_test)
y_pred_linear_tr = linearR.predict(x_train)

y_pred_ridge = ridgeR.predict(x_test)
y_pred_ridge_tr = ridgeR.predict(x_train)

y_pred_lasso = lassoR.predict(x_test)
y_pred_lasso_tr = lassoR.predict(x_train)

 

성능 확인을 위한 MSE, MAE, R^2를 불러오고

각 모델의 예측값을 변수에 저장합니다.

 

print('Mean Squared Error')
print('1. Linear regression')
print(' - trianing: ',mean_squared_error(y_train,y_pred_linear_tr))
print(' - test: ',mean_squared_error(y_test,y_pred_linear))

print('2. Ridge regression')
print(' - trianing: ',mean_squared_error(y_train,y_pred_ridge_tr))
print(' - test: ',mean_squared_error(y_test,y_pred_ridge))

print('3. Lasso regression')
print(' - trianing: ',mean_squared_error(y_train,y_pred_lasso_tr))
print(' - test: ',mean_squared_error(y_test,y_pred_lasso))

 

MSE를 먼저 비교하면 test data 기준으로 Ridge regression이 가장 좋은 성능을 보입니다.

train 데이터의 성능은 단순 Linear regression이 좋지만, test 데이터의 성능은 Ridge, Lasso가

더 좋은 모습을 보입니다.

 

print('Mean Absolute Error')
print('1. Linear regression')
print(' - trianing: ',mean_absolute_error(y_train,y_pred_linear_tr))
print(' - test: ',mean_absolute_error(y_test,y_pred_linear))

print('2. Ridge regression')
print(' - trianing: ',mean_absolute_error(y_train,y_pred_ridge_tr))
print(' - test: ',mean_absolute_error(y_test,y_pred_ridge))

print('3. Lasso regression')
print(' - trianing: ',mean_absolute_error(y_train,y_pred_lasso_tr))
print(' - test: ',mean_absolute_error(y_test,y_pred_lasso))

 

print('R2_score') # r2는 1에 가까울 수록 좋음
print('1. Linear regression')
print(' - trianing: ',r2_score(y_train,y_pred_linear_tr))
print(' - test: ',r2_score(y_test,y_pred_linear))

print('2. Ridge regression')
print(' - trianing: ',r2_score(y_train,y_pred_ridge_tr))
print(' - test: ',r2_score(y_test,y_pred_ridge))

print('3. Lasso regression')
print(' - trianing: ',r2_score(y_train,y_pred_lasso_tr))
print(' - test: ',r2_score(y_test,y_pred_lasso))

 

MAE, R2모두 Linear regression보다 Ridge, Lasso regression이

성능이 뛰어난 것을 확인할 수 있습니다.

 

728x90

 

2. Confusion matrix

 

Confusion Matrix는 분류기의 성능을 평가하는 지표입니다.

단순 accuracy score로도 확인할 수 있지만 보다 정확한 모델의 성능을 평가할 수 있는 지표입니다.

 

Confusion Matrix는 다음과 같습니다.

  • True positives(TP): 분류기가 Positive(양성)로 판단했으며, 실제로도 Positive인 경우
  • True negative(TN): 분류기가 Negative(음성)로 판단했으며, 실제로도 Negative인 경우
  • False positives(FP): 분류기는 Positive로 판단했으나, 실제로는 Negative인 경우
  • False negative(FN): 분류기는 Negative로 판단했으나, 실제로는 Positive인 경우

위를 통해 분류 정확도(Classification Accuracy), 오분류율(Misclassification rate)를 구할 수 있습니다.

 

먼저 분류 정확도는 정확하게 분류된 데이터의 수 / 전체 데이터의 수이며

(TP+TN) / (TP+TN+FP+FN)입니다.

 

오분류율은 잘못 분류된 데이터의 수 / 전체 데이터의 수 이며

(FP+FN) / (TP+TN+FP+FN)입니다.

 

이 외에도 Precision과 Recall이 있습니다.

 

Precision은 TP / (TP+FP)이며,

모델이 Positive로 판단한 경우, 얼마나 정확한지를 알 수 있습니다.

FN은 Precision에 영향을 미치지 않으며, FN에 의한 loss보다 FP에 의한 loss가 상대적으로 더 큰 경우,

매우 중요한 평가 척도입니다.

 

Recall은 TP / (TP+FN)이며,

실제로 Positive인 데이터를 모델이 얼마나 잘 분류했는지 알 수 있습니다.

FP는 Recall에 영향을 미치지 않으며, FP에 의한 loss보다 FN에 의한 loss가 상대적으로 더 큰 경우,

매우 중요한 평가 척도입니다.

 

위에서 서술했듯이 정확도만으로는 분류기 성능을 평가하기에 충분하지 않습니다.

 

예를 들어 암환자를 분류하는 모델이 있을 때, 암환자를 정상으로 판단한 것이

정상을 암환자로 분류하는 것 보다 중요하다 할 수 있습니다.

 

이 때 암환자가 10명이고 정상이 100명일 때, 90명의 사람을 정상으로 판단한다면

모델의 정확도가 높게 나올 것 입니다.

 

때문에 상황에 따라 Recall과 Precision이 중요한 성능평가의 척도가 될 수 있습니다.

 

Confusion matrix를 파이썬으로 구현하면 다음과 같습니다.

 

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

dataset = pd.read_csv('C:/data/Social_Network_Ads.csv').values

x = dataset[:,:-1]
y = dataset[:,-1]

from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.25,random_state = 42)

 

train 데이터와 test데이터로 나누고 데이터 스케일링을 진행합니다.

 

from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
sc.fit(x_train)
xsc_train = sc.transform(x_train)
xsc_test = sc.transform(x_test)

 

다음 모델은 Logistic Regression을 사용하겠습니다.

 

from sklearn.linear_model import LogisticRegression
lr = LogisticRegression()
lr.fit(xsc_train,y_train)

y_pred = lr.predict(xsc_test)

 

먼저 정확도를 구해보겠습니다.

 

from sklearn.metrics import accuracy_score
acc = accuracy_score(y_test,y_pred)
print('accuracy: ',acc*100)

 

정확도는 86으로 정확도만 봤을 때 꽤나 좋은 모델이라고 할 수 있습니다.

 

from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test,y_pred) # [TN, FP]
tn = cm[0,0]                         # [FN, TP] 형태임
fp = cm[0,1]
fn = cm[1,0]
tp = cm[1,1]
print(cm)

 

이 모델의 confusion matrix는 위와 같습니다.

이 값을 통해 precision과 recall을 구합니다.

 

precision = tp/(tp+fp)
recall = tp/(tp+fn)
print('precision: ',precision*100)
print('recall: ',recall*100)

 

이 모델은 모델이 Positive로 판단한 데이터의 정확도가 92%이며,

실제 Positive인 데이터를 정확히 예측한 정확도는 67%입니다.

 

3. ROC curve

 

ROC 곡선은 분류기의 분류 기준을 변경함에 따라 변화되는 FPR에 대한 TPR값을 이은 곡선으로,

분류기의 성능을 평가합니다.

 

FPR이 작을 수록, TPR은 클 수록 좋은 분류 모델임을 의미합니다.

 

출처: COSS 빅데이터

 

Threshold가 우측(Positive 쪽)으로 이동하면 FPR,TPR이 작아집니다.

Threshold가 좌측(Negative 쪽)으로 이동하면 FPR,TPR이 커집니다.

 

Positive 데이터 및 Negative 데이터 분포의 중첩 영역이 작을 수록 FP는 작고, TP는 커지게되며,

성능이 좋은 분류 모델은 중첩 영역이 작습니다.

 

또한 ROC 곡선을 봤을 때 좋은 분류 모델은 좌측 상단에 가까워집니다.

 

파이썬으로 구현 시 다음과 같습니다.

 

from sklearn.metrics import roc_curve,auc
y_pred_proba = lr.predict_proba(xsc_test)
fpr,tpr,thresholds = roc_curve(y_test,y_pred_proba[:,1]) # y_pred_proba[:,1] = 모델의 결과 중 x에 대해서 y가 1일 확률
lr_auc = auc(fpr,tpr)
label = 'LogisticRegression (AUC = {})'.format(round(lr_auc,2))
plt.plot(fpr,tpr,label=label)
plt.legend()

 

AUC(Area Under the Curve)는 곡선 아래 영역을 뜻하며,

AUC값이 높을 수록 좋은 모델을 뜻 합니다.

728x90
반응형