본문 바로가기

Machine, Deep Learning/Machine, Deep Learning 실습

Kaggle - 타이타닉 생존여부 예측 모델 생성 (1)

반응형
SMALL
  • 본 글은 머신러닝, 데이터 사이언스를 처음 접하는 이(본인)를 위한 Kaggle의 튜토리얼을 하는 글입니다.
  • 본 글에선 python을 사용할 것이고 라이브러리론 시각화 도구(matplotlib, seaborn, plotly), 데이터 분석 도구(pandas, numpy), 머신 러닝 도구(sklearn)을 사용할 것입니다.
  • 본 글에선 타이타닉에 탑승한 사람들의 신상정보를 활용하여, 승선한 사람들의 생존여부를 예측하는 모델을 생성할 것입니다.
import numpy as np
import pandas as pd
# pandas는 Python에서 테이블화 된 데이터를 다루는 데 가장 최적화되어 있는 라이브러리입니다.
# Python으로 데이터분석을 한다고 하면 반드시 능숙해져야 할 라이브러리이니, 여러 커널들을 공부하시면서 사용법에 익숙해져야 합니다.
import matplotlib.pyplot as plt
import seaborn as sns # seaborn은 matplotlib에 기반을 둔 Python data visualization library이다.

plt.style.use('seaborn')
sns.set(font_scale=2.5)
# matplotlib의 기본 scheme 말고 seaborn scheme를 세팅하고, 
# 일일이 graph 의 font size를 지정할 필요 없이 seaborn의 font_scale을 사용하면 편하다.

import missingno as msno # conda install -c conda-forge missingno로 conda prompt에서 설치해야 합니다.

#ignore warnings
import warnings
warnings.filterwarnings('ignore')

%maplotlib inline

앞으로 해야할 프로세스는 아래와 같습니다.


  1. 데이터셋 확인 - 대부분의 캐글 데이터들은 잘 정제되어 있지만, 가끔 null data가 존재한다. 이를 확인하고, 향후 수정합니다.
  2. 탐색적 데이터 분석(exploratory data analysis) - 여러 feature들을 개별적으로 분석한 뒤, feature 들 간의 상관관계를 확인합니다. 여러 시각화 툴을 사용하여 insight를 얻습니다.
  3. feature engineering - 모델을 세우기에 앞서, 모델의 성능을 높일 수 있도록 feature 들을 engineering 합니다. one-hot encoding, class로 나누기, 구간으로 나누기, 텍스트 데이터 처리 등을 합니다.
  4. model 만들기 - sklearn을 사용해 모델을 만듭니다. 파이썬에서 머신러닝을 할 때는 sklearn을 사용하면 수많은 알고리즘을 일관된 문법으로 사용할 수 있습니다. 물론 딥러닝을 위해 tensorflow, pytorch 등을 사용할 수도 있습니다.
  5. 모델 학습 및 예측 - trainset을 가지고 모델을 학습시킨 후, testset을 가지고 prediction 합니다.
  6. 모델 평가 - 예측 성능이 원하는 수준인지 판단합니다. 풀려는 문제에 따라 모델을 평가하는 방식도 달라집니다. 학습된 모델이 어떤 것을 학습했는지 확인해 봅니다.

1. Dataset Check

파이썬에서 테이블화 된 데이터를 다루는 데 가장 최적화되어 있으며, 많이 쓰이는 라이브러리는 pandas 입니다. pandas를 사용하여 데이터셋의 간단한 통계적 분석부터, 복잡한 처리들을 간단한 메소드를 사용하여 해낼 수 있습니다.

파이썬으로 데이터분석을 한다고 하면 반드시 능숙해져야 할 라이브러리이니, 여러 커널들을 공부하시면서 사용법에 익숙해져야 합니다.

캐글에서 데이터셋은 보통 train, testset 으로 나뉘어 있습니다.

