본문 바로가기

study

[Kaggle] Survival on the Titanic

구글의 예측모델 및 분석 대회 플랫폼인 kaggle의 가장 기초적인 문제를 풀어보았다. 영화로도 유명한 타이타닉호의 생존자를 예측하는 문제이다. 해당 내용은 유투브 채널 오늘의 코드와 허민석,  현재 수강 중인 교육 플랫폼 learnit의 영상을 토대로 작성하였다.

1. EDA
2. Feature engineering
3. 모델 적용 및 타당성 검증

1. EDA

**Data Dictionary**
- Survival : 0 = No, 1 = Yes  
- pclass : Ticket class (1 = 1st, 2 = 2nd, 3 = 3rd)  
- sibsp : # of siblings / spouses aboard the Titanic  
- parch : # of parents / children aboard the Titanic  
- embarked : Port of Embarkation (C = Cherbourg, Q = Queenstown, S = Southampton)

 

# 데이터 불러오기
import pandas as pd

train = pd.read_csv("C:/Users/user/Github/[Kaggle] Titanic/train.csv")
test = pd.read_csv("C:/Users/user/Github/[Kaggle] Titanic/test.csv")

# train데이터에는 생존여부가 나와있음 -> 지도학습
train.shape
test.shape

# 유실된 데이터가 있음을 파악 -> fearture engineering에서 다뤄야할 것
train.info()
test.info()

# 결측값 파악
train.isnull().sum()

train.head()

 

# 함수로 정의하여 그래프 그리기
def bar_chart(feature) :
    survived = train[train['Survived']==1][feature].value_counts()
    dead = train[train['Survived']==0][feature].value_counts()
    df = pd.DataFrame([survived,dead])
    df.index = ['Survived','Dead']
    df.plot(kind='bar',stacked=True, figsize=(10,5))
    
bar_chart('Sex')
bar_chart('Pclass')
bar_chart('SibSp')
bar_chart('Parch')
bar_chart('Embarked')

성별, 좌석, 동승한 형제자매에 따른 생존여부
동승가족과 탑승항에 따른 생존여부

 

# 각 데이터간 상관관계
train.corr('kendall')

# 상관관계 그래프
plt.figure(figsize=(10,5),)
sns.heatmap(train.corr('kendall'))

 

2. Feature engineering

불필요한 데이터를 걸러내고 데이터를 모델에 적용하기 위해 숫자로 치환 또는 스케일링하는 작업. 아래는 내용은 이름에서 결혼여부와 직업등을 걸러내고 숫자로 치환한 내용이다. 이렇게 성별, 좌석 등등 다른 피처들 역시 마찬가지로 작업해준다. 다만 나이의 경우 다른 피처에 비해 숫자의 범위가 커다보니 그대로 모델에 적용할 경우 왜곡이 발생할 수 있다. 따라서 bining을 통해 구간을 나눠 숫자로 바꿔준다.

# 데이터 합치기 및 타이틀 데이터 추출
# Name에서 대문자로 시작해서 이 후에는 소문자가 나열되며 . 을 만나면 탐색을 멈춰 string을 추출한다.
train_test_data = [train,test]

for dataset in train_test_data : 
    dataset['Title'] = dataset['Name'].str.extract('([A-Za-z]+)\.', expand=False)
    
train['Title'].head
train.shape
train['Title'].value_counts()

**Title map**  
Mr : 0  
Miss : 1  
Mrs : 2  
Others : 3  

# 타이틀 값에 수치값 매핑(데이터프레임형태의 두개의 데이터셋을 리스트형으로 묶은 경우 함수 사용하여 적요)
title_mapping = {"Mr": 0, "Miss": 1, "Mrs": 2, 
                 "Master": 3, "Dr": 3, "Rev": 3, "Col": 3, "Major": 3, "Mlle": 3,"Countess": 3,
                 "Ms": 3, "Lady": 3, "Jonkheer": 3, "Don": 3, "Dona" : 3, "Mme": 3,"Capt": 3,"Sir": 3 }

for dataset in train_test_data:
    dataset['Title'] = dataset['Title'].map(title_mapping)

 

# 나이 bining
for dataset in train_test_data :
    dataset.loc[ dataset['Age'] <= 16, 'Age'] = 0,
    dataset.loc[(dataset['Age'] > 16) & (dataset['Age'] <=26), 'Age'] = 1,
    dataset.loc[(dataset['Age'] > 26) & (dataset['Age'] <=36), 'Age'] = 2,
    dataset.loc[(dataset['Age'] > 36) & (dataset['Age'] <=62), 'Age'] = 3,
    dataset.loc[ dataset['Age'] > 62, 'Age'] = 4

