교육/코칭스터디<Data Science Projects 2024>

2. EDA를 통해 데이터 탐색하기

zzangyeah 2024. 1. 22. 14:27
728x90

2.1.1 당뇨병 데이터셋 미리보기

데이터 구성

  • Pregnancies : 임신 횟수
  • Glucose : 2시간 동안의 경구 포도당 내성 검사에서 혈장 포도당 농도
  • BloodPressure : 이완기 혈압 (mm Hg)
  • SkinThickness : 삼두근 피부 주름 두께 (mm), 체지방을 추정하는데 사용되는 값
  • Insulin : 2시간 혈청 인슐린 (mu U / ml)
  • BMI : 체질량 지수 (체중kg / 키(m)^2)
  • DiabetesPedigreeFunction : 당뇨병 혈통 기능
  • Age : 나이
  • Outcome : 768개 중에 268개의 결과 클래스 변수(0 또는 1)는 1이고 나머지는 0입니다.
#라이브러리 로드
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

%matplotlib inline

#데이터셋 로드
pd.read_csv("data/diabetes.csv")

#데이터셋 행렬크기 확인
df.shape

#데이터셋 상위 5개 행 미리보기
df.head()

#데이터셋 타입,결측치,메모리사용량확인
df.info()

#데이터셋 결측치 확인
df_null=df.isnull()
df_null.head()

#데이터셋 결측치 수 확인
df_null.sum()

#데이터셋 수치데이터에 대한 요약값
df.describe()

#처음 시작열부터 마지막에서 2번째 열까지 가져와 리스트 형태로 만듦
feature_columns=df.columns[0:1].tolist()
feature_columns

2.1.2 결측치 보기

#데이터셋에서 첫번쨰 열을 빼고 나머지 열들을 cols변수로 가져옴
cols=feature_columns[1:]
cols

#0으로 기록된 값은 null처리 후, 결측치를 알아봄
df_null=df[cols].replace(0,np.nan)
df_null=df_null.isnull()
df_null.sum()

#결측치 수치를 시각화
df_null.sum().plot.barh()

#결측치 전체 대비 비율
df_null.mean()*100

#히트맵
plt.figure(figsize=(15,4))
sns.heatmap(df_null, cmap="Greys_r")

2.1.3 훈련과 예측에 사용할 정답값을 시각화로 보기

#정답값
df["Outcome"]

#발병한 경우/발병하지 않은 경우의 수 비교
df["Outcome"].value_counts()

#발병하는 확률을 전체비율로 확인
df["Outcome"].value_count(normalize=True)

#임신횟수에 따른 당뇨병 발병확률
df.groupby(["Pregnancies"])["Outcome"].mean()

#임신횟수에 따른 당뇨병 빈도수
df.groupby(["Pregnancies"])["Outcome"].agg(["mean","count"])

#Pregnancies를 인덱스값으로 사용
df_po=df.groupby(["Pregnancies"])["Outcome"].agg(["mean","count"]).reset_index()
df_po

#시각화 그래프
df_po.plot()

#mean에 대한 시각화 그래프
df_po["mean"].plot()

#mean에 대한 막대 그래프
df_po["mean"].plot().bar()

#글씨를 회전하여 세워서 볼 수 있음
df_po["mean"].plot().bar(rot=0)

#seaborn 그래프
sns.countplot(data=df,x="Outcome")

#임신횟수를 카운트하여 시각화
sns.countplot(data=df, x="Pregnancies")

#임신횟수에 따른 당뇨병 발병 빈도수 비교
sns.coutplot(data=df, x="Pregnancies",hue="Outcome")

#임신횟수 6번을 기준으로 True/False지정
df["Pregnancies_high"]=df["Pregnancies"]>6
df[["Pregnancies","Pregnancies_high"]].head()

#2개의 카테고리로 나뉜 임신 횟수를 카운트
sns.countplot(data=df,x="Pregnancies_high")

#임신횟수에 따른 발병횟수 비교
sns.countplot(data=df, x="Pregnancies_high", hue="Outcome")

2.1.4 두 개의 변수를 정답값에 따라 시각화 해보기

#당뇨병 발병에 따른 BMI수치를 비교
sns.barplot(data=df, x="Outcome",y="BMI")

#당뇨병 발병에 따른 글루코스수치 비교
sns.barplot(data=df, x="Outcome",y="Glucose")

#당뇨병 발병에 따른 인슐린수치 비교
sns.barplot(data=df, x="Outcome",y="insulin")

#임신횟수에 따른 당뇨병 발병 횟수 비교
sns.barplot(data=df,x="Pregnancies",y="Outcome")

#임신횟수에 따른 당뇨병 발병횟수에 따른 글루코스수치 비교
sns.barplot(data=df,x="Pregnancies",y="Glucose",hue="Outcome")