df_train = pd.read_csv('input/train.csv')
df_test = pd.read_csv('input/test.csv')
# input 폴더가 코드 실행하는 파일과 같은 위치에 있습니다.
# df는 dataframe의 약자입니다.
df_train.head()

여기서 다루는 문제에서 feature는 Pclass(티켓의 클래스), Age(나이), silbSp(함께 탑승한 형제와 배우자의 수), parch(함께 탑승한 부모, 아이의 수), fare(탑승료) 이며, 예측하려는 target label은 Survived입니다. Survived가 0 또는 1인 것을 보면 one-hot encoding인걸 알 수 있습니다.

변수(feature, variable) 정의 설명 타입
survival 생존여부 targe label / 1 or 0 integer
Pclass 티켓의 클래스 1=1st, 2=2nd, 3=3rd categorical feature(범주형) integer
sex 성별 male, female string
Age 나이 continuous(연속적) integer
sibSp 함께 탑승한 형제와 배우자의 수 quantitative(정량적) integer
parch 함께 탑승한 부모, 아이의 수 quantitative integer
ticket 티켓 번호 alphabat + integer string
fare 탑승료 continuous float
cabin 객실 번호 alphabat + integer string
embared 탑승 항구 C=Cherbourg Q=Queenstown S=Southampton string

pandas dataframe 에는 describe() 메소드가 있는데, 이를 쓰면 각 feature가 가진 통계치를 반환해줍니다.

df_train.describe()

df_test.describe()

테이블에서 보다시피, PassengerId 숫자와 다른, null data가 존자하는 열(feature)가 있는 것 같다. 왜냐하면 전체 갯수는 891개인데, 나이의 갯수가 714개이기 때문입니다. 이를 좀 더 보기 편하도록 그래프를 시각화해서 살펴봅시다.

1.1 Null Data Check

print(df_train.columns)
Index(['PassengerId', 'Survived', 'Pclass', 'Name', 'Sex', 'Age', 'SibSp',
       'Parch', 'Ticket', 'Fare', 'Cabin', 'Embarked'],
      dtype='object')

for col in df_train.columns:
	msg = 'column: {:>10}\t Percent of NaN value : {:.2f}%'.format(
    col, 100 * (df_train[col].isnull().sum() / df_train[col].shape[0])
    )
    print(msg)

for col in df_test.columns:
    msg = 'column: {:>10}\t Percent of NaN value: {:.2f}%'.format(
    col, 100 * (df_test[col].isnull().sum() / df_test[col].shape[0])
    )
    print(msg)

Train, Test set 에서 Age(둘다 약 20%), Cabin(둘다 약 80%), Embarked(Train만 0.22%) null data가 존재하는 것을 볼 수 있습니다. missingno 라는 라이브러리를 사용하면 null data의 존재를 더 쉽게 볼 수 있습니다.

msno.matrix(df=df_train.iloc[:, :], figsize=(8, 8), color=(0.8, 0.5, 0.2))
# msno.matrix 행렬 형태로 데이터를 보여줍니다.
# msno.bar 바 형태로 데이터를 보여줍니다.
# figsize=(가로 길이, 세로 길이)
# color = (R, G, B) # (1, 1, 1)이 흰색입니다.

msno.bar(df=df_train.iloc[:, :], figsize=(8, 8), color=(0.8, 0.5, 0.2))

msno.bar(df=df_test.iloc[:, :], figsize=(8, 8), color=(0.8, 0.5, 0.2))

1.2 Target label Check

target label이 어떤 distribution을 가지고 있는 지 확인해야 합니다. 지금 같은 binary classification 문제의 경우에서, 1과 0의 분포가 어떠냐에 따라 모델의 평가 방법이 달라질 수 있습니다.

f, ax = plt.subplots(1, 2, figsize=(18, 8))

df_train['Survived'].value_counts().plot.pie(explode=[0, 0.1], autopct='%1.1f%%', ax=ax[0], shadow=True)
ax[0].set_title('Pie plot - Survived')
ax[0].set_ylabel('')
sns.countplot('Survived', data=df_train, ax=ax[1])
ax[1].set_title('Count plot - Survived')

