캐글은 세계적인 ML 기반 분석 대회이다. 그 중에서도 타이타닉 생존자 예측은 처음 입문하는 사람들이 하는 튜토리얼이다. 캐글 사이트에서 Titanic을 검색하거나, https://www.kaggle.com/c/titanic에 들어가면 Data 카테고리에서 학습 데이터(train.csv)와 테스트 데이터(test.csv)를 다운 받을 수 있다. 

 

 

다운받기 전에 로그인을 해야하니 회원가입을 먼저하고 데이터를 다운받으면 된다. 오른쪽에는 해당 데이터에 관한 간략한 정보들이 나와있는 것을 확인할 수 있다. 다운받은 파일은 파이썬 코드 파일( 주피터 노트북일 경우, 해당 .ipynb파일)이 있는 디렉토리에 csv 파일을 저장한다. 이후에 다른 파일들도 train.csv 파일들이 많이 존재하기 때문에, 구별할 수 있도록 train_titanic.csv로 파일명을 변경한다. 

 

 

이제 창을 열고 데이터 분석에 필요한 라이브러리와 csv파일을 읽어온다. 

 

 

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

titanic_df = pd.read_csv('./titanic_train.csv')
titanic_df.head(3)

 

잘 불러왔는지 확인하기 위해서 .head(3)를 통해서 세개의 데이터를 가져와서 확인해보았다.

 

print('### 학습 데이터 정보 ###')
print(titanic_df.info())

이후에 어떤 데이터를 전처리 해야하는지 알아보기 위해 .info()를 이용해서 데이터를 확인한다. 이때, 주로 Null 값이 존재하는지, 어떤 데이터 형식(int, float, object 등)으로 되어있는지 확인한다. (object 형식은 string 형식과 동일)

 

확인했을때, 전체 891개의 데이터 중 Age는 714개, Cabin은 204개가 Null이 아닌 데이터이고, Embarked는 2개의 Null Data가 존재한다는 것을 볼 수 있다. 또한, Scikit-Learn을 사용하여 알고리즘 모델을 학습 - 예측할 때에는 입력하는 데이터가 숫자형(int, float 등)만 가능하므로, object 형식에 대해서는 어떻게 전처리해야하는지 고민해야 한다. 

 

 

Null Data 처리 

 

판다스 라이브러리를 통해서 Null 값을 한번에 처리해준다. 'Age' 칼럼의 경우는 Null 값이 적으므로, 평균값으로 대체하는 경우가 많다. 하지만, 'Cabin'처럼 Null 값이 너무 많은 경우에는 칼럼 자체를 삭제하는 것에 대해서도 고민해야 한다. 여기에서는 일단 'N'이라고 Null Data들을 대체했다. 'Embarked' 피처에 대해서도 동일한 과정을 수행했다. 

 

titanic_df['Age'].fillna(titanic_df['Age'].mean(), inplace = True)
titanic_df['Cabin'].fillna('N' , inplace= True)
titanic_df['Embarked'].fillna('N', inplace = True)

print('데이터 세트 Null 값 개수 : ', titanic_df.isnull().sum().sum())

 

 

마지막에서는 .isnull().sum().sum()을 통해서 전처리를 해준 후에도 Null 값이 남아있는지 확인해준다. 

.isnull() -> Null 값엔 True, 아닌 값엔 False가 적혀있는 데이터의 Shape과 동일한 DataFrame이 반환된다.

.isnull().sum() -> 각 칼러마다 Null 값이 몇개 있는지를 반환한다. 

.isnull().sum().sum() -> DataFrame 전체에서 Null 값이 몇개가 있는지 반환한다. 

 

 

문자열 데이터 처리 

 

위에서도 언급한 것 처럼, Scikit_Learn에서는 알고리즘 모델에 오직 숫자형 데이터만 들어갈 수 있다.  일단 문자열 데이터로 구성된 피처는 어떻게 되어있는지 확인하기 위해 .value_counts() 메서드를 통해서 확인한다. 

 

print('Sex 값 분포 :\n', titanic_df['Sex'].value_counts())
print('\n Cabin 값 분포 : \n', titanic_df['Cabin'].value_counts())
print('\n Embarked 값 분포 : \n', titanic_df['Embarked'].value_counts())

 

 

