Lumiere, and s5unnyjjj

ML - Practice #3 : Regularization(Ridge, Lasso, L1-norm/L2-norm with Logistic), Confusion Matrix 본문

Artificial Intelligence/Machine Learning

ML - Practice #3 : Regularization(Ridge, Lasso, L1-norm/L2-norm with Logistic), Confusion Matrix

s5unnyjjj 2021. 8. 15. 22:53
반응형

본 글에서는 아래에 나열된 이론을 바탕으로 코드를 작성해보도록 한다.

 1. Regularization (참고링크) https://s5unnyjjj.tistory.com/42?category=939071 

  1_1. Ridge Regression

  1_2. Lasso Regression

  1_3. L1/L2 norm-regularized Logistic Regression

2. Confusion matrix (참고링크) https://s5unnyjjj.tistory.com/44?category=939071

 

Used train data #1

사용할 데이터는 data1.csv 파일에 담겨 있다. 해당 파일을 열어보면 아래와 같이 저장되어있다. 

아래의 코드를 이용하여 data1.csv 파일에서 0행을 drop한 정보만을 불러와서 확인해보면 아래와 같이 출력되는 것을 확인할 수 있다. info() 함수를 사용하면 데이터의 수와 존재여부 그리고 데이터 타입을 확인할 수 있다.

 

또한 head() 함수를 사용하면 데이터를 앞에서부터 5개정도를 보여준다. data1.csv 파일에서는 AtBat열의 첫번째 값은 293, 두번째 값은 315 인것을 확인할 수 있다. 하지만 앞서서 0행을 drop하였기에 첫번째 값인 293이 아니라 두번째 값인 315부터 나열되며 아래 그림에서 확인할 수 있다시피 AtBat의 첫번째 값은 315인 것을 확인할 수 있다.

 

위의 표에서 "League", "Division", "NewLeague"만을 선별하여 확인해보면 아래와 같이 출력되는 것을 확인할 수 있다. 선별된 3개의 값을 pd.get_dummies() 함수를 이용해 가변수를 만들어주었기에 선별된 각 값 뒤에 접두가가 추가되며 값은 0과 1로 변경된 것을 확인할 수있다.

 

우리는 각 player의 salary를 알아볼 것이기 때문에 target은 salary가 된다. 그리고 앞서 사용되었던 Salary, League, Division, NewLeague를 drop한 것에 League_N, Division_W, NewLeague_N을 이어 붙여줌으로써 완성된 데이터프레임은 아래와 같다.

 

우리는 이렇게 완성된 데이터프레임을 train_test_split() 함수를 이용하여 데이터셋을 split하여 train과 test에 사용한다. 여기서는 test_size를 0.2로 설정하였기에 데이터프레임에서 test에 사용되는 데이터는 20%임을 의미한다. 그러므로 trainX의 shape은 (210, 19)이며, trainY의 shape은 (53, 19)이다. 이제부터는 전처리한 데이터를 이용하여 코드를 직접 구현해보도록 한다.

 

Used train data #2

사용할 데이터는 data2.csv 파일에 담겨 있다. 해당 파일을 열어보면 아래와 같이 저장되어있다. 

 

아래의 코드를 이용하여 dropna() 함수를 사용하면 파일내의 column에 NaN 값이 있다면 불필요하다고 간주하여 제거할수 있으므로 data2.csv 파일에서 drop한 정보만을 불러와서 확인해보면 아래와 같이 출력되는 것을 확인할 수 있다. info() 함수를 사용하면 데이터의 수와 존재여부 그리고 데이터 타입을 확인할 수 있다.

 

또한 head() 함수를 사용하면 데이터를 앞에서부터 5개정도를 보여주며 아래와 같이 데이터의 일부분을 확인할 수 있다.

 

우리는 Outcome을 예측하는 것이기 때문에 data2.csv에 있는 Outcome에 해당하는 값들은 target 값이 되며 Outcome을 제외한 나머지 값들은 input값이 된다. 우리는 이렇게 완성된 데이터프레임을 train_test_split() 함수를 이용하여 데이터셋을 split하여 train과 test에 사용한다. 여기서는 test_size를 0.2로 설정하였기에 데이터프레임에서 test에 사용되는 데이터는 20%임을 의미한다. 그러므로 trainX의 shape은 (765, 7)이며, trainY의 shape은 (765, 1)이다. 이제부터는 전처리한 데이터를 이용하여 코드를 직접 구현해보도록 한다.

 