plt.show()

안타깝게도 죽은 사람이 많습니다. 38.4 %가 살아남았습니다. traget label의 분포가 제법 균일합니다. 불균일한 경우, 예를 들어 100 중 1이 99, 0이 1개인 경우엔 모델이 모든것을 1이라 해도 정확도가 99%가 나오게 됩니다. 0을 찾는 문제라면 이 모델은 원하는 결과를 줄 수 없는데, 지금 문제에서는 그렇지 않으니 진행을 하겠습니다.

2. Exploratory Data Analysis

본격적인 데이터 분석을 할 차례입니다. 이렇게 수많은 데이터 안에서 숨겨진 가치를 찾으려면 적절한 시각화가 필요합니다. 시각화 라이브러리는 matplotlib, seaborn, plotly 등이 있는데, 특정 목적에 맞는 소스코드를 정리해두어 필요할 때마다 참고하면 편합니다.


 탐색적 데이터 분석의 목적은 데이터를 이해하는 것입니다. 목적 달성을 위한 가장 쉬운 방법은 질문을 잘 만들어 이를 탐색과정을 거쳐 결국 데이터를 표현하는 적절한 모형, 시각화 산출물, 다음 과정을 위한 데이터를 생성해내는 것입니다.

 질문의 질은 결국 질문의 양에 비례합니다. 데이터에 대해 아는 것이 없기 때문에 질문의 질을 최대한 빨리 높이는 길은 한정된 시간에 가능하면 많은 질문을 생성해 내고, 탐색과정을 거쳐 최대한 빨리 좋은 질문을 생성해 내는 것입니다.


2.1 Pclass

Pclass(티켓의 클래스)에 대해서 살펴보겠습니다. Pclass는 ordinal, 서수형 데이터입니다. 카테고리이면서도 순서가 있는 데이터 타입입니다. 먼저 Pclass에 따른 생존률의 차이를 살펴야합니다. 엑셀의 피벗 차트와 유사한 작업을 하게 되는데, pandas dataframe 에서는 groupby를 사용하면 쉽게 할 수 있습니다. 또한, pivot이라는 메소드도 있습니다.

'Pclass', 'Survived'를 가져온 후, pclass로 묶습니다. 그러고 나면 각 pclass 마다 0, 1이 count가 되는데, 이를 평균내면 각 pclass 별 생존율을 뽑을 수 있습니다.

아래와 같이 count()를 하면, 각 class에 몇명이 있는 지 확인할 수 있으며, sum()을 하면, 216명 중 생존한 사람의 총합을 주게 됩니다.

df_train[['Pclass', 'Survived']].groupby(['Pclass'], as_index=True).count()

df_train[['Pclass', 'Survived']].groupby(['Pclass'], as_index=True).sum()

pandas의 crosstab을 사용하면 좀 더 위 과정을 수월하게 확인할 수 있습니다.

pd.crosstab(df_train['Pclass'], df_train['Survived'], margins=True).style.background_gradient(cmap='summer_r')

grouped 객체에 mean()을 하게 되면, 각 클래스별 생존율을 얻을 수 있습니다. class 1이면 80/(80 + 136)과 같습니다. (약 0.63)

df_train[['Pclass', 'Survived']].groupby(
['Pclass'], as_index=True).mean().sort_values(by='Survived', ascending=False
).plot.bar()
# .plot.bar()가 없으면 그냥 표로 표시된다. 있으면 그래프로 표현해준다.

보다시피, Pclass가 좋을 수록(1st) 생존율이 높은 것을 확인할 수 있습니다. 좀 더 보기 쉽게 그래프를 그려보겠습니다. seaborn의 countplot을 이용하면, 특정 label에 따른 개수를 확인해볼 수 있습니다.