Cabin 피처의 값들을 보면 일단 N(Null Data)가 가장 많고, 그 외에도 상당히 다양하게 분포되어 있는것을 확인할 수 있다. 자세히 보면 가장 앞의 알파벳이 공통부분인것 같으므로 알파벳만 남겨둔다. 

 

 

 

 

데이터 시각화

 

예측을 수행하기 이전에 데이터에 대해서 먼저 파악을 하고 있어야 한다. 이런 경우에는 matplotlib이나 seaborn 등의 라이브러리를 이용해서 시각화를 하여 이해하는 것이 좋은 방법 중 하나이다. 

 

성별에 따른 생존율 차이 

 

대부분 사고가 나는 경우, 어린아이와 여성들을 우선으로 구조하는 경우가 많다. 그러므로 성별에 따른 생존율의 차이에 대해서 먼저 보자. 

.groupby를 통해서 생존율을 확인하고 시각화 한다. 

 

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

sns.barplot(x = 'Sex', y = 'Survived', data = titanic_df)

 

 

빈부격차에 따른 생존율 차이 

 

객실 등급을 통해서 배에 탑승한 승객들의 빈부 격차에 따라 생존율이 달라지는지 확인한다. 이때, 이전에 분류해 보았던 성별에 대해서도 부가적으로 나누어서 그래프를 그린다. sns.barplot()의 hue 인자에 'Sex' 칼럼을 넣어 구현할 수 있다. 

 

sns.barplot(x= 'Pclass', y = 'Survived', hue = 'Sex', data = titanic_df)

 

그래프를 보면, 여성이 전반적으로 높기는 하지만, 3등급에 탑승한 여성의 생존율은 상대적으로 떨어지는 것을 확인했고, 남성의 경우에는 1등석에 탑승한 사람들의 생존율이 2,3등석보다 생존 확률이 훨씬 높다는 것을 확인했다. 

 

 

연령대에 따른 생존율 차이

 

연령대의 경우, 나이대를 나누어 확인한다. 별도의 연령대를 나누는 함수를 제작하고, lambda 함수에 넣는 방식으로 구현할 수 있다.

 

def get_category(age):
    cat = ''
    if age <= -1: cat = 'Unknown'
    elif age <=5 : cat = 'Baby'
    elif age <=12 : cat = 'Child'
    elif age <= 18 : cat = 'Teenager'
    elif age <= 25 : cat = 'Student'
    elif age <= 35 : cat = 'Young Adult'
    elif age <= 60 : cat = 'Adult'
    else : cat = 'Elderly'
        
    return cat


#막대 그래프의 크기 figure를 더 크게 설정 
plt.figure(figsize =( 10, 6))

#X 축의 값을 순차적으로 표시하기 위한 설정 
group_names = ['Unknown', 'Baby','Child', 'Teenager', 'Student' , 'Young Adult','Adult','Elderly']


#lambda 식에 위에서 생성한 get_category() 함수를 반환값으로 지정
#get_category(X)는 입력값으로 'Age' 칼럼 값을 받아서 해당하는 cat 반환
titanic_df['Age_cat']  = titanic_df['Age'].apply(lambda x : get_category(x))
sns.barplot(x = 'Age_cat', y = 'Survived' ,hue ='Sex', data = titanic_df, order = group_names)
titanic_df.drop('Age_cat', axis = 1, inplace = True)

 

 

 

연령대에 따라서 생존률의 변화가 있는것을 확인할 수 있다. 특징적인 부분은 여자 Child의 생존율이 낮고, 여자 Elderly의 생존율이 매우 높았다는 것을 확인했다. 

이로써 'Sex', 'Pclass', 'Age'가 중요한 피처라는 보았다. 이후에 문자열 값을 전처리하는 방법과, 알고리즘 모델의 학습은 다음 포스팅에서 이어서 하겠다.

 

( lambda, groupby, isnull 등의 판다스 메서드가 헷갈리는 분들은 https://dsbook.tistory.com/177?category=802611 여기에서 확인할 수 있습니다.) 

728x90
반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 라이프코리아트위터 공유하기
  • shared
  • 카카오스토리 공유하기