티스토리 뷰

머신러닝

kaggle 타이타닉 EDA

느린 개미 2018. 10. 25. 23:05
반응형


EDA of Titanic Data

캐글에서 유명한 타이타닉 데이터를 EDA 를 해보도록 하겠다. 
처음 해보는 것으로, 깊게 들어가지는 않고 최대한 쉬운 방향으로 진행해보고자한다.

In [74]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

1. Data Set

Train 과 Test 데이타가 있다. 처음 5개 행을 각각 보면 다음과 같다.
이 Titanic Data Set 의 최종 목표는, Survived 할지(1) 안할지(0) 를 맞추는 것이다. 
Test set 의 Data 는 따라서 Survived feature 가 없는 것을 알 수 있다.

In [75]:
test_df = pd.read_csv("./test.csv")
train_df = pd.read_csv("./train.csv")
In [3]:
test_df.head()
Out[3]:
PassengerIdPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
08923Kelly, Mr. Jamesmale34.5003309117.8292NaNQ
18933Wilkes, Mrs. James (Ellen Needs)female47.0103632727.0000NaNS
28942Myles, Mr. Thomas Francismale62.0002402769.6875NaNQ
38953Wirz, Mr. Albertmale27.0003151548.6625NaNS
48963Hirvonen, Mrs. Alexander (Helga E Lindqvist)female22.011310129812.2875NaNS
In [76]:
train_df.head()
Out[76]:
PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
4503Allen, Mr. William Henrymale35.0003734508.0500NaNS

데이터의 쉬운 가공을 위해서 train 과 test 데이터를 합쳐주도록 하겠다.
Survived 는 삭제해준다.

In [77]:
train_df_copy = train_df.drop(['Survived'], axis=1)
total_set = pd.concat([train_df_copy,test_df ])
total_set.tail()
Out[77]:
PassengerIdPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
41313053Spector, Mr. WoolfmaleNaN00A.5. 32368.0500NaNS
41413061Oliva y Ocana, Dona. Ferminafemale39.000PC 17758108.9000C105C
41513073Saether, Mr. Simon Sivertsenmale38.500SOTON/O.Q. 31012627.2500NaNS
41613083Ware, Mr. FrederickmaleNaN003593098.0500NaNS
41713093Peter, Master. Michael JmaleNaN11266822.3583NaNC
In [78]:
train_data =train_df.copy()

2. Feature 분석

1) Null Data Check

Data 에 Null 데이터가 얼마나 있는지 확인해보도록 하겠다.

In [79]:
total_set.isnull().sum()
Out[79]:
PassengerId       0
Pclass            0
Name              0
Sex               0
Age             263
SibSp             0
Parch             0
Ticket            0
Fare              1
Cabin          1014
Embarked          2
dtype: int64
In [80]:
total_set.isnull().sum() / len(total_set)
Out[80]:
PassengerId    0.000000
Pclass         0.000000
Name           0.000000
Sex            0.000000
Age            0.200917
SibSp          0.000000
Parch          0.000000
Ticket         0.000000
Fare           0.000764
Cabin          0.774637
Embarked       0.001528
dtype: float64

Cabin 의 Null Data percentage 가 77퍼센트이기 때문에, 이 열은 drop 하도록 하겠다.

In [81]:
total_set.drop('Cabin', axis=1, inplace=True)
total_set.head()
Out[81]:
PassengerIdPclassNameSexAgeSibSpParchTicketFareEmbarked
013Braund, Mr. Owen Harrismale22.010A/5 211717.2500S
121Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C
233Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250S
341Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000S
453Allen, Mr. William Henrymale35.0003734508.0500S
In [82]:
train_data.drop('Cabin', axis=1, inplace=True)
train_data.head()
Out[82]:
PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareEmbarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500S
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C
2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250S
3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000S
4503Allen, Mr. William Henrymale35.0003734508.0500S

2) 전체 생존률은 얼마일까?

train data 의 전체 생존률을 확인해보겠다. 생존률은 38.4 % 이다.

In [83]:
train_df["Survived"].value_counts().plot.pie( explode=[0,0.1], autopct='%1.1f%%', shadow=True)
plt.show()

각 Feature 에 대한 고찰

1) Sex Feature -> 카테고리 데이터로 변환

성별별로 생존률을 확인해보겠다

아래와 같이 남성의 생존률은 약 19%이며, 여성의 생존률은 약 74% 이다. 

  • 남성의 생존률
In [12]:
len(train_df.loc[ (train_df["Sex"]=='male') & (train_df["Survived"]==1)]) / len(train_df.loc[ (train_df["Sex"]=='male') ]) 
Out[12]:
0.18890814558058924
  • 여성의 생존률
In [11]:
len(train_df.loc[ (train_df["Sex"]=='female') & (train_df["Survived"]==1)]) / len(train_df.loc[ (train_df["Sex"]=='female') ]) 
Out[11]:
0.7420382165605095
  • 성별별 생존률을 파이차트로 나타내면 아래와 같다.
In [282]:
# Pie chart, where the slices will be ordered and plotted counter-clockwise:
labels = 'Survived', 'Dead'
sizes_m = [len(train_df.loc[ (train_df["Sex"]=='male') & (train_df["Survived"]==1)]), \
         len(train_df.loc[ (train_df["Sex"]=='male')& (train_df["Survived"]==0)]) ]

sizes_f = [len(train_df.loc[ (train_df["Sex"]=='female') & (train_df["Survived"]==1)]), \
         len(train_df.loc[ (train_df["Sex"]=='female')& (train_df["Survived"]==0)]) ]

explode = (0, 0.1)  # only "explode" the 2nd slice (i.e. 'Hogs')

fig = plt.figure()
fig.set_size_inches(10,5)
ax1 = fig.add_subplot(1,2,1)
ax2 = fig.add_subplot(1,2,2)

ax1.pie(sizes_m, explode=explode, labels=labels, autopct='%1.1f%%', shadow=True, startangle=90)
ax1.set_title('male')  # Equal aspect ratio ensures that pie is drawn as a circle.

ax2.pie(sizes_f, explode=explode, labels=labels, autopct='%1.1f%%',shadow=True, startangle=90)
ax2.set_title('female')  # Equal aspect ratio ensures that pie is drawn as a circle.

plt.show()

이는 성별에 따라 생존률에 영향이 있음을 알 수 있다.

성별의 값은 male, female 두가지가 있으므로 아래와 같이 category 값 0, 1 로 변환해주었다.

