Machine Learning/Evaluation matric

피마 인디언 당뇨병 예측

진성01 2022. 5. 20. 20:56

이번 글에서는 kaggle에서 제공하는 피마 인디언 당뇨병 데이터셋을 이용하여 당뇨병 여부를 판단하는 예측 모델 수립, 여러가지 성능 지표를 이용하여 모델의 성능을 평가한다.

 

피마 인디언 당뇨병 데이터 세트는 다음 피처로 구성된다.

  • Pregnancies: 임신 횟수
  • Glucose: 포도당 부하 검사 수치
  • BloodPressure: 혈압
  • SkinThickness: 팔 삼두근 뒤쪽 피하지방 측정값
  • Insulin: 혈청 인슐린
  • BMI: 체질량지수
  • DiabetesPedigreeFunction: 당뇨 내력 가중치 값
  • Age: 나이
  • Outcome: 클래스 결정 값(0또는 1)

먼저 모델 구현 및 성능 평가를 위한 라이브러리를 import하고, 데이터를 불러와 확인한다.

 

레이블이 불균등하게 분포하므로 Stratify를 이용하여 학습셋과 테스트셋에 클래스 별로 골고루 분포하게 해야 한다는 것을 알 수 있다.

 

info()를 이용하여 null값의 개수, 피처의 데이터 타입을 확인하였다. 

 

※이용할 데이터 프레임을 분석하기 위해서 describe()도 자주 사용한다. 다만 사용의 목적이 다르다.

  • info() -> null값 개수, 피처의 데이터 타입, 데이터의 용량을 확인하기 위해 사용
  • describe() -> 수치형 column의 통계학적 수치(min, max, 4분위값, mean, std 등)를 계산하기 위해 사용

데이터를 train_test_split을 이용하여 학습셋과 테스트셋으로 나누었다. 여기서 stratify = y를 이용하여 클래스의 분포가 균일하게 나누어 주었다.

 

get_clf_eval2()는 실제 클래스값(y_test), 예측 클래스값(pred), 예측 클래스 확률(pred_proba)를 이용하여 여러가지 성능지표를 계산하도록 작성하였다.

 

LogisticRegression 모델을 이용하여 학습하고 성능을 평가하였다. 여기서 재현율의 향상을 목표로  precision recall plot을 그렸다.

 

임계값을 0.42정도로 조정한다면 두 지표의 값이 비슷한 값을 나타내겠지만, 두 지표 모두 낮은 값을 나타낸다. 따라서 describe()를 이용하여 값들을 살펴보았다.

 

min값이 0인 데이터들을 확인할 수 있다. BloodPressure, skinThickness, Insulin 등 여러 값들이 0일 수 없는 데이터이지만 존재한다는 것은 누락값들을 0으로 처리했기 때문이라는 의심을 할 수 있다. 이를 그래프로 살펴보았다.

 

Glucose column의 값 분포를 살펴본 결과 0값이 5개 정도 분포한 것을 확인할 수 있다. 0 주변의 값은 없는데 0만 5개 있다는 것은 자연적인 분포가 아닌, 누락값을 0으로 처리했다는 것을 알 수 있다. 다음은 여러 지표들에서 0의 비율이 어느정도 되는지 확인해 보았다.

 

glucose 같은 경우 0.65%로 낮은 비율이나, Insulin, SkinThickness의 경우 매우 많은 비율을 차지하고 있어 해당 값들을 0이아닌 적절한 값으로 변경할 필요가 있다. 따라서 해당 값들을 평균값으로 대체하였다.

 

zero_features의 평균값을 mean_zero_features 변수에 저장하였다. 총 5개의 feature이므로 mean_zero_features는 5개의 값을 가지는 Series의 형태로 저장되었다. replace를 이용하여 0값을 평균값으로 변경하였다.

 

※mean_zero_features는 index로 zero_features의 column, 값은 평균값을 가지고 있다. 이를 replace에 이용한 결과 mean_zero_features의 index에 해당하는 column의 0값을 그 column의 평균값으로 replace하였다. 즉, mean_zero_features가 참조표와 같은 역할을 하여 replace하였다.

 

로지스틱 회귀의 경우 일반적으로 숫자 데이터에 표준화를 적용하면 더 좋은 성능을 나타내기 때문에 StandardScaler()를 통해 스케일링을 진행하였다. 전처리를 마친 데이터를 다시 로지스틱 회귀를 이용하여 예측하고 성능을 측정하였다. 성능 수치가 이전에 비해 좋아진 것을 확인할 수 있다.

 

다음으로 분류 결정 임계값의 변화에 따라 어떻게 성능 지표가 변화하는지 확인하기 위해 get_eval_by_threshold()를 작성하였다.

 

get_eval_by_threshold()는 실제 클래스, 예측 클래스의 1일 확률, 임계값 리스트를 입력하면 binarizer를 통해 임계값을 기준으로 0과 1로 나눈 후 custom_predict에 저장하고, get_clf_eval()을 이용하여 성능을 계산하는 함수이다.

 

임계값이 0.48일 경우 F1 score가 0.6931로 가장 높은 값을 보인다.

 

 

 

#이 글은 권철민 작가님의 [파이썬 머신러닝 완벽가이드]를 통해 공부한 내용을 바탕으로 정리하였습니다.

'Machine Learning > Evaluation matric' 카테고리의 다른 글

F1 score, ROC, AUC  (1) 2022.05.16
정밀도와 재현율  (0) 2022.05.15
정확도(accuracy), 오차 행렬(confusion matrix)  (0) 2022.05.12