y_position = 1.02
# 타이틀이 그래프 위에 얼마나 떨어졌는지 정하는 상수 값입니다.
f, ax = plt.subplots(1, 2, figsize=(18, 8))
#ax[0]은 왼쪽 그래프를 뜻하고, ax[1]은 오른쪽 그래프를 뜻합니다.
df_train['Pclass'].value_counts().plot.bar(color=[0, 0, 0], ax=ax[0])
# ax[0]이므로 왼쪽에 그래프를 그립니다.
ax[0].set_title('Number of Passengers By Pclass', y=y_position)
ax[0].set_ylabel('Count')
sns.countplot('Pclass', hue='Survived', data=df_train, ax=ax[1])
# ax[1]이므로 오른쪽에 그래프를 그립니다.
ax[1].set_title('Pclass: Survived vs Dead', y=y_position)
plt.show()

클래스가 높을 수록 생존 확률이 높은걸 확인할 수 있고, Pclasss 1, 2, 3 순서대로 63%, 48%, 25%입니다. 우리는 생존에 Pclass가 큰 영향을 미친다고 생각해볼 수 있으며, 나중에 모델을 세울 때 이 feature를 사용하는 것이 좋을 것이라 판단할 수 있습니다.

2.2 Sex

이번엔 성별로 생존률이 어떻게 달라지는지 확인해보겠습니다. 마찬가지로 pandas groupby와 seaborn countplot을 사용해서 시각화 해보려 합니다.

f, ax = plt.subplots(1, 2, figsize=(18, 8))
df_train[['Sex', 'Survived']].groupby(['Sex'], as_index=True).mean().plot.bar(ax=ax[0])
ax[0].set_title('Survived vs Sex')
sns.countplot('Sex', hue='Survived', data=df_train, ax=ax[1])
ax[1].set_title('Sex: Survived vs Dead')
plt.show()

보다시피, 여자가 생존할 확률이 높습니다.

df_train[['Sex', 'Survived']].groupby(['Sex'], as_index=False).mean().sort_values(by='Survived', ascending=False)

pd.crosstab(df_train['Sex'], df_train['Survived'], margins=True).style.background_gradient(cmap='summer_r')

Pclass와 마찬가지로 Sex도 예측 모델에 쓰일 중요한 feature 임을 알 수 있습니다.

2.3 Both Sex and Pclass

이번엔 Sex, Pclass 두가지에 관하여 생존이 어떻게 달라지는 지 확인해 보려합니다. seaborn의 factorplot을 이용하면, 손쉽게 3개의 차원으로 이루어진 그래프를 그릴 수 있습니다.

sns.factorplot('Pclass', 'Survived', hue='Sex', data=df_train, size=6, aspect=1.5)

모든 클래스에서 female이 살 확률이 male보다 높은 걸 알 수 있습니다. 또한 남자, 여자 상관없이 클래스가 높을 수록 살 확률이 높습니다. 위 그래프는 hue 대신 column으로 하면 아래와 같습니다.

sns.factorplot(x='Sex', y='Survived', col='Pclass', data=df_train, satureation=.5, size=9, aspect=1)

2.4 Age

이번엔 Age featrue을 살펴봅시다.