In [84]:
total_set["Sex"].unique()
Out[84]:
array(['male', 'female'], dtype=object)
In [85]:
total_set["Sex"].replace({"male":0, "female":1}, inplace=True )
In [86]:
train_data["Sex"].replace({"male":0, "female":1}, inplace=True )
In [ ]:
# 아래와 같은 코드도 가능 
#titanic_data["Sex"] = titanic_data["Sex"].apply(lambda s : 0 if s =='female' else 1)
In [87]:
total_set.head(5)
Out[87]:
PassengerIdPclassNameSexAgeSibSpParchTicketFareEmbarked
013Braund, Mr. Owen Harris022.010A/5 211717.2500S
121Cumings, Mrs. John Bradley (Florence Briggs Th...138.010PC 1759971.2833C
233Heikkinen, Miss. Laina126.000STON/O2. 31012827.9250S
341Futrelle, Mrs. Jacques Heath (Lily May Peel)135.01011380353.1000S
453Allen, Mr. William Henry035.0003734508.0500S

2) Name

아래와 같이 다양한 이름들이 있다.

In [88]:
total_set["Name"].head(5)
Out[88]:
0                              Braund, Mr. Owen Harris
1    Cumings, Mrs. John Bradley (Florence Briggs Th...
2                               Heikkinen, Miss. Laina
3         Futrelle, Mrs. Jacques Heath (Lily May Peel)
4                             Allen, Mr. William Henry
Name: Name, dtype: object

Mr. Mrs. Miss. 등의 값만 뽑아내어보기로 함

In [89]:
import re

def find_M(datas):   
    #wow = re.search("M[a-z]+\.", datas)
    wow = re.search("[A-Z][a-z]+\.", datas)
    
    if wow == None:
        return None
    
    return wow.group(0)
In [90]:
total_set["Name_convert"]=total_set["Name"].map(find_M)
In [91]:
train_data["Name_convert"]=train_data["Name"].map(find_M)
In [92]:
total_set.head(3)
Out[92]:
PassengerIdPclassNameSexAgeSibSpParchTicketFareEmbarkedName_convert
013Braund, Mr. Owen Harris022.010A/5 211717.2500SMr.
121Cumings, Mrs. John Bradley (Florence Briggs Th...138.010PC 1759971.2833CMrs.
233Heikkinen, Miss. Laina126.000STON/O2. 31012827.9250SMiss.

뽑아낸 값들과 각 값들의 수를 count 해본다.

In [93]:
total_set["Name_convert"].unique()
Out[93]:
array(['Mr.', 'Mrs.', 'Miss.', 'Master.', 'Don.', 'Rev.', 'Dr.', 'Mme.',
       'Ms.', 'Major.', 'Lady.', 'Sir.', 'Mlle.', 'Col.', 'Capt.',
       'Countess.', 'Jonkheer.', 'Dona.'], dtype=object)
In [94]:
total_set["Name_convert"].value_counts()
Out[94]:
Mr.          757
Miss.        260
Mrs.         197
Master.       61
Rev.           8
Dr.            8
Col.           4
Major.         2
Ms.            2
Mlle.          2
Sir.           1
Countess.      1
Lady.          1
Don.           1
Dona.          1
Mme.           1
Capt.          1
Jonkheer.      1
Name: Name_convert, dtype: int64

개수가 애매한 Dr. 승객들을 살펴보니 1명을 제외하고 남자이다. 
그래서 Dr. 은 Mr.과 동일하게 처리하도록 하고 나중에 여자 1명만 Mrs.로 변경하도록 하겠다.

In [95]:
total_set[total_set["Name_convert"]=='Dr.']
Out[95]:
PassengerIdPclassNameSexAgeSibSpParchTicketFareEmbarkedName_convert
2452461Minahan, Dr. William Edward044.0201992890.0000QDr.
3173182Moraweck, Dr. Ernest054.0002901114.0000SDr.
3983992Pain, Dr. Alfred023.00024427810.5000SDr.
6326331Stahelin-Maeglin, Dr. Max032.0001321430.5000CDr.
6606611Frauenthal, Dr. Henry William050.020PC 17611133.6500SDr.
7667671Brewe, Dr. Arthur Jackson0NaN0011237939.6000CDr.
7967971Leader, Dr. Alice (Farnham)149.0001746525.9292SDr.
29311851Dodge, Dr. Washington053.0113363881.8583SDr.

Rev. 승객들을 살펴보니 모두 남자이다. 
그래서 Rev. 도 Mr.과 동일하게 처리하도록 하겠다.

In [96]:
total_set[total_set["Name_convert"]=='Rev.']
Out[96]:
PassengerIdPclassNameSexAgeSibSpParchTicketFareEmbarkedName_convert
1491502Byles, Rev. Thomas Roussel Davids042.00024431013.000SRev.
1501512Bateman, Rev. Robert James051.000S.O.P. 116612.525SRev.
2492502Carter, Rev. Ernest Courtenay054.01024425226.000SRev.
6266272Kirkland, Rev. Charles Leonard057.00021953312.350QRev.
8488492Harper, Rev. John028.00124872733.000SRev.
8868872Montvila, Rev. Juozas027.00021153613.000SRev.
14910412Lahtinen, Rev. William030.01125065126.000SRev.
16410562Peruschitz, Rev. Joseph Maria041.00023739313.000SRev.

상위 4개값 Mr. Miss. Mrs. Master. 은 0~3 으로 매칭시키고, Dr. Rev. Major. , Col. Sir. 은 Mr.과 같은 값으로 처리한다.
Lady., Ms. Mlle. 는 Miss. 와 같은 값으로 처리한다. 

나머지는 4 로 매칭시킨다.

In [97]:
total_set["name_code"] = total_set.Name_convert.map({"Mr.":0, "Miss.":1, "Mrs.":2, "Master.":3, \
                                                     "Dr.":0, "Rev.":0, "Major.":0, "Col.":0, "Sir.":0,  \
                                                     "Lady.":1, "Ms.":1, "Mlle.":1 } )
In [98]:
total_set["name_code"].head(3)
Out[98]:
0    0.0
1    2.0
2    1.0
Name: name_code, dtype: float64
In [99]:
total_set["name_code"].value_counts()
Out[99]:
0.0    780
1.0    265
2.0    197
3.0     61
Name: name_code, dtype: int64
In [100]:
total_set[total_set["name_code"].isnull()]
Out[100]:
PassengerIdPclassNameSexAgeSibSpParchTicketFareEmbarkedName_convertname_code
30311Uruchurtu, Don. Manuel E040.000PC 1760127.7208CDon.NaN
3693701Aubart, Mme. Leontine Pauline124.000PC 1747769.3000CMme.NaN
7457461Crosby, Capt. Edward Gifford070.011WE/P 573571.0000SCapt.NaN
7597601Rothes, the Countess. of (Lucy Noel Martha Dye...133.00011015286.5000SCountess.NaN
8228231Reuchlin, Jonkheer. John George038.000199720.0000SJonkheer.NaN
41413061Oliva y Ocana, Dona. Fermina139.000PC 17758108.9000CDona.NaN

매칭되지 않는 이름들도 있다. 이 이름들은 4 로 넣어준다.

In [101]:
total_set["name_code"].fillna(4, inplace=True)
total_set[total_set["name_code"].isnull()]
Out[101]:
PassengerIdPclassNameSexAgeSibSpParchTicketFareEmbarkedName_convertname_code
In [102]:
# name_code 가 (0)Mr. 이면서, Sex 가 female 로 변환되었던 데이터 수정 -> (2)Mrs.
total_set.loc[ (total_set['name_code']==0)  &  (total_set['Sex']==1), ['name_code']] = 2

Name column 에서 에서 Mr. Mrs. 등 추출했으므로 Name column , Name_convert 열은 삭제한다.

In [103]:
total_set.drop(["Name", "Name_convert"], axis=1, inplace=True)
In [104]:
total_set.head(1)
Out[104]:
PassengerIdPclassSexAgeSibSpParchTicketFareEmbarkedname_code
013022.010A/5 211717.25S0.0

train_data 도 변환시켜준다.

In [105]:
train_data["name_code"] = train_data.Name_convert.map({"Mr.":0, "Miss.":1, "Mrs.":2, "Master.":3, \
                                                     "Dr.":0, "Rev.":0, "Major.":0, "Col.":0, "Sir.":0,  \
                                                     "Lady.":1, "Ms.":1, "Mlle.":1 } )
In [110]:
# name_code 가 (0)Mr. 이면서, Sex 가 female 로 변환되었던 데이터 수정 -> (2)Mrs.
train_data.loc[ (train_data['name_code']==0)  &  (train_data['Sex']==1), ['name_code']] = 2
In [111]:
train_data["name_code"].fillna(4, inplace=True)
In [107]:
train_data.drop(["Name", "Name_convert"], axis=1, inplace=True)

Name_code 별 생존률을 Factor plot 으로 살펴보겠다.

Name_code : "Mr.":0, "Miss.":1, "Mrs.":2, "Master.":3 그 외 : 4

In [300]:
import seaborn as sns
In [112]:
sns.factorplot(x='name_code' , y='Survived', data=train_data)
plt.show()

Mr. 이 포함된 이름이 가장 생존률이 낮고, Miss, Mrs. 가 포함된 이름은 생존률이 높은 편이다.

남성, 여성을 각각 분리하여 살펴보겠다.

In [114]:
sns.factorplot(x='name_code' , y='Survived' , col = 'Sex', data=train_data)
plt.show()

Mr.(0) 이 속한 이름을 가진 승객의 생존률은 0.2 이하이며, Miss. Mrs. (1,2) 를 가진 승객들은 생존률이 높았음을 알 수 있었다. 
위의 남성보다 여성의 생존률이 높았다는 결과와 동일 맥락이라 볼 수 있겠다.

3) Pclass Feature

class별 생존자를 세어보면 아래와 같다.

아래 crosstab 을 보면 1st class 는 생존자가 많고, 3rd class 는 사망자가 많음을 볼 수 있다.

In [116]:
pd.crosstab(train_data.Pclass,train_data.Survived,margins=True).style.background_gradient(cmap='summer_r')
Out[116]:
Survived01All
Pclass
180136216
29787184
3372119491
All549342891

확실히 돈앞에 평등하지 않았던 것일까? ㅠㅠ 파이차트를 그려보면 더 쉽게 알 수 있다.

In [118]:
# Pie chart, where the slices will be ordered and plotted counter-clockwise:
labels = 'Survived', 'Dead'
sizes_1 = [len(train_data.loc[ (train_data["Pclass"]==1) & (train_data["Survived"]==1)]), \
         len(train_data.loc[ (train_data["Pclass"]==1)& (train_data["Survived"]==0)]) ]

sizes_2 = [len(train_data.loc[ (train_data["Pclass"]==2) & (train_data["Survived"]==1)]), \
         len(train_data.loc[ (train_data["Pclass"]==2)& (train_data["Survived"]==0)]) ]

sizes_3 = [len(train_data.loc[ (train_data["Pclass"]==3) & (train_data["Survived"]==1)]), \
         len(train_data.loc[ (train_data["Pclass"]==3)& (train_data["Survived"]==0)]) ]

explode = (0, 0.1)  # only "explode" the 2nd slice (i.e. 'Hogs')

fig = plt.figure()
fig.set_size_inches(15,5)
ax1 = fig.add_subplot(1,3,1)
ax2 = fig.add_subplot(1,3,2)
ax3 = fig.add_subplot(1,3,3)

ax1.pie(sizes_1, explode=explode, labels=labels, autopct='%1.1f%%', shadow=True, startangle=90)
ax1.set_title('1st class')  # Equal aspect ratio ensures that pie is drawn as a circle.

ax2.pie(sizes_2, explode=explode, labels=labels, autopct='%1.1f%%',shadow=True, startangle=90)
ax2.set_title('2nd class')  # Equal aspect ratio ensures that pie is drawn as a circle.

ax3.pie(sizes_3, explode=explode, labels=labels, autopct='%1.1f%%',shadow=True, startangle=90)
ax3.set_title('3rd class')  # Equal aspect ratio ensures that pie is drawn as a circle.

plt.show()

이로써 Pclass 가 생존률에 미치는 영향이 컸음을 볼 수 있다.

그럼 Pclass 와 성별별로 살펴보겠다.

In [119]:
pd.crosstab([train_data.Pclass,train_data.Sex],train_data.Survived,margins=True).style.background_gradient(cmap='summer_r')
Out[119]:
Survived01All
PclassSex
107745122
139194
209117108
167076
3030047347
17272144
All549342891

1st class 의 여성(1)은 생존자가 많았음을 볼 수 있다. 2nd class 의 여성도 마찬가지다.
2nd, 3rd class 의 남성(0)은 사망자가 많다. 

즉 생존확률은 다음과 같은 분포를 보임을 확인할 수 있었다. 1st > 2nd > 3rd class, male < female

In [120]:
sns.factorplot(x='Sex' , y='Survived', col= 'Pclass', data=train_data)
plt.show()

4) Age Feature

우선 Age 의 Null 데이터 개수를 다시 확인해보고, 평균 최대 최소값도 확인해본다.

In [121]:
total_set ["Age"].isnull().sum()
Out[121]:
263
In [122]:
total_set ["Age"].describe()
Out[122]:
count    1046.000000
mean       29.881138
std        14.413493
min         0.170000
25%        21.000000
50%        28.000000
75%        39.000000
max        80.000000
Name: Age, dtype: float64

filling missing values

263 개의 없는 값을 어떻게 채울지 고민해본다. 
Pclass 와 Sex 를 그룹으로 평균 나이를 살펴본다

In [123]:
total_set.groupby(["Pclass", "Sex"])["Age"].mean()
Out[123]:
Pclass  Sex
1       0      41.029272
        1      37.037594
2       0      30.815380
        1      27.499223
3       0      25.962264
        1      22.185329
Name: Age, dtype: float64

1 -> 3 class 로 갈수록 나이가 어려지며, 동일 class 내에서는 남자들의 나이가 더 많은 것을 살펴볼 수 있다.

그래서 missing value 를 속한 Pclass 와 Sex 의 평균 나이값으로 채워주기로 한다.

In [124]:
total_set["Age"].fillna( total_set.groupby(["Pclass", "Sex"])["Age"].transform("mean") , inplace = True)

이제 나이분포를 그래프로 그려보고자 한다. 각 Age 별로 count 를 하여 표로 그려보겠다.

In [125]:
total_set["Age"].plot.hist(bins=50)
plt.show()

위의 그래프를 보면 주 나이대가 20~40 대에 많이 분포해있는 것을 알 수 있다.

다음은 나이에 따른 생존자수를 알아보도록 하자.

In [126]:
train_data ["Age"].fillna( train_data .groupby(["Pclass", "Sex"])["Age"].transform("mean") , inplace = True)
In [ ]:
 
In [127]:
train_data[train_data["Survived"]==1]["Age"].plot.hist(bins=30, color='g')
plt.title('Age ditrubution of Survival')
plt.show()
In [128]:
train_data[train_data["Survived"]==0]["Age"].plot.hist(bins=30, color='r')
plt.title('Age ditrubution of non Survival')
plt.show()

~ 5세의 아이들은 생존자가 많은 것을 확인할 수 있다.

15세~60세까지의 생존자, 사망자 분포는 비슷한 모양을 보이는 것을 알 수 있다.

전반적인 나이 분포는 크게 유의미하게 생각되지는 않으나, 특정 나이대의 생존자가 많기 때문에, 
일부 유의미한 것으로 보인다.

그럼 Age 는 continuous 한 value 이므로, categorial 한 value 로 변환시켜보고자 한다. 
16개의 category 로 나누는게 좀 많은것 같기도 한데, 우선 이렇게 해보겠다.

  • 0 < age <= 5 : 0
  • 5 < age <= 10 : 1
  • ...
  • 70 < age <= 75 : 14
  • 75 < age <= 80 : 15
In [129]:
bins = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80]
group_names = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
#bins = [0, 5, 10,  20,  30,  40, 80]
#group_names = [0, 1, 2, 3, 4, 5]
total_set['Age_value']= pd.cut(total_set['Age'], bins, labels=group_names)
total_set.head()
Out[129]:
PassengerIdPclassSexAgeSibSpParchTicketFareEmbarkedname_codeAge_value
013022.010A/5 211717.2500S0.04
121138.010PC 1759971.2833C2.07
233126.000STON/O2. 31012827.9250S1.05
341135.01011380353.1000S2.06
453035.0003734508.0500S0.06

