(3-4) EDA

Yongjoo Lee·2020년 12월 17일
0
post-thumbnail
post-custom-banner

EDA (Exploratory Data Analysis)

탐색적 자료분석

데이터를 분석하는 기술적 접근은 많다.

그래서 방법론에 집중하다보면 데이터가 가진 본질적인 의미를 훼손할 수 있다 !

🔥 EDA → 데이터 그 자체만으로부터 인사이트를 얻어내는 접근법!

📌 EDA 과정에서는 다음과 같은 과정이 포함됨

  • 통계적 수치 (통계학)
  • 자료를 담는 numpy, pandas
  • 시각화 과정

EDA의 Process

  1. 분석의 목적과 변수 확인
    • 분석의 목적 : 분석 후 결과에 대한 의미 도출
    • 변수 확인 : 각 컬럼들이 어떤 의미를 가지며 어떤 타입을 가지고 있고, 분석하는 데에 적절한지 확인
  2. 데이터 전체적으로 살펴보기
    • 데이터간의 상관관계, 결측치(NA), 데이터의 사이즈(일반화하기에 적절히 큰지?) 파악
  3. 데이터의 개별 속성 파악하기
    • 각 데이터의 개별 속성 (같은 값이어도 어느 컬럼에 들어가 있냐에 따라 달라짐) 파악

🔎EDA Example - Titanic Problem 🔗

  • 분석하기에 굉장히 좋은 자료!

*분석의 목적과 변수 확인

Exploratory Data Analysis

탐색적 데이터 분석을 통해 데이터를 통달해봅시다. with Titanic Data

  1. 라이브러리 준비
  2. 분석의 목적과 변수 확인
  3. 데이터 전체적으로 살펴보기
  4. 데이터의 개별 속성 파악하기

0. 라이브러리, 데이터 준비

# 라이브러리 불러오기

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

%matplotlib inline
# 데이터 블러오기
# 동일 경로에 "train.csv"가 있는 경우

titanic_df = pd.read_csv("./train.csv")

1. 분석의 목적과 변수 확인

  • 타이타닉 호에서 생존한 생존자들은 어떤 사람들일까?
# 상위 5개 데이터 확인하기

titanic_df.head(5)

![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2Fe6adb4bd-c256-43ae-a544-a34c31da71be%2Fimage.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2Fe6adb4bd-c256-43ae-a544-a34c31da71be%2Fimage.png)

  • Cabin 에 결측치(NaN)가 존재하는 것에 유의!
    • 결측치가 의미하는 바에 따라 처리해주어야 함.
# 각 Column의 데이터 타입 확인하기

titanic_df.dtypes
PassengerId      int64
Survived         int64
Pclass           int64
Name            object
Sex             object
Age            float64
SibSp            int64
Parch            int64
Ticket          object
Fare           float64
Cabin           object
Embarked        object
dtype: object

2. 데이터 전체적으로 살펴보기

📌수치형 데이터 요약 보기

  • DataFrame.describe()
  • 수치형 데이터만 요약해주기 때문에 Name, Ticket 와 같은 object 자료형은 제공하지 않는다!
# 데이터 전체 정보를 얻는 함수 : .describe()

titanic_df.describe() # 수치형 데이터에 대한 요약만을 제공!

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/6aebea19-2d47-4c3a-ba90-2798734e0c77/Untitled.png

count 개수 / mean 평균 / std 표준편차 / min 최소 / Q 백분위 / max 최대

👉 데이터 살펴보기

  • PassengerId
    • 인덱스이기 때문에 큰 의미가 없다.
  • Survived
    • 0, 1로 구성되어있는 이진데이터
    • (예상) 평균이 0.5보다 작기 때문에 생존하지 못한사람이 더 많을 것이다.
  • Pclass
    • 범주형 데이터이기 때문에 큰 의미를 가지지 않는다.
  • Age
    • 평균 29.5, 표준편차 14.5, 최소나이 0.4, 최대나이 80
  • SibSp
    • 최대 8 (대가족?이려나...)
  • Parch
    • 최대 6 (대가족?이려나...)
  • Fare
    • (예상) 평균 32.2, 표준편차 49 인데, 최소가 0이고 최대가 512인 것은 차이가 너무 크므로 이상점(outlier)라고 볼 수 있다.

📌
상관계수 확인

  • DataFrame.corr()
  • x1x_1x2x_2의 상관관계
# 상관계수 확인!

titanic_df.corr()

![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2Ffc0a33dc-b899-4809-b8cc-f85b7e908c00%2Fimage.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2Ffc0a33dc-b899-4809-b8cc-f85b7e908c00%2Fimage.png)

👉 데이터 살펴보기

  • Pclass - Fare
    • 높은 등급(값이 낮음)일수록 요금이 비쌀 수 있다.
  • Pclass - Survived
    • 높은 등급의 사람들의 생존율이 더 높을 수 있다.

🔥 Correlation is NOT Causation

  • 상관성 : A가 올라갈수록 B가 올라감
  • 인과성 : A로 인해 B가 됨.

인과가 아니므로 높은 등급인 사람의 생존률이 높다고 무조건 단정하면 안됨!

📌
결측치 확인

  • DataFrame.isnull()
  • 통계함수 (sum())를 이용하면 보기 편하다.
# 결측치 확인

titanic_df.isnull().sum()
# Age, Cabin, Embarked에서 결측치 발견!
PassengerId      0
Survived         0
Pclass           0
Name             0
Sex              0
Age            177
SibSp            0
Parch            0
Ticket           0
Fare             0
Cabin          687
Embarked         2
dtype: int64