print('제일 나이 많은 탑승객 : {:.1f} Years'.format(df_train['Age'].max())
print('제일 어린 탑승객 : {:.1f} Years'.format(df_train['Age'].min())
print('탑승객 평균 나이 : {:.1f} Years'.format(df_train['Age'].mean())

생존에 따른 Age의 histogram을 그려봅시다.

fig, ax = plt.subplots(1, 1, figsize = (9, 5))
sns.kdeplot(df_train[df_train['Survived'] == 1]['Age'], ax=ax)
sns.kdeplot(df_train[df_train['Survived'] == 0]['Age'], ax=ax)
plt.legend(['Survived == 1', 'Survived == 0'])
plt.show()

보다시피 나이가 어릴 수록 생존자가 많음을 알 수 있습니다.

class가 높을 수록 나이 많은 사람의 비중이 커짐

나이대가 변하면서 생존률이 어떻게 되는지 보려고 합니다. 나이범위를 점점 넓혀가며, 생존률이 어떻게 되는지 한번 봅시다.

cummulate_survival_ratio = []
for i in range(1, 80):
	cummulate_survival_ratio.append(df_train[df_train['Age'] < i]['Survived'].sum() / len(
    df_train[df_train['Age'] < i]['Survived']))

plt.figure(figsize=(7, 7))
plt.plot(cummulate_survival_ratio)
plt.title('Survival rate change depending on range of Age', y=1.02)
plt.xlabel('Range of Age(0~x)')
plt.ylabel('Survival rate')
plt.show()

보다시피 나이가 어릴수록 생존률이 높은 것을 확인할 수 있습니다. 이 나이도 역시 중요한 feature로 쓰일 수 있다는 것을 확인했습니다.

2.5 Pclass, Sex, Age

지금까지 본, Sex, Pclass, Age, Survived 모두에 대해서 보고싶지 않나여? 이것을 쉽게 해주는 것이 seaborn의 violinplot입니다. x 축은 우리가 나눠서 보고 싶어하는 case(여기선 Pclass, Sex)를 나타내고, y 축은 보고 싶어하는 distribution(Age)입니다.

f,ax=plt.subplots(1, 2, figsize=(18,8))
sns.violinplot("Pclass", "Age", hue="Survived", data=df_train, scale="count", split=True,
	ax=ax[0])
# scale은 바이올린처럼 생긴 그래프가 어떤 모양과 너비를 가질지를 정하는 변수이다.
# count, width, area 3가지가 있다.
# count는 스케일이 숫자 비율에 따라서 달라진다.
# width는 각 바이올린이 같은 너비를 가지게 된다.
# area는 각 바이올린 그래프가 같은 area를 가지게 된다.
ax[0].set_title('Pclass and Age vs Survived')
ax[0].set_yticks(range(0, 110, 10))
sns.violinplot("Sex", "Age", hue="Survived", data=df_train, scale='count', split=True,
	ax=ax[1])
# hue는 카테고리형 데이터가 섞여 있을 때 hue 인수에 카테고리 변수 이름을 지정하여
# 카테고리 값에 따라 색상을 다르게 할 수 있다.
ax[1].set_title('Sex and Age vs Survived')
ax[1].set_yticks(range(0,110,10))
plt.show()

왼쪽 그림은 Pclass별로 Age의 distribution이 어떻게 다른지, 거기에 생존여부에 따라 구분한 그래프입니다. 오른쪽 그림도 마찬가지로 Sex, 생존에 따른 distribution이 어떻게 다른지 보여주는 그래프입니다. 생존만 봤을 때, 모든 클래스에서 나이가 어릴 수록 생존을 많이 한 것을 볼 수 있습니다. 오른쪽 그림을 보면 여자가 생존을 많이 한 것을 볼 수 있습니다.

즉, 여성과 아이를 먼저 챙긴 것을 알 수 있다.

2.6 Embarked

Embarked는 탑승한 항구를 나타낸다. 위에서 해왔던 것과 비슷하게 탑승한 곳에 따른 생존율을 확인해보겠습니다.

f,ax=plt.subplots(1,1,figsize=(7,7))
df_train[['Embarked', 'Survived']].groupby(['Embarked'], as_index=True).mean().sort_values(
	by='Survived', ascending=False).plot.bar(ax=ax)

 조금의 차이는 있지만 C가 제일 생존율이 높습니다. 모델에 큰 영향을 미칠진 모르겠지만, 그래도 사용할 만합니다. 사실, 모델을 만들고 나면 우리가 사용한 feature 들이 얼마나 중요한 역할을 했는지 확인해볼 수 있습니다. 이는 추후에 모델을 만들고 확인해봅시다.

 다른 feature로 split하여 한번 살펴보겠습니다.

f,ax=plt.subplots(2,2,figsize=(20,15))
# 2x2행렬 그래프를 그린다.
sns.countplot('Embarked', data=df_train, ax=ax[0,0])
ax[0,0].set_title('(1) No. Of Passengers Boarded')
sns.countplot('Embarked', data=df_train, hue='Sex', ax=ax[0,1])
ax[0,1].set_title('(2) Male-Female Split for Embarked')
sns.countplot('Embarked', hue='Survived', data=df_train, ax=ax[1,0])
ax[1,0].set_title('(3) Embarked vs Survived')
sns.countplot('Embarked', data_df_train, hue='Pclass', ax=ax[1,1])
ax[1,1].set_title('(4) Embarked vs Pclass')
plt.subplots_adjust(wspace=0.2, hspace=0.5)
plt.show()

Figure(1) - 전체적으로 봤을 때, S 에서 가장 많은 사람이 탑승했습니다.

Figure(2) - C와 Q는 남녀 비율이 비슷하고, S는 남자가 더 많이 탑승했습니다.

Figure(3) - 생존 확률은 S에서 가장 낮은 것을 확인할 수 있습니다.

Figure(4) - Class로 split 해서 보니, C가 생존확률이 높은건 클래스가 높은 사람이 많이 타서 그렇습니다. S는 3rd class가 많아서 생존율이 낮게 나옵니다.

2.7 Family - SibSp(형제 자매) + Parch(부모, 자녀)

SibSp와 Parch가 합치면 가족(Family)가 되겠죠? Family로 합쳐서 분석해봅시다.

df_train['FamilySize'] = df_train['SibSp'] + df_train['Parch'] + 1 # 자신을 포함해야하니 1을 더합니다.
df_train['FamilySize'] = df_test['SibSp'] + df_test['Parch'] + 1 # 역시 자신을 포함해야하니 1을 더합니다.
# 딕셔너리에서 새로운 밸류 값을 가지는 키를 만드는 것입니다.
print("Maximum size of Family : ", df_train['FamilySize'].max())
print("Minimum size of Family : ", df_train['FamilySize'].min())

FamilySize와 생존의 관계를 한번 살펴보도록 합시다.

f,ax=plt.subplots(1, 3, figsize=(40, 10))
sns.countplot('FamilySize', data=df_train, ax=ax[0])
# 제일 앞에 원래라면 x='FamilySize'라고 해야지만 'x='이 생략되었다.
# 저 뜻은 엑셀에서 구분 짓는 어떤 스키마를 지정해준다는 뜻이다.
ax[0].set_title('(1) No. Of Passengers Boarded', y=1.02)

sns.countplot('FamilySize', hue='Survived', data=df_train, ax=ax[1])
ax[1].set_title('(2) Survived countplot depending on FamilySize', y=1.02)

df_Train[['FamilySize', 'Survived']].groupby(['FamilySize'], ax_index=True).mean().sort_values(
	by='Survived', ascending=False).plot.bar(ax=ax[2])
ax[2].set_title('(3) Survived rate depending on FamilySize', y=1.02)

plt.subplots.adjust(wspace=0.2, hspace=0.5)
plt.show()

Figure (1) - 가족 크기가 1~11까지 있음을 확인할 수 있습니다. 대부분이 1명이고 그 다음으로 2, 3, 4명 순입니다.

Figure (2), (3) - 가족 크기에 따른 생존비교입니다. 가족이 4명인 경우가 가장 생존 확률이 높습니다. 가족수가 많아질 수록(5, 6, 7, 8, 11) 생존확률이 낮아지네요. 가족수가 너무 작아도(1), 너무 커도(5, 6, 8, 11) 생존확률이 작은걸 볼 수 있습니다. 3~4명 선에서 생존확률이 높은 것을 알 수 있습니다.

2.8 Fare

Fare는 탑승요금이며, countious feature 입니다. 한번 histogram(도수 분포표)을 그려볼까요?

f, ax=plt.subplots(1, 1, figsize=(8,8))
g = sns.displot(df_train['Fare'].color='b', label='Skewness : {:.2f}'.format(df_train['Fare'].skew()), ax=ax)
g = g.legend(loc='best')

보시다시피, distribution이 매우 비대칭인 것을 알 수 있습니다.(high skewness) 만약 이대로 모델에 넣어준다면 자칫 모델이 잘못 학습할 수도 있습니다. 몇개 없는 outlier에 대해서 너무 민감하게 반응한다면, 실제 예측 시에 좋지 못한 결과를 부를 수 있습니다.

outlier의 영향을 줄이기 위해 Fare에 log를 취하겠습니다.

여기서 우리는 pandas의 유용한 기능을 사용할 것입니다. dataFrame의 특정 columns에 공통된 작업(함수)를 적용하고 싶으면 아래의 map, 또는 apply를 사용하면 매우 손쉽게 적용할 수 있습니다.

우리가 원하는 것은 Fare coluns의 데이터 모두를 log 값 취하는 것인데, 파이썬의 간단한 lambda 함수를 이용해 간단한 로그를 적용하는 함수를 map에 인수로 넣어주면, Fare columns 데이터에 그대로 적용이 됩니다. 매우 유용한 기능이에요 !!

df_test.loc[df_test.Fare.isnull(), 'Fare'] = df_test['Fare'].mean()
# testset에 있는 nan value를 평균값으로 치환합니다.

df_train['Fare'] = df_train['Fare'].map(lambda i : np.log(i) if i>0 else 0)
df_test['Fare'] = df_test['Fare'].map(lambda i : np.log(i) if i>0 else 0)
f, ax = plt.subplots(1, 1, figsize=(8, 8))
g = sns.distplot(df_train['Fare'], color='b', label='Skewness : {:.2f}'.format(
	df_train['Fare'].skew()), ax=ax)
g = g.legend(loc='best')

전체적으로 log를 취하니, 비대칭성이 많이 사라진 것을 볼 수 있습니다. 이런 작업을 사용해 모델이 좀 더 좋은 성능을 내도록 할 수 있다는 점을 기억해야 합니다.

사실 방금한 것은 feature engineering에 들어가는 부분인데, 여기서 작업을 했네요.

모델을 학습시키기 위해, 그리고 그 모델의 성능을 높이기 위해 feature들에 여러 조작을 가하거나, 새로운 feature를 추가하는 것을 feature engineering이라고 하는데, 우리는 이제 그것을 살펴보도록 합시다.

2.9 Cabin

이 feature는 NaN이 대략 80% 이므로, 생존에 영향을 미칠 중요한 정보를 얻어내기가 쉽지는 않습니다. 그러므로 우리가 세우려는 모델엔 포함시키지 않도록 합시다.

msno.bar(df=df_train.iloc[:, :], figsize=(8, 8), color=(0,0,0))
# 이 코드로 Cabin의 Null 값이 얼마나 차지하는지를 확인할 수 있습니다.

 2.10 Ticket

이 feature는 NaN은 없습니다. string data이므로 우리가 어떤 작업을 해주어야 실제 모델에 사용할 수 있는데, 이를 위해선 아이디어가 필요합니다.

df_train['Ticket'].value_counts()
# 티켓 번호에 따른 갯수를 알 수 있습니다.

보시다시피, ticket number는 매우 다양합니다. 그렇다면 어떤 특징을 이끌어내서 생존과 연결시킬 수 있을까요?

티켓에 따른 클래스를 한번 나누어볼까요?

저는 아이디어가 떠오르지 않군요 ㅎㅎ

조금 조사해보니 Cabin의 NaN값을 Random으로 다 채워놓고 돌린 사람도 있었지만 Ticket을 사용한 사람은 없더군요.


이상 Kaggle - 타이타닉 생존여부 예측 모델 생성 (1)이었습니다 !

반응형
LIST