Age 열은 drop 하도록 한다.

In [130]:
total_set.drop('Age', axis=1, inplace=True)
total_set.head()
Out[130]:
PassengerIdPclassSexSibSpParchTicketFareEmbarkedname_codeAge_value
013010A/5 211717.2500S0.04
121110PC 1759971.2833C2.07
233100STON/O2. 31012827.9250S1.05
34111011380353.1000S2.06
4530003734508.0500S0.06

아래 데이터를 다시 replace 함수를 써서 변환한 이유는, heatmap 을 그릴 오류가 나서 살펴보니 pd.cut 으로 binning 하면 해당 값이 카테고리 type 으로 인식하여, correlation 값이 계산이 안된다. 그래서 다시 한번 정수 변환을 시켜주었다.

In [131]:
total_set.Age_value.replace(
    {0:0, 1:1, 2:2, 3:3, 4:4, 5:5,
     6:6, 7:7, 8:8, 9:9, 10:10, 11:11,
     12:12, 13:13, 14:14, 15:15},   inplace = True
)

5) Sibsp

Sibsp 가 모지? 처음에 약자가 이해 안되서 kaggle 사이트를 다시 방문했다. 
정의는 다음과 같다.

Sibilings : Brother and Sister 
Spouse : husband and wife

같이 Titanic 호에 탑승한 형제자매, 배우자 숫자를 의미한다고 볼 수 있겠다

