본문 바로가기

cs,코딩,알고리즘/<파이썬 머신러닝 완벽 가이드>스터디

피마 인디언 당뇨병 예측

728x90

머신러닝의 프로세스: 데이터 세트 가공.변환-> 모델 만들고 학습/예측-> 평가

오차행렬(Negative와 Positive 값을 가지는 실제 클래스 값과 예측 클래스 값이 True와 False에 따라 TN, FP, FN, TP오 나뉘는 행렬)을 기반으로 예측 성능을 평가. 이때 사용되는 분류 평가 지표는 positive 데이터 세트에 초점을 둔 정밀도(Precision)재현율(Recall), 이 둘을 결합한 F1 스코어, AUC가 있다.

 

 

이번에 사용할 데이터 세트는 피마지역의 인디언 당뇨병(Type-2) 데이터 세트. (고립된 지역에서 인디언 고유의 혈통이 지속되어왔지만 20세기 후반 서구화가 되며 식습관의 변화로 많은 당뇨환자가 생겨났다)

www.kaggle.com/uciml/pima-indians-diabetes-database

 

Pima Indians Diabetes Database

Predict the onset of diabetes based on diagnostic measures

www.kaggle.com

 

 

1. 데이터 세트 확인하기

Negative값(0)이 500개, Positive값(1)이 268개(전체 데이터의  65.1% 가 Negative이다)

여기서 피처(데이터 세트의 일반 속성, 타겟값을 제외한 나머지 속성)가 모두 숫자형 데이터임->회귀의 방법으로 예측모델을 만들어

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

2. 함수생성

Logistic Regression(로지스틱 회귀)의 방법으로 학습하고 예측, 수행

get_clf_eval()을 이용해서 성능 평가지표 출력(파이썬에서 커스텀했던 함수들 그대로 가져왔음)

예측 정확도가 77.27%, 재현율이 59.26%->정밀도에 비해 재현율이 낮으므로 재현율을 높히는 쪽으로 방향을 잡으면 되겠다


정확도=예측 결과와 실제 값이 동일한 건수/전체 데이터=(TN+TP)/(TN+TP+FN+FP)

정밀도(positive으로 예측한 대상중에 실제 값이 positive인 비율)=TP/(TP+FP)
재현율(실제 값이 positive인 대상 중 예측 값이 positive인 비율)=TP/(TP+FN)

=>이러한 불균형 label class를 가지는 이진 분류 모델에서는 많은 데이터 중에서 중점적으로 찾고자 하는 매우 적은 양의 결과값에 Positive를 설정하고, 그렇지 않은 경우는 Negative로 부여하는 경우가 많다. 그리고 Positive 데이터 수가 매우 작은 불균형한 이진 분류 dataset이기 때문에 데이터에 기반하는 ML 알고리즘은 Positive보다는 Negative로 예측 정확도를 높아지게 하는 경향이 있다. 따라서 TN은 매우 커지고 TP는 매우 작아지게 될 것이다. 또한 Negative로 예측할 때 정확도가 높기 때문에 FN이 매우 작고, Positive로 예측하는 경우가 애초에 매우 작아서 FP 또한 매우 작아진다. 결과적으로 비대칭한 dataset에서는 정확한 판단이 아님에도 불구하고 정확도가 매우 높게 나타나는 수치적인 판단 오류를 발생시킨다.

 

3. (전체 데이터의 65%가 Negative이므로) 재현율 성능에 좀 더 초점을 맞춰보자

1)precision recall 곡선 그림

정밀도는 점선, 재현율은 실선. 임계값이 낮을 수록 재현율의 값이 극도로 높아지고 정밀도가 극도로 낮아진다. 임계값을 증가시킬 수록 재현율이 낮아지고 정밀도 값이 높아진다. 

여기서 0.42에서 정밀도와 재현율이 비슷해진다. 그러나 둘다 0.7도 안됨 그리고 정밀도가 급격히 떨어진다는 것도 알 수 있다.

 

2) 각 피처들의 값 4분위 분포 확인

:describe()를 통해 수치들의 분포도 확인

최소 값이 0이 나오면 안 되는데 0으로 되어 있는 값들이 많이 존재한다 Glucose(포도당 수치), BloodPressure(혈압), SkinThickness(피하지방), Insulin(인슐린), BMI(체질량 지수) 같은 값이 실제로 0일 수는 없으니까

 

3)'Glucose' 피처의 분포도

포도당(Glucose) 수치를 대표로 hist로 분포도를 그려보면 0이 어느정도 있음을 볼 수 있다

 

4) 0값이 있는 피처들에서 0값의 데이터 건수와 퍼센트 계산

: min()값이 0으로 되어있는 피처에 대해 0값이 건수 및 저네 데이터 건수대비 몇 퍼센트의 비율로 존재해야 하는지

전체 데이터 건수는 아무 피처나 전체 개수를 세 주면 된다. 피처들을 반복하면서 0값이 들어간 피처들만 카운트를 하고 출력한다. 출력을 해 보면 SkinThickness와 Insulin쪽의 퍼센트가 꽤 높다

데이터 건수가 많지 않아서 데이터를 일괄 삭제하면 안되니까 피처 값을 그냥 0으로 하자

 

5) StandardScaler 클래스를 이용해 피처 데이터 세트에 일괄적으로 0값 처리와 스케일링 적용

다시 확인을 해 보면, 재현율이 올라가서 앞선 예측보다 약간 개선이 되었다(이전의 재현율: 0.5741)

 

6) 분류결정 임곗값을 변경하면서 성능 측정

0.3부터 0.5까지 임계값을 변경하면서 성능을 측정했다 정확도, 정밀도, 재현율, F1, AUC 등의 평가 지표를 보고 적절히 판단하여 임계값을 재설정하여 예측을 수행해야 한다!!!

F1스코어가 가장 높은 0.6931의 경우 정밀도와 재현율이 너무 떨어지기 때문에, 적당히 타협을 본 0.6857 스코어의 임계값이 0.48을 선택해 본다

최종 예측결과는 이러하다!!