데이터사이언스/머신러닝

Logistic Regression - 당뇨병예측

ghtis1798 2021. 3. 3. 10:49

로지스틱 회귀

로지스틱 회귀를 활용해 피마 인디언 당뇨병을 예측해보려고 합니다.

UCI Machine Learning에서 제공하는 피마 인디언 당뇨병 데이터를 갖고 Classfication 실습을 해보았습니다.

https://archive.ics.uci.edu/ml/index.php

📌데이터 수집 및 전처리

코드는 Colab에서 작성하였고 Drive에 csv파일을 올려두었습니다.

필요한 라이브러리들을 모두 불러와줍니다.

  • 데이터 처리를 위한 Pandas, Numpy
  • 시각화 라이브러리 plotly
  • 머신러닝 프레임워크인 sklearn
  • 교차 검증을 위한 cross_val_score, KFold
  • 평가를 위한 accuracy_score, precision_score, recall_score
import pandas as pd
import numpy as np
import plotly.express as px

from sklearn.model_selection import cross_val_score, KFold
from sklearn.metrics import accuracy_score, precision_score, recall_score

from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression

import warnings
warnings.filterwarnings('ignore')

데이터를 Load한 후 head()명령어로 살펴보겠습니다.

pima = pd.read_csv('diabetes.csv')
pima.head()

info() 명령어로 확인하니 null값은 존재하지 않고 768 x 9의 shape을 띄고 있습니다.

# 768 rows, 9 columns, null값 없음
# Outcome은 당뇨병 여부
pima.info()

각 값들의 분포와 최대값, 최소값, 평균등을 describe() 명령어로 한 번에 확인해보겠습니다.

# pima 데이터의 값 특징 확인
pima.describe()

최소값이 0인 값들이 존재합니다. Pregnancies의 경우 그렇다쳐도, Gluecose와 BloodPressure, SkinThickness, Insulin, BMI등의 값이 0인 것은 이상합니다. 시각화해서 확인해보겠습니다.

# 각 Column별 값 분포 시각화
for col in pima.columns:
  fig = px.histogram(pima, x=col, nbins=20)
  fig.show()

비정상적인 값들의 경우 중앙값인 median으로 대체해주려고합니다. 평균값으로 대체할 경우 Outlier의 영향을 강하게 받기 때문입니다.

# 혈압, 피부두께, 인슐린, 글루코스, BMI가 0인 Outlier들 전처리
outlier = ['Glucose', 'BloodPressure', 'SkinThickness', 'Insulin', 'BMI']

# outlier들 중 0인 값들 median(중앙값)으로 대체
pima[outlier] = pima[outlier].replace(0, np.median(pima[outlier]))

그리고 다시 살펴보겠습니다.

각 최소값이 0에서 median값으로 잘 대체되었습니다.

📌로지스틱 회귀로 분류

이제 로지스틱 회귀를 돌리기 전, feature와 target 데이터를 분리한 뒤 표준화하겠습니다.

# feature와 target 분리
X = pima.drop(columns=['Outcome'])
y = list(pima['Outcome'])

로지스틱 회귀의 경우 KFold=5인 교차검증을 실시하고, 정확도, 정밀도, 재현율을 구합니다.

lr_clf = LogisticRegression()

# 로지스틱 회귀 교차 검증
accuracy = cross_val_score(lr_clf, X, y, cv=5, scoring='accuracy')
precision = cross_val_score(lr_clf, X, y, cv=5, scoring='precision')
recall = cross_val_score(lr_clf, X, y, cv=5, scoring='recall')

# 정확도, 정밀도, 재현율 평균값
print('정확도 : ',accuracy.mean())
print('정밀도 : ',precision.mean())
print('재현율 : ',recall.mean())

참고자료

파이썬 머신러닝 완벽가이드 - 권철민 저

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

https://www.archive.ics.uci.edu/ml/index.php