같이 탑승한 형제/자매, 배우자의 수를 count 해보았다. 혼자 탑승한 경우(0명)가 가장 많았다.

In [132]:
total_set ["SibSp"].value_counts()
Out[132]:
0    891
1    319
2     42
4     22
3     20
8      9
5      6
Name: SibSp, dtype: int64

Sisp 숫자별로 Survived 한 숫자를 살펴보겠다.

In [136]:
train_data.groupby(["SibSp","Survived"])["Survived"].count()
Out[136]:
SibSp  Survived
0      0           398
       1           210
1      0            97
       1           112
2      0            15
       1            13
3      0            12
       1             4
4      0            15
       1             3
5      0             5
8      0             7
Name: Survived, dtype: int64

SibSp 숫자별로 Survived 한 비율이 0~2 까지는 크게 차이가 나지 않다가,
3~8 까지는 사망자의 수가 급격히 많아짐을 볼 수 있었다.
5, 8 명의 경우는 생존자가 없었다. 
(아마도 가족이 많은 경우는 서로를 챙기고 구하려다가 생존하지 못하지 않았을까 생각해본다.)

Factor plot 으로 다시 살펴보도록 하겠다.

In [138]:
sns.factorplot(x='SibSp' , y='Survived', data=train_data)
plt.show()

그래프를 봐도 3명부터 생존률이 급격히 낮아진다. 
생존률이 0인 SibSp가 5와 8인 데이터를 살펴보다가, Pclass 가 다 3임을 볼 수 있었다.

그럼 SibSp 에 따른 생존률을 다시 Pclass 로 세분화하여 보겠다.