Ridge Regression with regularization (using train data #1)

Ridge Regression은 Norm-based shrinkage regurlarization 방법이다. Ridge Regression은 penalty로 L2-norm을 사용한다. Ridge Regression의 최적화를 위한 전체 식은 아래와 같다.

 

최적화 과정에서, 파라미터 theta 전체 식은 아래와 같다.

 

RidgeRegression_model.py 하위에 있는 ridgeRegression 함수

ridgeRegression 클래스 하위에 아래에 작성된 함수의 기능을 구현하였으며, 자세한 내용은 아래와 같다.

 (def _cost 함수)  def _cost에는 Ridge Regression 함수의 cost function을 작성해준다. 추가적으로 regularization을 적용한 Ridge Regression이므로 penalty 부분도 추가해주어야 한다.

 >>> 여기서는 일반 cost function은 J1으로 작성해주고, regularization은 J2로 작성하고 J1+J2를 최종 cost function으로 정의하였다.

 (def _update 함수) Ridge Regression의 가설함수를 통해 예측한 값을 이용해주어야 한다. theta0은 이전 theta0에서 cost function을 theta0으로 미분한 값에 alpha를 곱한 값을 빼준 후, 해당 값을 theta0으로 재정의한다. theta1도 이전 theta1에서 cost function을 theta1으로 미분한 값에 alpha를 곱한 값을 빼준 후, 해당 값을 theta1으로 재정의한다. 

 (def fit 함수) update함수를 통해 학습시킴으로써 최적의 theta0과 theta1를 구한다. 

 (def predict 함수) Ridge Regression의 값을 예측하는 것이기에 가설함수를 작성해준다.

 

penalty 값이 너무 크면 모델을 편향되게(high bias) 만들기 때문에 역효과로 MSE가 커지게 되는 결과를 초래하게 된다. 그렇다고 너무 작은 penalty 값을 설정하면 high variance가 나타난다. 그러므로 적절한 lambda를 설정하는 것이 중요하다.

 

하지만 lambda 값을 일일히 설정하면서 적절한 lambda를 찾는 것은 쉽지 않다. 그러므로 이럴 때는 cross validation 기법을 사용한다. (참고링크) https://s5unnyjjj.tistory.com/43?category=939071 

 

cross validation 기법 중에서 여기서는 k-fold cross validation을 이용하여 적절한 lambda값을 구한다.

 

RidgeRegression_model.py 하위에 있는 kFold 함수

n_splits는 fold의 개수이다. n_samples는 dataset의 개수이므로 n_samples를 n_splits로 나눈 fold_size는 각 fold 내의 데이터 개수이다.

이해를 돕기 위해 아래의 그림을 그려보았다. 본 코드에서는 5개의 fold를 사용하므로 Fold#1~Fold#5로 작성하였다. 또한 각 fold에는 값이 Value#1~Value #n_samples만큼 있다. 여기서 n_samples라고 변수를 정한 이유는 코드에서 각 fold내의 데이터 개수를 n_samples라고 정의하였기 때문이다. 그러므로 

 

K-Fold cross validation은 (k-1)개의 fold는 training dataset이며 나머지 1개의 fold는 test dataset으로 사용한다. 빨간색은 test dataset을 의미하며 파란색은 training dataset을 의미한다. 

 

여기서 kFold 함수의 역할은 dataset을 k개의 fold로 분할한 후, fold 개수 만큼 반복문을 진행하여 training dataset과 test dataset에 해당하는 index값을 train_index 배열과 val_index배열에 저장한 값을 return 한다. 코드로 구현하면 아래와 같다.

 

RidgeRegression_model.py 하위에 있는 crossValidation_Ridge 함수

kFold함수를 통해 retrun 된 index를 이용하여 fold 만큼 반복하여 평균 오차를 확인한다. 각 fold 만큼 반복하였을 때, 제일 작은 MSE일 때가 최적의 lambda이기에 best_lambda 변수에 저장해준다. 위에서 정의한 set_params함수를 통해 ridge 모델을 최적의 lambda로 세팅해주고 training dataset으로 재학습시켜주면 최적의 ridge 모델 구축이 완료되었다. 마지막으로 최적의 lambda로 학습된 Lasso 모델을 이용하여 test dataset 상에서 예측한 값과 실제 test dataset 값 사이의 MSE를 구한다.

 

RidgeRegression_model.py 하위에 있는 ridgeClosed_get_theta 함수

미분된 theta0과 theta1을 통해 직관적으로 해당 값을 구할 수 있는 식을 코드로 구현하면 아래와 같다.

 

Result : Check 'train MSE' by closed Ridge and 'test MSE' by closed Ridge

'Train MSE' by closed Ridge and 'Test MSE' by closed Ridge를 확인한

ridgeClosed

 

closed form solution : 문제에 대한 해답을 식으로 명확하게 제시할 수 있다는 것을 의미

 

Result : Check the coefficients when lambda increases

Norm-based Shrinkage는 lambda를 이용한 정규화를 통해 coefficient 크기를 줄여 모델을 더욱 단순해지도록 규제한다. 아래 그림을 통해 lambda가 커질수록 즉, 규제 강도가 강해질수록 parameter가 0에 가까워지는 것을 알 수 있다.

 

Result : Check the best lambda

cross validation을 통해 제일 작은 MSE일 때의 lambda를 확인할 수 있다.

 

Lasso Regression with regularization (using train data #1)

Lasso Regression은 Ridge Regression과 마찬가지로 Norm-based shrinkage regurlarization 방법이다. Lasso Regression은 penalty로 L1-norm을 사용한다. Lasso Regression의 최적화를 위한 전체 식은 아래와 같다.

최적화 과정에서, 파라미터 theta 전체 식은 아래와 같다.

Lasso Regression 식은 뒤의 penalty를 제외하고는 식이 같기 때문에 update 과정도 유사하다. 그러므로 Lasso Regression에서는 update 과정을 일일이 식으로 작성하지 않고 sklearn을 사용하여 간단하게 표현하도록 한다.

 

LassoRegression_model.py 하위에 있는 crossValidation_Lasso 함수

Lasso의 theta를 update하는 함수만 sklearn에서 가져오는 것이기 때문에 적절한 lambda를 찾기 위한 코드는 따로 구현을 해줘야한다. 해당 부분 역시 K-Fold cross validation을 이용하는 것이기에 설명은 생략한다.

 

Result : Check the coefficients when lambda increases

Norm-based Shrinkage는 lambda를 이용한 정규화를 통해 coefficient 크기를 줄여 모델을 더욱 단순해지도록 규제한다. 아래 그림을 통해 lambda가 커질수록 즉, 규제 강도가 강해질수록 parameter가 0에 가까워지는 것을 알 수 있다.

Result : Check the best lambda

cross validation을 통해 제일 작은 MSE일 때의 lambda를 확인할 수 있다.

 

Logistic Regression with regularization (using train data #2)

이 전까지는 Linear Regression에서 L1-norm과 L2-norm의 적용에 따른 규제를 진행하였다. 해당 section에서는 egularization을 사용한 Logistic Regression을 구현한다. 우선 Logistic Regression에 대해서 간랸하게 설명을 하고 코드 구현을 시작하려 한다. Logistic Regression의 가설함수 전체 식은 아래와 같으며, sigmoid 함수가 사용된다.

 

Logistic Regression의 비용함수 전체 식은 아래와 같다.

 

Logistic Regression에 regularization을 사용하면 아래와 같다. 

위의 식인 일반 Logistic Regression의 식과 regularization을 사용한 Logistic Regression의 식과 다른 점은 regularization을 위하여 뒤에 lambda와 penalty가 붙었다는 것이다. penalty에는 L1-norm과 L2-norm이 사용될 수 있으며, L2-norm을 사용한 코드를 작성해보려 한다. regularization의 효과를 확인하기 위해 마지막에 regularization을 미적용한 일반 Logistic Regression과 regularization을 적용한 Logistic Regression의 결과를 비교해본다.

(Logistic Regression에 대한 정보를 추가적으로 알고싶다면 하단의 더보기를 누르면 된다.)

더보기

Logistic Regression의 이론 (참고링크) https://s5unnyjjj.tistory.com/39?category=939071 

Logistic Regression의 실습 (참고링크) https://s5unnyjjj.tistory.com/70

 

 

LogisticRegression_model.py 하위에 있는 l2_logistic 함수

l2_logistic 클래스 하위에 아래에 작성된 함수의 기능을 구현하였으며, 자세한 내용은 아래와 같다.

 (def _cost 함수)  def _cost에는 Logistic Regression 함수의 cost function을 작성해준다. 추가적으로 L2-norm regularization을 적용한 Logistic Regression이므로 penalty 부분도 추가해주어야 한다.

 (def _update 함수) Logistic Regression의 가설함수를 통해 예측한 값을 이용해주어야 한다. theta0은 이전 theta0에서 cost function을 theta0으로 미분한 값에 alpha를 곱한 값을 빼준 후, 해당 값을 theta0으로 재정의한다. theta1도 이전 theta1에서 cost function을 theta1으로 미분한 값에 alpha를 곱한 값을 빼준 후, 해당 값을 theta1으로 재정의한다. 

 (def fit 함수) update함수를 통해 학습시킴으로써 최적의 theta0과 theta1를 구한다. 

 (def predict 함수) Logistic Regression의 값을 예측하는 것이기에 가설함수를 작성해준다.

 

Result : Compare Logistic Regression without regularization and Logistic Regression with regularization

regularization을 적용하지 않은 Logistic Regression은 lambda와 penalty가 사용되지 않기에 lambda를 0으로 설정한다. Training Accuracy와 Test Accuracy를 확인해보면 아래와 같다.

 

regularization을 적용한 Logistic Regressino의 결과를 확인하기 위해 lambda는 0.5를 사용하며, penalty는 L2-norm을 사용한다. Training Accuracy와 Test Accuracy를 확인해보면 아래와 같다.

 

위의 두 결과를 통해 우리는 regularization을 적용한 것이 Test Accuracy가 더 높은 것을 확인할 수 있다.

추가적으로 sklearn으로 불러온 L1-norm logistic regression을 통해 Training Accuracy와 Test Accuracy를 확인해보면 아래와 같다.

 

Confusion matrix

L1-norm regularization/L2-norm regularization 적용에 따른 Logistic Regression에서 Confusion Matrix를 이용하여 성능 평가를 진행해본다. 

(참고링크) https://s5unnyjjj.tistory.com/44?category=939071

 

ConfusionMatrix.py 하위에 있는 Confusion_Matrix 함수

Confusion_Matrix함수에는 아래 그림을 배열 형태로 만들어준다. 그러므로 (2, 2)배열이 만들어지게 된다.

코드로 구현하면 아래와 같다.

 

ConfusionMatrix.py 하위에 있는 precision 함수

Precision의 식은 TP/(TP+FP) 이며, 코드로 구현하면 아래와 같다.

 

ConfusionMatrix.py 하위에 있는 recall 함수

Recall(True Positive Rate, Sensitivity)의 식은 TP/(TP+FN) 이며, 코드로 구현하면 아래와 같다.

 

ConfusionMatrix.py 하위에 있는 f1 함수

F1 score의 식은 (2*Precistion*Recall)/(Precision+Recall) 이며, 코드로 구현하면 아래와 같다.

 

ConfusionMatrix.py 하위에 있는 roc_auc 함수

모델의 성능을 평가하기 위해, TPR과 FPR를 이용한 AUROC(Area Under Receiver Operating Characteristic) 값을 구하는 코드를 구현하면 아래와 같다.

 

Result : PR Curve in L1-norm regularization and L2-norm regularization

Logistic Regression with L1-norm regularzation의 결과는 아래와 같다.

 

Logistic Regression with L2-norm regularzation의 결과는 아래와 같다.

 

Result : Area under the ROC Curve(AUROC) in L1-norm regularization and L2-norm regularization

L2-norm regularization 모델의 ROC curve를 확인해보면 아래 그림과 같다.

 

L1-norm regression 모델과 L2-norm regression 모델의 AUROC 값을 확인해보면 아래와 같다. 

 

위에서 L1 logistic regression 모델이 L2 logistic regression 모델보다 Training Accuracy와 Test Accuracy가 더 높은 것을 확인할 수 있었다. 정량적으로 성능을 평가하기 위해 confusion matrix와 AUROC도 확인해본 결과 L1 logistic regression 모델의 성능이 더 우수한 것을 알 수 있다. 

 

----------------------------------------------------------------------------------------------------

 

>> 위 내용은 필자가 직접 작성한 내용입니다.

>> 필자가 직접 구현한 코드를 아래의 링크에 업로드하였으니 참고바랍니다.

https://github.com/s5unnyjjj/ML_Practice-3

>> 부족한 점이 많을 수 있기에 잘못된 내용이나 궁금한 사항이 있으면 댓글 달아주시기 바랍니다.

>> 긴 글 읽어주셔서 감사합니다. 

 

반응형
Comments