👉 결측치를 어떻게 처리할 지 정해야함!

  • 특정 값으로 대체할지
  • 하나의 데이터로 판단할지
  • 제거할지

3. 데이터의 개별 속성 파악하기

I. Survived Column

# 생존자, 사망자 수는?

titanic_df['Survived'].value_counts()
0    549
1    342
Name: Survived, dtype: int64
# 생존자 수, 사망자 수를 Barplot으로 그려보기 sns.countplot()

sns.countplot(x='Survived', data=titanic_df)
plt.show()

![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2Fe13c6aa9-744b-4d3d-baf8-a18880aa0d85%2Foutput_22_0.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2Fe13c6aa9-744b-4d3d-baf8-a18880aa0d85%2Foutput_22_0.png)

II. Pclass

# Pclass에 따른 인원 파악

titanic_df[['Pclass', 'Survived']].groupby(['Pclass']).count()

![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2Fc4c52063-ab69-4de6-b5b2-c28024189df7%2Fimage.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2Fc4c52063-ab69-4de6-b5b2-c28024189df7%2Fimage.png)

# Pclass 별 생존자 인원은?

titanic_df[['Pclass', 'Survived']].groupby(['Pclass']).sum()

![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2F8b57b6c3-7d1c-4b19-94f9-3e6e42b3b135%2Fimage.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2F8b57b6c3-7d1c-4b19-94f9-3e6e42b3b135%2Fimage.png)

# 전체 인원 대비 Pclass 별 생존자 비율은?

titanic_df[['Pclass', 'Survived']].groupby(['Pclass']).mean()

![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2Fdabb48f0-b50d-4968-8963-b52b89ae266a%2Fimage.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2Fdabb48f0-b50d-4968-8963-b52b89ae266a%2Fimage.png)

# 히트맵 활용

sns.heatmap(titanic_df[['Pclass', 'Survived']].groupby(['Pclass']).mean())
plt.show()

![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2F96cc45e7-9eeb-4c14-8298-fcbd08882c93%2Foutput_27_0.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2F96cc45e7-9eeb-4c14-8298-fcbd08882c93%2Foutput_27_0.png)

III. Sex

titanic_df.groupby(['Survived', 'Sex']).count()

![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2F4f5db40e-fc66-495e-94c6-ead109cd497d%2Fimage.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2F4f5db40e-fc66-495e-94c6-ead109cd497d%2Fimage.png)

# sns.catplot

sns.catplot(x='Sex', col='Survived', kind='count', data=titanic_df)
plt.show()

![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2F19d6183c-0705-49e0-8e69-da8c02af343a%2Foutput_30_0.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2F19d6183c-0705-49e0-8e69-da8c02af343a%2Foutput_30_0.png)

IV. Age

  • (유의) 결측치 존재!
titanic_df.describe()['Age']
count    714.000000
mean      29.699118
std       14.526497
min        0.420000
25%       20.125000
50%       28.000000
75%       38.000000
max       80.000000
Name: Age, dtype: float64
# Suvived 1, 0 과 Age의 경향성

fig, ax = plt.subplots(1, 1, figsize=(10, 5))
sns.kdeplot(x=titanic_df[titanic_df['Survived'] == 1]['Age'], ax=ax)
sns.kdeplot(x=titanic_df[titanic_df['Survived'] == 0]['Age'], ax=ax)

plt.legend(['Survived', 'Dead'])

plt.show()

![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2Fcf1902d4-9542-4659-a929-ffcd836d35a4%2Foutput_33_0.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2Fcf1902d4-9542-4659-a929-ffcd836d35a4%2Foutput_33_0.png)

여기까지는 단일 요소와 Survived에 대한 단일 비교를 해보았다.

복합적인 요소에도 분석을 할 수 있다.
👇

Appendix I. Sex + Pclass vs Survived

  • 복합적인 요소를 표현할 때에는 catplot을 많이 사용!
sns.catplot(x='Pclass', y='Survived', kind='point', data=titanic_df)

plt.show()

![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2F5f9c3c52-815b-4744-abde-c7e00047fe49%2Foutput_36_0.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2F5f9c3c52-815b-4744-abde-c7e00047fe49%2Foutput_36_0.png)

hue 옵션을 추가하면 특정 컬럼을 기준으로 나눠서 파악하기 용이하다!
sns.catplot(x='Pclass', y='Survived', hue='Sex', kind='point', data=titanic_df)

plt.show()

![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2Ff719ff5c-e8e4-4760-b80c-2f8570dd6cb8%2Foutput_38_0.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2Ff719ff5c-e8e4-4760-b80c-2f8570dd6cb8%2Foutput_38_0.png)

그래프는 pclass 별 생존자에 대한 추정치를 나타냄

👉 pclass가 높을 수록 생존자인 비율이 더 높다!

Appendix II. Age + Pclass

# Age graph with Pclass

titanic_df['Age'][titanic_df.Pclass == 1].plot(kind='kde')
titanic_df['Age'][titanic_df.Pclass == 2].plot(kind='kde')
titanic_df['Age'][titanic_df.Pclass == 3].plot(kind='kde')

plt.legend(['1st class', '2nd class', '3rd class'])

plt.show()

![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2Fc3221e99-105b-4199-b9c5-f85751db6a17%2Foutput_41_0.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2Fc3221e99-105b-4199-b9c5-f85751db6a17%2Foutput_41_0.png)

👉 클래스가 높은 등급일수록 나이대가 높다!

profile
하나씩 정리하는 개발공부로그입니다.
post-custom-banner

0개의 댓글