In [140]:
sns.factorplot(x='SibSp' , y='Survived', col= 'Pclass', data=train_data)
plt.show()

위의 그래프에서 Pclass 가 3이면서 SibSp가 3 이상인 사람들의 생존률은 아주 낮았음을 볼 수 있었다.

6) Parch

Parch 가 모지? kaggle 사이트를 다시 방문했다. 
정의는 다음과 같다.

  • number of parents / children aboard the Titanic

같이 Titanic 호에 탑승한 부모, 자식 숫자를 의미한다고 볼 수 있겠다

In [141]:
total_set["Parch"].value_counts()
Out[141]:
0    1002
1     170
2     113
3       8
5       6
4       6
9       2
6       2
Name: Parch, dtype: int64

Factor plot 으로 다시 살펴보도록 하겠다.

In [142]:
sns.factorplot(x='Parch' , y='Survived', data=train_data)
plt.show()

Sibsp 와 비슷하게 4이상부터 생존률이 낮아지는 것을 볼 수 있다. ㅠㅠ 4이상인 데이터를 한번 보도록 하겠다.

In [144]:
train_data[train_data["Parch"] >=4]
Out[144]:
PassengerIdSurvivedPclassSexAgeSibSpParchTicketFareEmbarkedname_code
131403039.01534708231.2750S0.0
252613138.01534707731.3875S2.0
16716803145.01434708827.9000S2.0
36036103040.01434708827.9000S0.0
43843901064.01419950263.0000S0.0
56756803129.00434990921.0750S2.0
61061103139.01534708231.2750S2.0
63863903141.005310129539.6875S2.0
67867903143.016CA 214446.9000S2.0
88588603139.00538265229.1250Q2.0

역시 SibSp 와 비슷하게 Pclass 가 3 인 데이터가 압도적으로 많다.

In [145]:
sns.factorplot(x='Parch' , y='Survived', col = 'Pclass', data=train_data)
plt.show()

Pclass 가 3이면서 Parch 가 4이상인 경우는 역시 낮은 생존률을 보여준다.

Parch 가 0 인 경우는 1-3 인 경우보다 생존률이 낮다.

7) Fare

요금을 살펴보도록 하겠다. 평균은 약 33 이며, 최소는 0 ~ 최대 512 까지 있다. 
75% 값은 31인것을 보면, 고가 티켓은 아주 비싼값이라는것을 알 수 있다.

In [146]:
total_set['Fare'].describe()
Out[146]:
count    1308.000000
mean       33.295479
std        51.758668
min         0.000000
25%         7.895800
50%        14.454200
75%        31.275000
max       512.329200
Name: Fare, dtype: float64

요금이 없는 데이터를 살펴본다.

In [150]:
total_set.loc[total_set['Fare'].isnull()]
Out[150]:
PassengerIdPclassSexSibSpParchTicketFareEmbarkedname_codeAge_value
152104430003701NaNS0.012

요금이 없는 데이터에 평균값으로 채워준다.

In [151]:
total_set['Fare'].fillna(total_set['Fare'].mean(), inplace=True)

seaborn 의 Distribution plot 이라는 함수로 class 별 요금분포를 살펴보도록 하겠다.

In [157]:
f, ax = plt.subplots(1,3,figsize=(15,5))

sns.distplot( total_set[total_set['Pclass']==1]['Fare'] , ax=ax[0])
ax[0].set_title('Fares of 1st class')
sns.distplot(total_set[total_set['Pclass']==2]['Fare'] , ax=ax[1])
ax[1].set_title('Fares of 2nd class')
sns.distplot(total_set[total_set['Pclass']==3]['Fare'] , ax=ax[2])
ax[2].set_title('Fares of 3rd class')

plt.show()

class 별 평균 요금도 살펴보자.

In [158]:
[total_set[total_set['Pclass']==1]['Fare'].mean(),
total_set[total_set['Pclass']==2]['Fare'].mean(),
total_set[total_set['Pclass']==3]['Fare'].mean()]
Out[158]:
[87.5089916408668, 21.1791963898917, 13.331086994755067]

continuous 한 값이므로, 아래 기준으로 값을 변경시켜보도록 하겠다. 

min 0.000000 
25% 7.895800 
50% 14.454200 
75% 31.275000 
max 512.329200 

In [159]:
bins = [-1, 7.895800, 14.4542, 31.275, 512.3292 ]
group_names = [0, 1, 2, 3]
total_set['Fare_value']= pd.cut(total_set['Fare'], bins, labels=group_names)
total_set.head()
Out[159]:
PassengerIdPclassSexSibSpParchTicketFareEmbarkedname_codeAge_valueFare_value
013010A/5 211717.2500S0.040
121110PC 1759971.2833C2.073
233100STON/O2. 31012827.9250S1.051
34111011380353.1000S2.063
4530003734508.0500S0.061
In [160]:
total_set[total_set['Fare_value'].isnull()]
Out[160]:
PassengerIdPclassSexSibSpParchTicketFareEmbarkedname_codeAge_valueFare_value
In [164]:
bins = [-1, 7.895800, 14.4542, 31.275, 512.3292 ]
group_names = [0, 1, 2, 3]
train_data['Fare_value']= pd.cut(train_data['Fare'], bins, labels=group_names)
train_data.head()
Out[164]:
PassengerIdSurvivedPclassSexAgeSibSpParchTicketFareEmbarkedname_codeFare_value
0103022.010A/5 211717.2500S0.00
1211138.010PC 1759971.2833C2.03
2313126.000STON/O2. 31012827.9250S1.01
3411135.01011380353.1000S2.03
4503035.0003734508.0500S0.01
In [166]:
sns.factorplot('Fare_value', 'Survived', hue='Sex', data=train_data)
plt.show()

성별에 따른 Fare_value 에 따른 생존률을 살펴보았다. 
표가 비쌀수록, 일반적으로 생존률이 높다는 것을 알 수 있었다.

Fare 는 카테고리변수 Fare_value 로 변환되었기 때문에 drop 시켜준다.

In [167]:
total_set.drop(['Fare'], axis=1, inplace=True)
In [168]:
total_set.head()
Out[168]:
PassengerIdPclassSexSibSpParchTicketEmbarkedname_codeAge_valueFare_value
013010A/5 21171S0.040
121110PC 17599C2.073
233100STON/O2. 3101282S1.051
341110113803S2.063
453000373450S0.061
In [169]:
total_set.Fare_value.replace(
    {0:0, 1:1, 2:2, 3:3 }  , inplace = True
)
In [170]:
train_data.drop(['Fare'], axis=1, inplace=True)
train_data.Fare_value.replace(
    {0:0, 1:1, 2:2, 3:3 }  , inplace = True
)

