2023. 11. 19. 21:18ㆍML&DL/Data Analysis
- 목표: 심부전증 데이터 분석 및 예측 모델 만들기
- 데이터셋
https://www.kaggle.com/andrewmvd/heart-failure-clinical-data
Heart Failure Prediction
12 clinical features por predicting death events.
www.kaggle.com
- 데이터 변수
age: 환자의 나이 anaemia: 환자의 빈혈증 여부 (0: 정상, 1: 빈혈) creatinine_phosphokinase: 크레아틴키나제 검사 결과 diabetes: 당뇨병 여부 (0: 정상, 1: 당뇨) ejection_fraction: 박출계수 (%) high_blood_pressure: 고혈압 여부 (0: 정상, 1: 고혈압) platelets: 혈소판 수 (kiloplatelets/mL) serum_creatinine: 혈중 크레아틴 레벨 (mg/dL) serum_sodium: 혈중 나트륨 레벨 (mEq/L) sex: 성별 (0: 여성, 1: 남성) smoking: 흡연 여부 (0: 비흡연, 1: 흡연) time: 관찰 기간 (일) DEATH_EVENT: 사망 여부 (0: 생존, 1: 사망) |
💻 실습
라이브러리 import
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
데이터 불러오기 & 확인
df = pd.read_csv('heart_failure_clinical_records_dataset.csv')
df
df.info()
age: 환자의 나이 (수치형) anaemia: 환자의 빈혈증 여부 (0: 정상, 1: 빈혈) (범주형) creatinine_phosphokinase: 크레아틴키나제 검사 결과 (수치형) diabetes: 당뇨병 여부 (0: 정상, 1: 당뇨) (범주형) ejection_fraction: 박출계수 (%) (수치형) high_blood_pressure: 고혈압 여부 (0: 정상, 1: 고혈압) (범주형) platelets: 혈소판 수 (kiloplatelets/mL) (수치형) serum_creatinine: 혈중 크레아틴 레벨 (mg/dL) (수치형) serum_sodium: 혈중 나트륨 레벨 (mEq/L) (수치형) sex: 성별 (0: 여성, 1: 남성) (범주형) smoking: 흡연 여부 (0: 비흡연, 1: 흡연) (범주형) time: 관찰 기간 (일) (수치형) DEATH_EVENT: 사망 여부 (0: 생존, 1: 사망) (범주형) |
* 기초통계량
df.describe()
* 데이터 시각화 (histplot, joinplot, pairplot)
- age 와 DEATH_EVENT (사망 여부 (0: 생존, 1: 사망))
sns.histplot(x='age', data=df, hue='DEATH_EVENT', kde=True)
=> 80대가 넘어가면 생존률 보다 사망률이 높음
- 크레아틴키나제 3000 보다 작은 값만 보기
sns.histplot(data=df.loc[df['creatinine_phosphokinase'] < 3000, 'creatinine_phosphokinase'])
- 박출 계수와 사망 여부
sns.histplot(x='ejection_fraction', data=df, bins=13, hue='DEATH_EVENT', kde=True)
sns.boxplot(x='DEATH_EVENT', y='ejection_fraction', data=df)
=> 낮을 수록 사망률이 높은 경향을 보임
- 혈소판 수와 사망 여부
sns.histplot(x='platelets', data=df, hue='DEATH_EVENT')
sns.jointplot(x='platelets', y='creatinine_phosphokinase', hue='DEATH_EVENT', data=df, alpha=0.3)
=> 이상치가 보임
- 관찰기간(일)과 사망 여부
sns.histplot(x='time', data=df, hue='DEATH_EVENT', kde=True)
sns.boxplot(x='DEATH_EVENT', y='time', data=df)
=> 관찰 기간이 짧으면 사망률이 높고, 오히려 관찰 기간이 길면 생존률이 높다
=> 관찰 기간이 짧으면 심부전증이 악화된 환자일 확률이 높겠다. 반대로 관찰기간이 긴 환자일 수록 심부전증을 초기 발견해서 치료하고 있겠다는 개인적인 생각
* 데이터 전처리
from sklearn.preprocessing import StandardScaler
- 수치형(X_num), 범주형(X_cat), 타겟 데이터(y) 구분
X_num = df[['age', 'creatinine_phosphokinase','ejection_fraction', 'platelets','serum_creatinine', 'serum_sodium']]
X_cat = df[['anaemia', 'diabetes', 'high_blood_pressure', 'sex', 'smoking']]
y = df['DEATH_EVENT']
- 스케일러
- 수치화 데이터를 평균이 0이고 분산이 1인 값으로 표준화해줌
scaler = StandardScaler()
scaler.fit(X_num)
X_scaled = scaler.transform(X_num)
X_scaled = pd.DataFrame(data=X_scaled, index=X_num.index, columns=X_num.columns)
X = pd.concat([X_scaled, X_cat], axis=1)
X.head()
* train/test 데이터 7:3으로 분리
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=1)
* 모델 학습
-LogisticRegression
from sklearn.linear_model import LogisticRegression
model_lr = LogisticRegression(max_iter=1000)
model_lr.fit(X_train, y_train)
- 결과 평가
from sklearn.metrics import classification_report
pred = model_lr.predict(X_test)
print(classification_report(y_test, pred))
- XGBoost
from xgboost import XGBClassifier
model_xgb = XGBClassifier()
model_xgb.fit(X_train, y_train)
pred = model_xgb.predict(X_test)
print(classification_report(y_test, pred))
- RandomForest
from sklearn.ensemble import RandomForestClassifier
model_rf = RandomForestClassifier()
model_rf.fit(X_train, y_train)
pred = model_rf.predict(X_test)
print(classification_report(y_test, pred))
- 특징 중요도 확인
plt.bar(X.columns, model_xgb.feature_importances_)
plt.xticks(rotation=90)
plt.show()
'ML&DL > Data Analysis' 카테고리의 다른 글
[회귀] 삼성전자 주가 예측 모델 구현하기 (시계열 데이터) (0) | 2023.11.19 |
---|---|
[분류] 학생 데이터 분석 & 성적 등급 예측 모델 (1) | 2023.11.19 |