#임신횟수에 따른 당뇨병 발병횟수에 따른 BMI수치 비교
sns.barplot(data=df, x="Pregnancies",y="BMI",hue="Outcome")

#임신횟수에 따른 당뇨병 발병횟수에 따른 인슐린수치 비교
sns.barplot(data=df, x="Pregnancies, y="insulin", hue="Outcome")

sns.barplot(data=df[df["Insulin"] > 0], x="Pregnancies", y="Insulin", hue="Outcome")
sns.boxplot(data=df, x="Pregnancies", y="Insulin", hue="Outcome")
sns.boxplot(data=df[df["Insulin"] > 0], x="Pregnancies", y="Insulin", hue="Outcome")

plt.figure(figsize=(15, 4))
sns.violinplot(data=df[df["Insulin"] > 0], x="Pregnancies", y="Insulin", hue="Outcome", split=True)

plt.figure(figsize=(15, 4))
sns.violinplot(data=df[df["Insulin"] > 0], x="Pregnancies", y="Insulin", hue="Outcome")

2.1.5 수치형 변수의 분포를 정답값에 따라 시각화해보기

#1개의 수치형변수(Pregnancies) 표현
sns.distplot(df["Pregnancies"])

#발병한 경우/발병하지 않은 경우를 변수에 할당
df_0=df[df["Outcome"]==0]
df_1=df[df["Outcome"]==1]
df_0.shape,df_1.shape

#임신여부에 따른 당뇨병 발병률
sns.distplot(df_0["Pregnancies"])
sns.distplot(df_1["Pregnancies"])

#나이에 따른 당뇨병 발병률
sns.distplot(df_0["Age"])
sns.distplot(df_1["Age"])

#곡선 그래프만 남길 때
sns.distplot(df_0["Age"],hist=false)
sns.distplot(df_1["Age"],hist=false)

2.1.6 서브플롯으로 모든 변수 한번에 시각화하기

#distplot은 밀도함수와 커널추정함수를 같이 그려줌
#subplot은 범주형 column을 시각화할 때 사용
#histplot은 수치형 데이터를 시각화할 때 사용
df["Pregnancies_high"]=df["Pregnancies_high"].astype(int)
h=df.hist(figsize=(15,15),bins=20)

#모든 column을 다 만들고 싶으면 서브플롯을 그려야함
#column의 갯수 세기
col_num=df.columns.shape
col_num

#서브플롯 그리기
fig, axes=plt.subplots(nrows=3,ncols=3,figsize(15,15))

#Outcome을 x축으로 하는 displot 그리기
fig,axes=plt.subplots(nrows=3,ncols=3, figsize=(15,15))
sns.distplot(df["Outcome"],ax=axes[0][0])

#반복문을 활용하여 subplots를 그리기
cols=df.columns[:-1].tolist()
fig, axes=plt.subplots(nrows=3,ncols=3,figsize=(15,15))

for i, col_name in enumerate(cols):
    row=i//3
    col=i%3
    
sns.distplot(df[col_name],ax=axes[row][col])

2.1.7 시각화를 통한 변수간의 차이 이해하기

#violin plot
fig,axes=plt.subplots(nrows=4,ncols=2,figsize=(15,15))

for i, col_name in enumerate(cols[:-1]):
    row=i//2
    col=i%2
sns.violinplot(data=df, x="Outcome",y=col_name, ax=axes[row][col])

sns.regplot(data=df,x="Glucose",y="Insulin")

sns.lmplot(data=df, x="Glucose",y="Insuline", hue="Outcome")

sns.lmplot(data=df[df["Insulin"]>0],x="Glucose",y="Insulin",hue="Outcome")

#Pairplot(모든 수치에 대해 plot을 그림)
sns.pairplot(df)

g=sns.PairGrid(df, hue="Outcome")
g.map(plt.scatter)

2.1.8 피처엔지니어링을 위한 상관계수 분석하기

#상관분석
df_corr=df.corr()

#상관계수
df_corr.style.background_gradient()

#히트맵
sns.heatmap(df_corr)
sns.heatmap(df_corr,vmax=1,vmin=1)

figure(figsize=(15,8))
sns.heatmap(df_corr, annot=True, vmax=1, vmin=-1,cmap="coolwarm")

df.iloc[:,:-2].replace(0,np.nan)

df_matrix=df.iloc[:,:-2].replace(0,np.nan)
df_matrix=["Outcome"]=df["Outcome"]
df_matrix.head()

df_corr["Outcome"]

sns.regplot(data=df_matrix,x="Insulin",y="Glucose")

sns.regplot(data=df,x="Age",y="Pregnancies")

sns.lmplot(data=df, x="Age",y="Pregnancies",hue="Outcome")

sns.lmplot(data=df,x="Age",y="Pregnancies",hue="Outcome",col="Outcome")