8) Ticket

Ticket 에 대해서 알아보자. 우선 값을 보았더니 잘 이해할수가 없다. drop 하도록 하겠다.

In [171]:
total_set.Ticket.unique()
Out[171]:
array(['A/5 21171', 'PC 17599', 'STON/O2. 3101282', '113803', '373450',
       '330877', '17463', '349909', '347742', '237736', 'PP 9549',
       '113783', 'A/5. 2151', '347082', '350406', '248706', '382652',
       '244373', '345763', '2649', '239865', '248698', '330923', '113788',
       '347077', '2631', '19950', '330959', '349216', 'PC 17601',
       'PC 17569', '335677', 'C.A. 24579', 'PC 17604', '113789', '2677',
       'A./5. 2152', '345764', '2651', '7546', '11668', '349253',
       'SC/Paris 2123', '330958', 'S.C./A.4. 23567', '370371', '14311',
       '2662', '349237', '3101295', 'A/4. 39886', 'PC 17572', '2926',
       '113509', '19947', 'C.A. 31026', '2697', 'C.A. 34651', 'CA 2144',
       '2669', '113572', '36973', '347088', 'PC 17605', '2661',
       'C.A. 29395', 'S.P. 3464', '3101281', '315151', 'C.A. 33111',
       'S.O.C. 14879', '2680', '1601', '348123', '349208', '374746',
       '248738', '364516', '345767', '345779', '330932', '113059',
       'SO/C 14885', '3101278', 'W./C. 6608', 'SOTON/OQ 392086', '343275',
       '343276', '347466', 'W.E.P. 5734', 'C.A. 2315', '364500', '374910',
       'PC 17754', 'PC 17759', '231919', '244367', '349245', '349215',
       '35281', '7540', '3101276', '349207', '343120', '312991', '349249',
       '371110', '110465', '2665', '324669', '4136', '2627',
       'STON/O 2. 3101294', '370369', 'PC 17558', 'A4. 54510', '27267',
       '370372', 'C 17369', '2668', '347061', '349241',
       'SOTON/O.Q. 3101307', 'A/5. 3337', '228414', 'C.A. 29178',
       'SC/PARIS 2133', '11752', '7534', 'PC 17593', '2678', '347081',
       'STON/O2. 3101279', '365222', '231945', 'C.A. 33112', '350043',
       '230080', '244310', 'S.O.P. 1166', '113776', 'A.5. 11206',
       'A/5. 851', 'Fa 265302', 'PC 17597', '35851', 'SOTON/OQ 392090',
       '315037', 'CA. 2343', '371362', 'C.A. 33595', '347068', '315093',
       '363291', '113505', 'PC 17318', '111240', 'STON/O 2. 3101280',
       '17764', '350404', '4133', 'PC 17595', '250653', 'LINE',
       'SC/PARIS 2131', '230136', '315153', '113767', '370365', '111428',
       '364849', '349247', '234604', '28424', '350046', 'PC 17610',
       '368703', '4579', '370370', '248747', '345770', '3101264', '2628',
       'A/5 3540', '347054', '2699', '367231', '112277',
       'SOTON/O.Q. 3101311', 'F.C.C. 13528', 'A/5 21174', '250646',
       '367229', '35273', 'STON/O2. 3101283', '243847', '11813',
       'W/C 14208', 'SOTON/OQ 392089', '220367', '21440', '349234',
       '19943', 'PP 4348', 'SW/PP 751', 'A/5 21173', '236171', '347067',
       '237442', 'C.A. 29566', 'W./C. 6609', '26707', 'C.A. 31921',
       '28665', 'SCO/W 1585', '367230', 'W./C. 14263', 'STON/O 2. 3101275',
       '2694', '19928', '347071', '250649', '11751', '244252', '362316',
       '113514', 'A/5. 3336', '370129', '2650', 'PC 17585', '110152',
       'PC 17755', '230433', '384461', '110413', '112059', '382649',
       'C.A. 17248', '347083', 'PC 17582', 'PC 17760', '113798', '250644',
       'PC 17596', '370375', '13502', '347073', '239853', 'C.A. 2673',
       '336439', '347464', '345778', 'A/5. 10482', '113056', '349239',
       '345774', '349206', '237798', '370373', '19877', '11967',
       'SC/Paris 2163', '349236', '349233', 'PC 17612', '2693', '113781',
       '19988', '9234', '367226', '226593', 'A/5 2466', '17421',
       'PC 17758', 'P/PP 3381', 'PC 17485', '11767', 'PC 17608', '250651',
       '349243', 'F.C.C. 13529', '347470', '29011', '36928', '16966',
       'A/5 21172', '349219', '234818', '345364', '28551', '111361',
       '113043', 'PC 17611', '349225', '7598', '113784', '248740',
       '244361', '229236', '248733', '31418', '386525', 'C.A. 37671',
       '315088', '7267', '113510', '2695', '2647', '345783', '237671',
       '330931', '330980', 'SC/PARIS 2167', '2691', 'SOTON/O.Q. 3101310',
       'C 7076', '110813', '2626', '14313', 'PC 17477', '11765', '3101267',
       '323951', 'C 7077', '113503', '2648', '347069', 'PC 17757', '2653',
       'STON/O 2. 3101293', '349227', '27849', '367655', 'SC 1748',
       '113760', '350034', '3101277', '350052', '350407', '28403',
       '244278', '240929', 'STON/O 2. 3101289', '341826', '4137', '315096',
       '28664', '347064', '29106', '312992', '349222', '394140',
       'STON/O 2. 3101269', '343095', '28220', '250652', '28228', '345773',
       '349254', 'A/5. 13032', '315082', '347080', 'A/4. 34244', '2003',
       '250655', '364851', 'SOTON/O.Q. 392078', '110564', '376564',
       'SC/AH 3085', 'STON/O 2. 3101274', '13507', 'C.A. 18723', '345769',
       '347076', '230434', '65306', '33638', '113794', '2666', '113786',
       '65303', '113051', '17453', 'A/5 2817', '349240', '13509', '17464',
       'F.C.C. 13531', '371060', '19952', '364506', '111320', '234360',
       'A/S 2816', 'SOTON/O.Q. 3101306', '113792', '36209', '323592',
       '315089', 'SC/AH Basle 541', '7553', '31027', '3460', '350060',
       '3101298', '239854', 'A/5 3594', '4134', '11771', 'A.5. 18509',
       '65304', 'SOTON/OQ 3101317', '113787', 'PC 17609', 'A/4 45380',
       '36947', 'C.A. 6212', '350035', '315086', '364846', '330909',
       '4135', '26360', '111427', 'C 4001', '382651', 'SOTON/OQ 3101316',
       'PC 17473', 'PC 17603', '349209', '36967', 'C.A. 34260', '226875',
       '349242', '12749', '349252', '2624', '2700', '367232',
       'W./C. 14258', 'PC 17483', '3101296', '29104', '2641', '2690',
       '315084', '113050', 'PC 17761', '364498', '13568', 'WE/P 5735',
       '2908', '693', 'SC/PARIS 2146', '244358', '330979', '2620',
       '347085', '113807', '11755', '345572', '372622', '349251', '218629',
       'SOTON/OQ 392082', 'SOTON/O.Q. 392087', 'A/4 48871', '349205',
       '2686', '350417', 'S.W./PP 752', '11769', 'PC 17474', '14312',
       'A/4. 20589', '358585', '243880', '2689', 'STON/O 2. 3101286',
       '237789', '13049', '3411', '237565', '13567', '14973', 'A./5. 3235',
       'STON/O 2. 3101273', 'A/5 3902', '364848', 'SC/AH 29037', '248727',
       '2664', '349214', '113796', '364511', '111426', '349910', '349246',
       '113804', 'SOTON/O.Q. 3101305', '370377', '364512', '220845',
       '31028', '2659', '11753', '350029', '54636', '36963', '219533',
       '349224', '334912', '27042', '347743', '13214', '112052', '237668',
       'STON/O 2. 3101292', '350050', '349231', '13213', 'S.O./P.P. 751',
       'CA. 2314', '349221', '8475', '330919', '365226', '349223', '29751',
       '2623', '5727', '349210', 'STON/O 2. 3101285', '234686', '312993',
       'A/5 3536', '19996', '29750', 'F.C. 12750', 'C.A. 24580', '244270',
       '239856', '349912', '342826', '4138', '330935', '6563', '349228',
       '350036', '24160', '17474', '349256', '2672', '113800', '248731',
       '363592', '35852', '348121', 'PC 17475', '36864', '350025',
       '223596', 'PC 17476', 'PC 17482', '113028', '7545', '250647',
       '348124', '34218', '36568', '347062', '350048', '12233', '250643',
       '113806', '315094', '36866', '236853', 'STON/O2. 3101271', '239855',
       '28425', '233639', '349201', '349218', '16988', '376566',
       'STON/O 2. 3101288', '250648', '113773', '335097', '29103',
       '392096', '345780', '349204', '350042', '29108', '363294',
       'SOTON/O2 3101272', '2663', '347074', '112379', '364850', '8471',
       '345781', '350047', 'S.O./P.P. 3', '2674', '29105', '347078',
       '383121', '36865', '2687', '113501', 'W./C. 6607',
       'SOTON/O.Q. 3101312', '374887', '3101265', '12460', 'PC 17600',
       '349203', '28213', '17465', '349244', '2685', '2625', '347089',
       '347063', '112050', '347087', '248723', '3474', '28206', '364499',
       '112058', 'STON/O2. 3101290', 'S.C./PARIS 2079', 'C 7075', '315098',
       '19972', '368323', '367228', '2671', '347468', '2223', 'PC 17756',
       '315097', '392092', '11774', 'SOTON/O2 3101287', '2683', '315090',
       'C.A. 5547', '349213', '347060', 'PC 17592', '392091', '113055',
       '2629', '350026', '28134', '17466', '233866', '236852',
       'SC/PARIS 2149', 'PC 17590', '345777', '349248', '695', '345765',
       '2667', '349212', '349217', '349257', '7552', 'C.A./SOTON 34068',
       'SOTON/OQ 392076', '211536', '112053', '111369', '370376', '330911',
       '363272', '240276', '315154', '7538', '330972', '2657', '349220',
       '694', '21228', '24065', '233734', '2692', 'STON/O2. 3101270',
       '2696', 'C 17368', 'PC 17598', '2698', '113054', 'C.A. 31029',
       '13236', '2682', '342712', '315087', '345768', '113778',
       'SOTON/O.Q. 3101263', '237249', 'STON/O 2. 3101291', 'PC 17594',
       '370374', '13695', 'SC/PARIS 2168', 'SC/A.3 2861', '349230',
       '348122', '349232', '237216', '347090', '334914', 'F.C.C. 13534',
       '330963', '2543', '382653', '349211', '3101297', 'PC 17562',
       '359306', '11770', '248744', '368702', '19924', '349238', '240261',
       '2660', '330844', 'A/4 31416', '364856', '347072', '345498',
       '376563', '13905', '350033', 'STON/O 2. 3101268', '347471',
       'A./5. 3338', '11778', '365235', '347070', '330920', '383162',
       '3410', '248734', '237734', '330968', 'PC 17531', '329944', '2681',
       '13050', '367227', '392095', '368783', '350045', '211535', '342441',
       'STON/OQ. 369943', '113780', '2621', '349226', '350409', '2656',
       '248659', 'SOTON/OQ 392083', '17475', 'SC/A4 23568', '113791',
       '349255', '3701', '350405', 'S.O./P.P. 752', '347469', '110489',
       'SOTON/O.Q. 3101315', '335432', '220844', '343271', '237393',
       'PC 17591', '17770', '7548', 'S.O./P.P. 251', '2670', '2673',
       '233478', '7935', '239059', 'S.O./P.P. 2', 'A/4 48873', '28221',
       '111163', '235509', '347465', '347066', 'C.A. 31030', '65305',
       'C.A. 34050', 'F.C. 12998', '9232', '28034', 'PC 17613', '349250',
       'SOTON/O.Q. 3101308', '347091', '113038', '330924', '32302',
       'SC/PARIS 2148', '342684', 'W./C. 14266', '350053', 'PC 17606',
       '350054', '370368', '242963', '113795', '3101266', '330971',
       '350416', '2679', '250650', '112377', '3470', 'SOTON/O2 3101284',
       '13508', '7266', '345775', 'C.A. 42795', 'AQ/4 3130', '363611',
       '28404', '345501', '350410', 'C.A. 34644', '349235', '112051',
       'C.A. 49867', 'A. 2. 39186', '315095', '368573', '2676', 'SC 14888',
       'CA 31352', 'W./C. 14260', '315085', '364859', 'A/5 21175',
       'SOTON/O.Q. 3101314', '2655', 'A/5 1478', 'PC 17607', '382650',
       '2652', '345771', '349202', '113801', '347467', '347079', '237735',
       '315092', '383123', '112901', '315091', '2658', 'LP 1588', '368364',
       'AQ/3. 30631', '28004', '350408', '347075', '2654', '244368',
       '113790', 'SOTON/O.Q. 3101309', '236854', 'PC 17580', '2684',
       '349229', '110469', '244360', '2675', '2622', 'C.A. 15185',
       '350403', '348125', '237670', '2688', '248726', 'F.C.C. 13540',
       '113044', '1222', '368402', '315083', '112378', 'SC/PARIS 2147',
       '28133', '248746', '315152', '29107', '680', '366713', '330910',
       'SC/PARIS 2159', '349911', '244346', '364858', 'C.A. 30769',
       '371109', '347065', '21332', '17765', 'SC/PARIS 2166', '28666',
       '334915', '365237', '347086', 'A.5. 3236', 'SOTON/O.Q. 3101262',
       '359309'], dtype=object)
