Kaggle 타이타닉 생존율 예측

Kaggle 타이타닉 생존율 예측 머신러닝 문제를 풀어봅니다.

# Machine Learning
title

준비

  • Python 3 개발 환경

본 글에서는 Jupyter Notebook 을 사용하여 실습을 진행합니다.





Kaggle

먼저 Kaggle 에 접속해서 새 계정을 생성합니다.

풀어볼 문제 Titanic - Machine Learning from Disaster 에 접속하여 참가합니다.

Data 섹션에서 필요한 데이터셋을 모두 다운로드합니다.

  • gender_submission.csv
  • test.csv
  • train.csv

실습을 위한 디렉토리에 데이터셋을 구성합니다.





데이터셋 분석

필요한 모듈들을 가져옵니다. (설치 과정은 생략)

import pandas as pd
import numpy as np

필요한 데이터셋을 불러와서 확인합니다.

train = pd.read_csv('train.csv')
test = pd.read_csv('test.csv')
print(train.shape)
print(test.shape)
train.head()
test.head()

데이터셋 정보 확인

print(train.info())
print(test.info())

유실된 데이터 확인

print(train.isnull().sum())
print(test.isnull().sum())

데이터셋 설명 (참고용)

  • Survived : 0이면 사망, 1이면 생존
  • Pclass : 선실 등급
  • SibSp : 배우자 형제 동행 수
  • Parch : 부모 or 아이 동행 수
  • Fare : 선실당 요금
  • Cabin : 짐칸
  • Embarked : 선착장





시각화

필요한 모듈들을 가져옵니다.

import matplotlib.pyplot as plt
import seaborn as sns

원 그래프를 그리는 함수를 작성합니다.

def pie_chart(feature):
  feature_ratio = train[feature].value_counts(sort=False)
  feature_size = feature_ratio.size
  feature_index = feature_ratio.index
  survived = train[train['Survived'] == 1][feature].value_counts()
  dead = train[train['Survived'] == 0][feature].value_counts()

  plt.plot(aspect='auto')
  plt.pie(feature_ratio, labels=feature_index, autopct='%1.1f%%')
  plt.title(feature + '\'s ratio in total')
  plt.show()

  for i, index in enumerate(feature_index):
    plt.subplot(1, feature_size + 1, i + 1, aspect='equal')
    plt.pie([survived[index], dead[index]], labels=['Survivied', 'Dead'], autopct='%1.1f%%')
    plt.title(str(index) + '\'s ratio')
  plt.show()

Sex 칼럼 시각화

pie_chart('Sex')

Sex 원 그래프



막대 그래프를 그리는 함수를 작성합니다.

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))

Pclass 칼럼 시각화

bar_chart('Pclass')

Pclass 막대 그래프





데이터 전처리

두 데이터셋을 병합하고 Name 칼럼에서 Mr., Mrs. 등의 문자열을 추출하여 Title 칼럼에 넣습니다.

train_and_test = [train, test]

for dataset in train_and_test:
  dataset['Title'] = dataset.Name.str.extract(' ([A-Za-z]+)\.')

Title 과 Sex 별 승객 수 출력

pd.crosstab(train['Title'], train['Sex'])

Title 카테고리 분류