위와 같이 Feature engineering을 마친 최종 데이터셋은 아래와 같다. 추가로 숫자로 치환하는 방법 중 scikit-learn과 pandas에서 제공하는 는 함수를 소개하고자 한다.

 

# Feature engineering
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OneHotEncoder

## Case1 - 라벨 인코더 : 각각 value에 직접 라벨을 입히는 것을 자동으로 해준다.
label_encoder = LabelEncoder()
integer_encoded = label_encoder.fit_transform(train.Sex.values)
integer_encoded

## Case2 - 원핫 인코더 : 구분해야하는 라벨을 열로 지정하고 그에 해당하는 경우 1 그렇지 않은 경우 0으로 표시하는 방법
onehot_encoder = OneHotEncoder(sparse = False)
integer_encoded = integer_encoded.reshape(len(integer_encoded),1)
integer_encoded

onehot_encoded = onehot_encoder.fit_transform(integer_encoded)
onehot_encoded

## Case3 - pd.get_dumies : 원핫 인코더를 바로 적용해주는 편리한 함수
pd.get_dumies(train.Sex)

### Case3로 치환한 값 train dataset에 합치기
df = pd.get_dumies(train.Sex, prefix = train.Sex.name, dummy_na =True)
pd.concat([train,df], axis = 1 ) # axis가 1일 경우 열, 0일 경우 행에 합침

 

3. 모델 적용 및 타당성 검증

예측에 사용될 다양한 모델들이다. 각각 사용해보면서 값을 비교해보았다.

# Importing classifier modules 
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.svm import SVC

import numpy as np

 

3.1. 모델 타당성 평가 - K-fold 교차 검증

train data를 학습하여 생성한 모델을 평가하는 방법 중 하나이다. train data를 K개로 분할하여 모델을 적용한 후 결과값을 기존의 train data의 결과값과 비교하여 accuracy를 산정한다. 이번 문제에서는 다양한 모델을 적용해보고 K-fold 교차 검증을 통해 각 각 모델의 평균 accuracy를 비교해보고자 한다.

# K-fold Cross-validation
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
k_fold = KFold(n_splits=10, shuffle=True, random_state=0)

 

3.2. 모델 적용

KNN - 최근접 이웃 알고리즘 : target의 위치에서 가장 가까운 K개 이웃의 비율로 값을 예측

clf = KNeighborsClassifier(n_neighbors = 13)
scoring = 'accuracy'
score = cross_val_score(clf, train_data, target, cv=k_fold, n_jobs=1, scoring=scoring)
round(np.mean(score)*100, 2)

 

Decisiom Tree : 쉽게 말해 일종의 스무고개 질문을 잘 설계한다면 좋은 질문을 골라낸다면 성과가 좋을 것이다.

clf = DecisionTreeClassifier()
scoring = 'accuracy'
score = cross_val_score(clf, train_data, target, cv=k_fold, n_jobs= 1, scoring = scoring)
round(np.mean(score)*100,2)

 

RadomForest : 여러 결정 트리들이 내린 예측 값들 중 가장 많이 나온 값을 최종 예측값으로 선정하는 방법

clf = RandomForestClassifier(n_estimators=13)
scoring = 'accuracy'
score = cross_val_score(clf, train_data, target, cv=k_fold, n_jobs=1, scoring=scoring)
print(score)

 

Naive Bayes : 확률이론을 바탕으로 하는 방법, 추후에 따로 정리할 예정

clf = GaussianNB()
scoring = 'accuracy'
score = cross_val_score(clf, train_data, target, cv=k_fold, n_jobs=1, scoring=scoring)
print(score)

 

SVM : 경계를 설정하고 그에 따라 결과값을 구분하는 방법, 추후에 따로 정리할 예정

clf = SVC()
scoring = 'accuracy'
score = cross_val_score(clf, train_data, target, cv=k_fold, n_jobs=1, scoring=scoring)
print(score)

총 5개의 모델을 적용한 결과 SVM 모델을 적용했을때 교차검증 시 accuracy의 평균값이 가장 높았다. 따라서 해당 모델을 test dataset에 적용하여 결과값을 산출하였다.

 

마치며..

처음 접했던 캐글 문제로 분석과제를 해결할때 어떤 순서와 방법론을 통해 진행하는지 감을 익힐 수 있었다. 추가로 사용된 모델에 대해 구체적으로 공부하여 주요 파라미터 정도는 알아둬야겠다.

 

 

'study' 카테고리의 다른 글

스타벅스 이디야 매장 수 비교  (2) 2020.03.19
러닛 - 우주 최초 플립러닝 플랫폼  (0) 2020.03.16
Database 기초  (0) 2020.03.14
[Kaggle] Survival on the Titanic  (0) 2020.03.11
카카오톡 채팅 분석  (0) 2020.03.10
[자격증] 데이터분석 준전문가  (0) 2019.12.28