In [172]:
total_set.drop("Ticket", axis=1, inplace = True)
total_set.head()
Out[172]:
PassengerIdPclassSexSibSpParchEmbarkedname_codeAge_valueFare_value
013010S0.040
121110C2.073
233100S1.051
341110S2.063
453000S0.061
In [173]:
train_data.drop("Ticket", axis=1, inplace = True)

9) Embarked

Embarked 는 승선한 항구를 의미한다.
C = Cherbourg, Q = Queenstown, S = Southampton

In [174]:
total_set['Embarked'].unique()
Out[174]:
array(['S', 'C', 'Q', nan], dtype=object)
In [175]:
total_set['Embarked'].value_counts()
Out[175]:
S    914
C    270
Q    123
Name: Embarked, dtype: int64

filling NaN values

In [178]:
total_set.loc[total_set['Embarked'].isnull()]
Out[178]:
PassengerIdPclassSexSibSpParchEmbarkedname_codeAge_valueFare_value
61621100NaN1.073
8298301100NaN2.0123

위에서 확인할 때 2개의 NaN 값이 있었으므로, 가장 개수가 많은 S 로 채워준다.

In [180]:
total_set['Embarked'].fillna('S', inplace=True)
In [181]:
total_set['Embarked'].value_counts()
Out[181]:
S    916
C    270
Q    123
Name: Embarked, dtype: int64
In [182]:
total_set['Embarked'].fillna('S', inplace=True)
In [183]:
train_data['Embarked'].fillna('S', inplace=True)
In [184]:
sns.factorplot('Embarked', 'Survived', data=train_data)
plt.show()