for dataset in train_and_test:
  dataset['Title'] = dataset['Title'].replace(
    ['Capt', 'Col', 'Countess', Don','Dona', 'Dr', 'Jonkheer', 'Lady','Major', 'Rev', 'Sir'],
    'Other',
  )
  dataset['Title'] = dataset['Title'].replace('Mlle', 'Miss')
  dataset['Title'] = dataset['Title'].replace('Mme', 'Mrs')
  dataset['Title'] = dataset['Title'].replace('Ms', 'Miss')

train[['Title', 'Survived']].groupby(['Title'], as_index=False).mean()

string 형으로 변환

for dataset in train_and_test:
  dataset['Title'] = dataset['Title'].astype(str)
  dataset['Sex'] = dataset['Sex'].astype(str)

NaN 을 포함한 Embarked 데이터 갯수를 확인하고 Nan 값을 모두 'S' 로 대체합니다.

print(train.Embarked.value_counts(dropna=False))

for dataset in train_and_test:
  dataset['Embarked'] = dataset['Embarked'].fillna('S').astype(str)

Age 의 NaN 값은 승객들 나이의 평균 값으로 대체하고 연령대별 생존율을 출력합니다.

for dataset in train_and_test:
  dataset['Age'].fillna(dataset['Age'].mean(), inplace=True)
  dataset['Age'] = dataset['Age'].astype(int)
  train['AgeBand'] = pd.cut(train['Age'], 5)
print(train[['AgeBand', 'Survived']].groupby(['AgeBand'], as_index=False).mean())

Fare 의 Nan 값은 평균 값인 13.675 로 대체합니다.

for dataset in train_and_test:
  dataset['Fare'] = dataset['Fare'].fillna(13.675)



Binning 기법

여러 종류의 데이터에 대해 범위를 지정하거나 카테고리를 통해 이전보다 작은 수의 그룹으로 만드는 방법.

for dataset in train_and_test:
  dataset['Embarked'] = dataset['Embarked'].fillna(dataset['Age'].mean())
for dataset in train_and_test:
  dataset.loc[dataset['Age'] <= 16, 'Age'] = 0
  dataset.loc[(dataset['Age'] > 16) & (dataset['Age'] <= 32), 'Age'] = 1
  dataset.loc[(dataset['Age'] > 32) & (dataset['Age'] <= 48), 'Age'] = 2
  dataset.loc[(dataset['Age'] > 48) & (dataset['Age'] <= 64), 'Age'] = 3
  dataset.loc[dataset['Age'] > 64, 'Age'] = 4
  dataset['Age'] = dataset['Age'].map(
    {
      0: 'Child',
      1: 'Young',
      2: 'Middle',
      3: 'Prime',
      4: 'Old'
    }
  ).astype(str)
for dataset in train_and_test:
  dataset.loc[dataset['Fare'] <= 7.854, 'Fare'] = 0
  dataset.loc[(dataset['Fare'] > 7.854) & (dataset['Fare'] <= 10.5), 'Fare'] = 1
  dataset.loc[(dataset['Fare'] > 10.5) & (dataset['Fare'] <= 21.679), 'Fare'] = 2
  dataset.loc[(dataset['Fare'] > 21.679) & (dataset['Fare'] <= 39.688), 'Fare'] = 3
  dataset.loc[dataset['Fare'] > 39.688, 'Fare'] = 4
  dataset['Fare'] = dataset['Fare'].astype(int)
for dataset in train_and_test:
  dataset['Family'] = dataset["Parch"] + dataset["SibSp"]
  dataset['Family'] = dataset['Family'].astype(int)

사용하지 않을 데이터는 제거합니다.

features_drop = ['Name', 'Ticket', 'Cabin', 'SibSp', 'Parch']

train = train.drop(features_drop, axis=1)
test = test.drop(features_drop, axis=1)
train = train.drop(['PassengerId', 'AgeBand'], axis=1)



원-핫 인코딩 (One-Hot Encoding)

컴퓨터의 데이터 처리를 위해 0과 1로 데이터를 구별하는 인코딩입니다.

본 글에서 사용할 scikit-learn 라이브러리의 머신러닝 알고리즘은 문자열을 입력 값으로 허용하지 않기 때문에 숫자형으로 인코딩하는 전처리 작업이 필요합니다.

train = pd.get_dummies(train)
test = pd.get_dummies(test)

train_label = train['Survived']
train_data = train.drop('Survived', axis=1)
test_data = test.drop("PassengerId", axis=1).copy()





학습

필요한 모듈들을 가져옵니다.

from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.utils import shuffle

데이터 셔플

train_data, train_label = shuffle(train_data, train_label, random_state = 5)

모델 학습 적용

def train_and_test(model):
  model.fit(train_data, train_label)
  prediction = model.predict(test_data)
  accuracy = round(model.score(train_data, train_label) * 100, 2)
  print("Accuracy: ", accuracy, "%")
  return prediction





예측

알고리즘별 예측 결과를 확인합니다.

# Logistic Regression
log_pred = train_and_test(LogisticRegression())

# SVM
svm_pred = train_and_test(SVC())

# KNN
knn_pred = train_and_test(KNeighborsClassifier(n_neighbors = 4))

# Random Forest
rf_pred = train_and_test(RandomForestClassifier(n_estimators = 100))

# Navie Bayes
nb_pred = train_and_test(GaussianNB())

제출을 위해 정확도가 제일 높은 알고리즘의 예측 값을 csv 파일로 저장합니다.

submission = pd.DataFrame(
  {
    "PassengerId": test["PassengerId"],
    "Survived": rf_pred
  }
)
submission.to_csv('submission_rf.csv', index=False)





제출

submission_rf.csv 파일이 생성되면 페이지에서 Submit Predictions 을 클릭하고 업로드 후 제출합니다.

제출 결과

제출 결과

비록 점수는 낮지만 성공적으로 완료한 것 같습니다.







읽어주셔서 감사합니다.

😍  댓글