Port C 가 생존률이 약 0.55 로 높은 것을 볼 수 있다.

각 클래스별로, Embarked 분포를 살펴보겠다.

생존률이 높은 Port C 는 1st 의 구성이 가장 많고, 
생존률이 낮은 Port S 는 3rd class 의 남성이 가장 많이 탑승했음을 알 수 있다.

In [185]:
pd.crosstab([total_set.Pclass, total_set.Sex] ,total_set.Embarked,margins=True).style.background_gradient(cmap='summer_r')
Out[185]:
EmbarkedCQSAll
PclassSex
10701108179
171271144
20175149171
111293106
307057366493
13156129216
All2701239161309
In [186]:
sns.factorplot('Pclass', 'Survived', col = 'Embarked', hue='Sex',data=train_data)
plt.show()

위의 그래프도 살펴보며, 다음과 같은 특징을 찾을 수 있었다. 

  • 1st, 2nd class 의 여성들은 생존률이 높았음을 알 수 있다. 
  • Port Q 인 남성들은 생존률이 낮았음을 볼 수 있다. 
    위의 표를 보면 Port Q 에 탑승한 63명의 남성들 중에 57명이 3rd class 탑승자임을 알 수 있다. 
  • Port S 에서 탑승한 3rd class 의 여성은 생존률이 낮았음을 볼 수 있다.
In [187]:
total_set['Embarked'].replace( ["S","C","Q"], [0, 1, 2] , inplace = True)
In [188]:
train_data['Embarked'].replace( ["S","C","Q"], [0, 1, 2] , inplace = True)

3. 각 Feature 에 대한 정리

  • Sex : male -> 0, female -> 1 로 값 변환

    성별에 따른 생존률 차이가 컸다.(남: 18.9 , 여 : 74.2)
  • Name : 이름에서 특정 문자 추출하여 아래와 같이 값 변환

     (Mr. -> 0, Miss. -> 1, Mrs. -> 2, Master. -> 3 그 외-> 4)
    
     Mr.(0) 이 속한 이름을 가진 승객의 생존률은 0.2 이하이며, 
     Miss. Mrs. (1,2) 를 가진 승객들은 생존률이 높았음을 알 수 있었다. 
     남성보다 여성의 생존률이 높았다는 결과와 동일 맥락이라 볼 수 있겠다. 
  • Age : 나이대를 16개의 구간으로 나누어 0~15로 변경함.

    ~5세 이하는 생존률이 높음을 확인할 수 있었다.   
  • Pclass : 생존 확률은 다음과 같은 순임을 알 수 있다.

        1st > 2nd > 3rd class
  • SibSp : Pclass 가 3이면서 SibSp가 3 이상인 사람들의 생존률은 아주 낮았음을 볼 수 있었다.

  • Parch : Pclass 가 3이면서 Parch 가 4이상인 경우는 역시 낮은 생존률을 보여준다. 

  • Ticket: 값을 보니 잘 이해할 수가 없어 drop 함.

  • Embarked :
    Port Q 인 남성들은 생존률이 낮았음을 볼 수 있다.
    Port Q 에 탑승한 63명의 남성들 중에 57명이 3rd class 탑승자임을 알 수 있다. 
    Port S 에서 탑승한 3rd class 의 여성은 생존률이 낮았음을 볼 수 있다.

4. 참고

In [189]:
total_set.to_pickle('total_set.pickle')
In [190]:
train_data.to_pickle('train_data.pickle')
In [191]:
total_set.isnull().sum()
Out[191]:
PassengerId    0
Pclass         0
Sex            0
SibSp          0
Parch          0
Embarked       0
name_code      0
Age_value      0
Fare_value     0
dtype: int64
In [192]:
train_data.isnull().sum()
Out[192]:
PassengerId    0
Survived       0
Pclass         0
Sex            0
Age            0
SibSp          0
Parch          0
Embarked       0
name_code      0
Fare_value     0
dtype: int64
In [ ]:
 


반응형