티스토리 뷰
캐글에서 유명한 타이타닉 데이터를 EDA 를 해보도록 하겠다.
처음 해보는 것으로, 깊게 들어가지는 않고 최대한 쉬운 방향으로 진행해보고자한다.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
Train 과 Test 데이타가 있다. 처음 5개 행을 각각 보면 다음과 같다.
이 Titanic Data Set 의 최종 목표는, Survived 할지(1) 안할지(0) 를 맞추는 것이다.
Test set 의 Data 는 따라서 Survived feature 가 없는 것을 알 수 있다.
test_df = pd.read_csv("./test.csv")
train_df = pd.read_csv("./train.csv")
test_df.head()
PassengerId | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 892 | 3 | Kelly, Mr. James | male | 34.5 | 0 | 0 | 330911 | 7.8292 | NaN | Q |
1 | 893 | 3 | Wilkes, Mrs. James (Ellen Needs) | female | 47.0 | 1 | 0 | 363272 | 7.0000 | NaN | S |
2 | 894 | 2 | Myles, Mr. Thomas Francis | male | 62.0 | 0 | 0 | 240276 | 9.6875 | NaN | Q |
3 | 895 | 3 | Wirz, Mr. Albert | male | 27.0 | 0 | 0 | 315154 | 8.6625 | NaN | S |
4 | 896 | 3 | Hirvonen, Mrs. Alexander (Helga E Lindqvist) | female | 22.0 | 1 | 1 | 3101298 | 12.2875 | NaN | S |
train_df.head()
PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S |
1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
2 | 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S |
3 | 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
4 | 5 | 0 | 3 | Allen, Mr. William Henry | male | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | S |
데이터의 쉬운 가공을 위해서 train 과 test 데이터를 합쳐주도록 하겠다.
Survived 는 삭제해준다.
train_df_copy = train_df.drop(['Survived'], axis=1)
total_set = pd.concat([train_df_copy,test_df ])
total_set.tail()
PassengerId | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|
413 | 1305 | 3 | Spector, Mr. Woolf | male | NaN | 0 | 0 | A.5. 3236 | 8.0500 | NaN | S |
414 | 1306 | 1 | Oliva y Ocana, Dona. Fermina | female | 39.0 | 0 | 0 | PC 17758 | 108.9000 | C105 | C |
415 | 1307 | 3 | Saether, Mr. Simon Sivertsen | male | 38.5 | 0 | 0 | SOTON/O.Q. 3101262 | 7.2500 | NaN | S |
416 | 1308 | 3 | Ware, Mr. Frederick | male | NaN | 0 | 0 | 359309 | 8.0500 | NaN | S |
417 | 1309 | 3 | Peter, Master. Michael J | male | NaN | 1 | 1 | 2668 | 22.3583 | NaN | C |
train_data =train_df.copy()
Data 에 Null 데이터가 얼마나 있는지 확인해보도록 하겠다.
total_set.isnull().sum()
PassengerId 0 Pclass 0 Name 0 Sex 0 Age 263 SibSp 0 Parch 0 Ticket 0 Fare 1 Cabin 1014 Embarked 2 dtype: int64
total_set.isnull().sum() / len(total_set)
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 하도록 하겠다.
total_set.drop('Cabin', axis=1, inplace=True)
total_set.head()
PassengerId | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 3 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | S |
1 | 2 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C |
2 | 3 | 3 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | S |
3 | 4 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | S |
4 | 5 | 3 | Allen, Mr. William Henry | male | 35.0 | 0 | 0 | 373450 | 8.0500 | S |
train_data.drop('Cabin', axis=1, inplace=True)
train_data.head()
PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | S |
1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C |
2 | 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | S |
3 | 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | S |
4 | 5 | 0 | 3 | Allen, Mr. William Henry | male | 35.0 | 0 | 0 | 373450 | 8.0500 | S |
train data 의 전체 생존률을 확인해보겠다. 생존률은 38.4 % 이다.
train_df["Survived"].value_counts().plot.pie( explode=[0,0.1], autopct='%1.1f%%', shadow=True)
plt.show()
성별별로 생존률을 확인해보겠다
아래와 같이 남성의 생존률은 약 19%이며, 여성의 생존률은 약 74% 이다.
- 남성의 생존률
len(train_df.loc[ (train_df["Sex"]=='male') & (train_df["Survived"]==1)]) / len(train_df.loc[ (train_df["Sex"]=='male') ])
0.18890814558058924
- 여성의 생존률
len(train_df.loc[ (train_df["Sex"]=='female') & (train_df["Survived"]==1)]) / len(train_df.loc[ (train_df["Sex"]=='female') ])
0.7420382165605095
- 성별별 생존률을 파이차트로 나타내면 아래와 같다.
# 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 로 변환해주었다.
total_set["Sex"].unique()
array(['male', 'female'], dtype=object)
total_set["Sex"].replace({"male":0, "female":1}, inplace=True )
train_data["Sex"].replace({"male":0, "female":1}, inplace=True )
# 아래와 같은 코드도 가능
#titanic_data["Sex"] = titanic_data["Sex"].apply(lambda s : 0 if s =='female' else 1)
total_set.head(5)
PassengerId | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 3 | Braund, Mr. Owen Harris | 0 | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | S |
1 | 2 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | 1 | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C |
2 | 3 | 3 | Heikkinen, Miss. Laina | 1 | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | S |
3 | 4 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | 1 | 35.0 | 1 | 0 | 113803 | 53.1000 | S |
4 | 5 | 3 | Allen, Mr. William Henry | 0 | 35.0 | 0 | 0 | 373450 | 8.0500 | S |
아래와 같이 다양한 이름들이 있다.
total_set["Name"].head(5)
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
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)
total_set["Name_convert"]=total_set["Name"].map(find_M)
train_data["Name_convert"]=train_data["Name"].map(find_M)
total_set.head(3)
PassengerId | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Embarked | Name_convert | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 3 | Braund, Mr. Owen Harris | 0 | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | S | Mr. |
1 | 2 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | 1 | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C | Mrs. |
2 | 3 | 3 | Heikkinen, Miss. Laina | 1 | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | S | Miss. |
뽑아낸 값들과 각 값들의 수를 count 해본다.
total_set["Name_convert"].unique()
array(['Mr.', 'Mrs.', 'Miss.', 'Master.', 'Don.', 'Rev.', 'Dr.', 'Mme.', 'Ms.', 'Major.', 'Lady.', 'Sir.', 'Mlle.', 'Col.', 'Capt.', 'Countess.', 'Jonkheer.', 'Dona.'], dtype=object)
total_set["Name_convert"].value_counts()
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.로 변경하도록 하겠다.
total_set[total_set["Name_convert"]=='Dr.']
PassengerId | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Embarked | Name_convert | |
---|---|---|---|---|---|---|---|---|---|---|---|
245 | 246 | 1 | Minahan, Dr. William Edward | 0 | 44.0 | 2 | 0 | 19928 | 90.0000 | Q | Dr. |
317 | 318 | 2 | Moraweck, Dr. Ernest | 0 | 54.0 | 0 | 0 | 29011 | 14.0000 | S | Dr. |
398 | 399 | 2 | Pain, Dr. Alfred | 0 | 23.0 | 0 | 0 | 244278 | 10.5000 | S | Dr. |
632 | 633 | 1 | Stahelin-Maeglin, Dr. Max | 0 | 32.0 | 0 | 0 | 13214 | 30.5000 | C | Dr. |
660 | 661 | 1 | Frauenthal, Dr. Henry William | 0 | 50.0 | 2 | 0 | PC 17611 | 133.6500 | S | Dr. |
766 | 767 | 1 | Brewe, Dr. Arthur Jackson | 0 | NaN | 0 | 0 | 112379 | 39.6000 | C | Dr. |
796 | 797 | 1 | Leader, Dr. Alice (Farnham) | 1 | 49.0 | 0 | 0 | 17465 | 25.9292 | S | Dr. |
293 | 1185 | 1 | Dodge, Dr. Washington | 0 | 53.0 | 1 | 1 | 33638 | 81.8583 | S | Dr. |
Rev. 승객들을 살펴보니 모두 남자이다.
그래서 Rev. 도 Mr.과 동일하게 처리하도록 하겠다.
total_set[total_set["Name_convert"]=='Rev.']
PassengerId | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Embarked | Name_convert | |
---|---|---|---|---|---|---|---|---|---|---|---|
149 | 150 | 2 | Byles, Rev. Thomas Roussel Davids | 0 | 42.0 | 0 | 0 | 244310 | 13.000 | S | Rev. |
150 | 151 | 2 | Bateman, Rev. Robert James | 0 | 51.0 | 0 | 0 | S.O.P. 1166 | 12.525 | S | Rev. |
249 | 250 | 2 | Carter, Rev. Ernest Courtenay | 0 | 54.0 | 1 | 0 | 244252 | 26.000 | S | Rev. |
626 | 627 | 2 | Kirkland, Rev. Charles Leonard | 0 | 57.0 | 0 | 0 | 219533 | 12.350 | Q | Rev. |
848 | 849 | 2 | Harper, Rev. John | 0 | 28.0 | 0 | 1 | 248727 | 33.000 | S | Rev. |
886 | 887 | 2 | Montvila, Rev. Juozas | 0 | 27.0 | 0 | 0 | 211536 | 13.000 | S | Rev. |
149 | 1041 | 2 | Lahtinen, Rev. William | 0 | 30.0 | 1 | 1 | 250651 | 26.000 | S | Rev. |
164 | 1056 | 2 | Peruschitz, Rev. Joseph Maria | 0 | 41.0 | 0 | 0 | 237393 | 13.000 | S | Rev. |
상위 4개값 Mr. Miss. Mrs. Master. 은 0~3 으로 매칭시키고, Dr. Rev. Major. , Col. Sir. 은 Mr.과 같은 값으로 처리한다.
Lady., Ms. Mlle. 는 Miss. 와 같은 값으로 처리한다.
나머지는 4 로 매칭시킨다.
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 } )
total_set["name_code"].head(3)
0 0.0 1 2.0 2 1.0 Name: name_code, dtype: float64
total_set["name_code"].value_counts()
0.0 780 1.0 265 2.0 197 3.0 61 Name: name_code, dtype: int64
total_set[total_set["name_code"].isnull()]
PassengerId | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Embarked | Name_convert | name_code | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
30 | 31 | 1 | Uruchurtu, Don. Manuel E | 0 | 40.0 | 0 | 0 | PC 17601 | 27.7208 | C | Don. | NaN |
369 | 370 | 1 | Aubart, Mme. Leontine Pauline | 1 | 24.0 | 0 | 0 | PC 17477 | 69.3000 | C | Mme. | NaN |
745 | 746 | 1 | Crosby, Capt. Edward Gifford | 0 | 70.0 | 1 | 1 | WE/P 5735 | 71.0000 | S | Capt. | NaN |
759 | 760 | 1 | Rothes, the Countess. of (Lucy Noel Martha Dye... | 1 | 33.0 | 0 | 0 | 110152 | 86.5000 | S | Countess. | NaN |
822 | 823 | 1 | Reuchlin, Jonkheer. John George | 0 | 38.0 | 0 | 0 | 19972 | 0.0000 | S | Jonkheer. | NaN |
414 | 1306 | 1 | Oliva y Ocana, Dona. Fermina | 1 | 39.0 | 0 | 0 | PC 17758 | 108.9000 | C | Dona. | NaN |
매칭되지 않는 이름들도 있다. 이 이름들은 4 로 넣어준다.
total_set["name_code"].fillna(4, inplace=True)
total_set[total_set["name_code"].isnull()]
PassengerId | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Embarked | Name_convert | name_code |
---|
# 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 열은 삭제한다.
total_set.drop(["Name", "Name_convert"], axis=1, inplace=True)
total_set.head(1)
PassengerId | Pclass | Sex | Age | SibSp | Parch | Ticket | Fare | Embarked | name_code | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 3 | 0 | 22.0 | 1 | 0 | A/5 21171 | 7.25 | S | 0.0 |
train_data 도 변환시켜준다.
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 } )
# name_code 가 (0)Mr. 이면서, Sex 가 female 로 변환되었던 데이터 수정 -> (2)Mrs.
train_data.loc[ (train_data['name_code']==0) & (train_data['Sex']==1), ['name_code']] = 2
train_data["name_code"].fillna(4, inplace=True)
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
import seaborn as sns
sns.factorplot(x='name_code' , y='Survived', data=train_data)
plt.show()
Mr. 이 포함된 이름이 가장 생존률이 낮고, Miss, Mrs. 가 포함된 이름은 생존률이 높은 편이다.
남성, 여성을 각각 분리하여 살펴보겠다.
sns.factorplot(x='name_code' , y='Survived' , col = 'Sex', data=train_data)
plt.show()
Mr.(0) 이 속한 이름을 가진 승객의 생존률은 0.2 이하이며, Miss. Mrs. (1,2) 를 가진 승객들은 생존률이 높았음을 알 수 있었다.
위의 남성보다 여성의 생존률이 높았다는 결과와 동일 맥락이라 볼 수 있겠다.
class별 생존자를 세어보면 아래와 같다.
아래 crosstab 을 보면 1st class 는 생존자가 많고, 3rd class 는 사망자가 많음을 볼 수 있다.
pd.crosstab(train_data.Pclass,train_data.Survived,margins=True).style.background_gradient(cmap='summer_r')
Survived | 0 | 1 | All |
---|---|---|---|
Pclass | |||
1 | 80 | 136 | 216 |
2 | 97 | 87 | 184 |
3 | 372 | 119 | 491 |
All | 549 | 342 | 891 |
확실히 돈앞에 평등하지 않았던 것일까? ㅠㅠ 파이차트를 그려보면 더 쉽게 알 수 있다.
# 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 와 성별별로 살펴보겠다.
pd.crosstab([train_data.Pclass,train_data.Sex],train_data.Survived,margins=True).style.background_gradient(cmap='summer_r')
Survived | 0 | 1 | All | |
---|---|---|---|---|
Pclass | Sex | |||
1 | 0 | 77 | 45 | 122 |
1 | 3 | 91 | 94 | |
2 | 0 | 91 | 17 | 108 |
1 | 6 | 70 | 76 | |
3 | 0 | 300 | 47 | 347 |
1 | 72 | 72 | 144 | |
All | 549 | 342 | 891 |
1st class 의 여성(1)은 생존자가 많았음을 볼 수 있다. 2nd class 의 여성도 마찬가지다.
2nd, 3rd class 의 남성(0)은 사망자가 많다.
즉 생존확률은 다음과 같은 분포를 보임을 확인할 수 있었다. 1st > 2nd > 3rd class, male < female
sns.factorplot(x='Sex' , y='Survived', col= 'Pclass', data=train_data)
plt.show()
우선 Age 의 Null 데이터 개수를 다시 확인해보고, 평균 최대 최소값도 확인해본다.
total_set ["Age"].isnull().sum()
263
total_set ["Age"].describe()
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
263 개의 없는 값을 어떻게 채울지 고민해본다.
Pclass 와 Sex 를 그룹으로 평균 나이를 살펴본다
total_set.groupby(["Pclass", "Sex"])["Age"].mean()
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 의 평균 나이값으로 채워주기로 한다.
total_set["Age"].fillna( total_set.groupby(["Pclass", "Sex"])["Age"].transform("mean") , inplace = True)
이제 나이분포를 그래프로 그려보고자 한다. 각 Age 별로 count 를 하여 표로 그려보겠다.
total_set["Age"].plot.hist(bins=50)
plt.show()
위의 그래프를 보면 주 나이대가 20~40 대에 많이 분포해있는 것을 알 수 있다.
다음은 나이에 따른 생존자수를 알아보도록 하자.
train_data ["Age"].fillna( train_data .groupby(["Pclass", "Sex"])["Age"].transform("mean") , inplace = True)
train_data[train_data["Survived"]==1]["Age"].plot.hist(bins=30, color='g')
plt.title('Age ditrubution of Survival')
plt.show()
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
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()
PassengerId | Pclass | Sex | Age | SibSp | Parch | Ticket | Fare | Embarked | name_code | Age_value | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 3 | 0 | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | S | 0.0 | 4 |
1 | 2 | 1 | 1 | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C | 2.0 | 7 |
2 | 3 | 3 | 1 | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | S | 1.0 | 5 |
3 | 4 | 1 | 1 | 35.0 | 1 | 0 | 113803 | 53.1000 | S | 2.0 | 6 |
4 | 5 | 3 | 0 | 35.0 | 0 | 0 | 373450 | 8.0500 | S | 0.0 | 6 |
Age 열은 drop 하도록 한다.
total_set.drop('Age', axis=1, inplace=True)
total_set.head()
PassengerId | Pclass | Sex | SibSp | Parch | Ticket | Fare | Embarked | name_code | Age_value | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 3 | 0 | 1 | 0 | A/5 21171 | 7.2500 | S | 0.0 | 4 |
1 | 2 | 1 | 1 | 1 | 0 | PC 17599 | 71.2833 | C | 2.0 | 7 |
2 | 3 | 3 | 1 | 0 | 0 | STON/O2. 3101282 | 7.9250 | S | 1.0 | 5 |
3 | 4 | 1 | 1 | 1 | 0 | 113803 | 53.1000 | S | 2.0 | 6 |
4 | 5 | 3 | 0 | 0 | 0 | 373450 | 8.0500 | S | 0.0 | 6 |
아래 데이터를 다시 replace 함수를 써서 변환한 이유는, heatmap 을 그릴 오류가 나서 살펴보니 pd.cut 으로 binning 하면 해당 값이 카테고리 type 으로 인식하여, correlation 값이 계산이 안된다. 그래서 다시 한번 정수 변환을 시켜주었다.
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
)
Sibsp 가 모지? 처음에 약자가 이해 안되서 kaggle 사이트를 다시 방문했다.
정의는 다음과 같다.
Sibilings : Brother and Sister
Spouse : husband and wife
같이 Titanic 호에 탑승한 형제자매, 배우자 숫자를 의미한다고 볼 수 있겠다
같이 탑승한 형제/자매, 배우자의 수를 count 해보았다. 혼자 탑승한 경우(0명)가 가장 많았다.
total_set ["SibSp"].value_counts()
0 891 1 319 2 42 4 22 3 20 8 9 5 6 Name: SibSp, dtype: int64
Sisp 숫자별로 Survived 한 숫자를 살펴보겠다.
train_data.groupby(["SibSp","Survived"])["Survived"].count()
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 으로 다시 살펴보도록 하겠다.
sns.factorplot(x='SibSp' , y='Survived', data=train_data)
plt.show()
그래프를 봐도 3명부터 생존률이 급격히 낮아진다.
생존률이 0인 SibSp가 5와 8인 데이터를 살펴보다가, Pclass 가 다 3임을 볼 수 있었다.
그럼 SibSp 에 따른 생존률을 다시 Pclass 로 세분화하여 보겠다.
sns.factorplot(x='SibSp' , y='Survived', col= 'Pclass', data=train_data)
plt.show()
위의 그래프에서 Pclass 가 3이면서 SibSp가 3 이상인 사람들의 생존률은 아주 낮았음을 볼 수 있었다.
Parch 가 모지? kaggle 사이트를 다시 방문했다.
정의는 다음과 같다.
- number of parents / children aboard the Titanic
같이 Titanic 호에 탑승한 부모, 자식 숫자를 의미한다고 볼 수 있겠다
total_set["Parch"].value_counts()
0 1002 1 170 2 113 3 8 5 6 4 6 9 2 6 2 Name: Parch, dtype: int64
Factor plot 으로 다시 살펴보도록 하겠다.
sns.factorplot(x='Parch' , y='Survived', data=train_data)
plt.show()
Sibsp 와 비슷하게 4이상부터 생존률이 낮아지는 것을 볼 수 있다. ㅠㅠ 4이상인 데이터를 한번 보도록 하겠다.
train_data[train_data["Parch"] >=4]
PassengerId | Survived | Pclass | Sex | Age | SibSp | Parch | Ticket | Fare | Embarked | name_code | |
---|---|---|---|---|---|---|---|---|---|---|---|
13 | 14 | 0 | 3 | 0 | 39.0 | 1 | 5 | 347082 | 31.2750 | S | 0.0 |
25 | 26 | 1 | 3 | 1 | 38.0 | 1 | 5 | 347077 | 31.3875 | S | 2.0 |
167 | 168 | 0 | 3 | 1 | 45.0 | 1 | 4 | 347088 | 27.9000 | S | 2.0 |
360 | 361 | 0 | 3 | 0 | 40.0 | 1 | 4 | 347088 | 27.9000 | S | 0.0 |
438 | 439 | 0 | 1 | 0 | 64.0 | 1 | 4 | 19950 | 263.0000 | S | 0.0 |
567 | 568 | 0 | 3 | 1 | 29.0 | 0 | 4 | 349909 | 21.0750 | S | 2.0 |
610 | 611 | 0 | 3 | 1 | 39.0 | 1 | 5 | 347082 | 31.2750 | S | 2.0 |
638 | 639 | 0 | 3 | 1 | 41.0 | 0 | 5 | 3101295 | 39.6875 | S | 2.0 |
678 | 679 | 0 | 3 | 1 | 43.0 | 1 | 6 | CA 2144 | 46.9000 | S | 2.0 |
885 | 886 | 0 | 3 | 1 | 39.0 | 0 | 5 | 382652 | 29.1250 | Q | 2.0 |
역시 SibSp 와 비슷하게 Pclass 가 3 인 데이터가 압도적으로 많다.
sns.factorplot(x='Parch' , y='Survived', col = 'Pclass', data=train_data)
plt.show()
Pclass 가 3이면서 Parch 가 4이상인 경우는 역시 낮은 생존률을 보여준다.
Parch 가 0 인 경우는 1-3 인 경우보다 생존률이 낮다.
요금을 살펴보도록 하겠다. 평균은 약 33 이며, 최소는 0 ~ 최대 512 까지 있다.
75% 값은 31인것을 보면, 고가 티켓은 아주 비싼값이라는것을 알 수 있다.
total_set['Fare'].describe()
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
요금이 없는 데이터를 살펴본다.
total_set.loc[total_set['Fare'].isnull()]
PassengerId | Pclass | Sex | SibSp | Parch | Ticket | Fare | Embarked | name_code | Age_value | |
---|---|---|---|---|---|---|---|---|---|---|
152 | 1044 | 3 | 0 | 0 | 0 | 3701 | NaN | S | 0.0 | 12 |
요금이 없는 데이터에 평균값으로 채워준다.
total_set['Fare'].fillna(total_set['Fare'].mean(), inplace=True)
seaborn 의 Distribution plot 이라는 함수로 class 별 요금분포를 살펴보도록 하겠다.
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 별 평균 요금도 살펴보자.
[total_set[total_set['Pclass']==1]['Fare'].mean(),
total_set[total_set['Pclass']==2]['Fare'].mean(),
total_set[total_set['Pclass']==3]['Fare'].mean()]
[87.5089916408668, 21.1791963898917, 13.331086994755067]
continuous 한 값이므로, 아래 기준으로 값을 변경시켜보도록 하겠다.
min 0.000000
25% 7.895800
50% 14.454200
75% 31.275000
max 512.329200
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()
PassengerId | Pclass | Sex | SibSp | Parch | Ticket | Fare | Embarked | name_code | Age_value | Fare_value | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 3 | 0 | 1 | 0 | A/5 21171 | 7.2500 | S | 0.0 | 4 | 0 |
1 | 2 | 1 | 1 | 1 | 0 | PC 17599 | 71.2833 | C | 2.0 | 7 | 3 |
2 | 3 | 3 | 1 | 0 | 0 | STON/O2. 3101282 | 7.9250 | S | 1.0 | 5 | 1 |
3 | 4 | 1 | 1 | 1 | 0 | 113803 | 53.1000 | S | 2.0 | 6 | 3 |
4 | 5 | 3 | 0 | 0 | 0 | 373450 | 8.0500 | S | 0.0 | 6 | 1 |
total_set[total_set['Fare_value'].isnull()]
PassengerId | Pclass | Sex | SibSp | Parch | Ticket | Fare | Embarked | name_code | Age_value | Fare_value |
---|
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()
PassengerId | Survived | Pclass | Sex | Age | SibSp | Parch | Ticket | Fare | Embarked | name_code | Fare_value | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 0 | 3 | 0 | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | S | 0.0 | 0 |
1 | 2 | 1 | 1 | 1 | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C | 2.0 | 3 |
2 | 3 | 1 | 3 | 1 | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | S | 1.0 | 1 |
3 | 4 | 1 | 1 | 1 | 35.0 | 1 | 0 | 113803 | 53.1000 | S | 2.0 | 3 |
4 | 5 | 0 | 3 | 0 | 35.0 | 0 | 0 | 373450 | 8.0500 | S | 0.0 | 1 |
sns.factorplot('Fare_value', 'Survived', hue='Sex', data=train_data)
plt.show()
성별에 따른 Fare_value 에 따른 생존률을 살펴보았다.
표가 비쌀수록, 일반적으로 생존률이 높다는 것을 알 수 있었다.
Fare 는 카테고리변수 Fare_value 로 변환되었기 때문에 drop 시켜준다.
total_set.drop(['Fare'], axis=1, inplace=True)
total_set.head()
PassengerId | Pclass | Sex | SibSp | Parch | Ticket | Embarked | name_code | Age_value | Fare_value | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 3 | 0 | 1 | 0 | A/5 21171 | S | 0.0 | 4 | 0 |
1 | 2 | 1 | 1 | 1 | 0 | PC 17599 | C | 2.0 | 7 | 3 |
2 | 3 | 3 | 1 | 0 | 0 | STON/O2. 3101282 | S | 1.0 | 5 | 1 |
3 | 4 | 1 | 1 | 1 | 0 | 113803 | S | 2.0 | 6 | 3 |
4 | 5 | 3 | 0 | 0 | 0 | 373450 | S | 0.0 | 6 | 1 |
total_set.Fare_value.replace(
{0:0, 1:1, 2:2, 3:3 } , inplace = True
)
train_data.drop(['Fare'], axis=1, inplace=True)
train_data.Fare_value.replace(
{0:0, 1:1, 2:2, 3:3 } , inplace = True
)
Ticket 에 대해서 알아보자. 우선 값을 보았더니 잘 이해할수가 없다. drop 하도록 하겠다.
total_set.Ticket.unique()
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)
total_set.drop("Ticket", axis=1, inplace = True)
total_set.head()
PassengerId | Pclass | Sex | SibSp | Parch | Embarked | name_code | Age_value | Fare_value | |
---|---|---|---|---|---|---|---|---|---|
0 | 1 | 3 | 0 | 1 | 0 | S | 0.0 | 4 | 0 |
1 | 2 | 1 | 1 | 1 | 0 | C | 2.0 | 7 | 3 |
2 | 3 | 3 | 1 | 0 | 0 | S | 1.0 | 5 | 1 |
3 | 4 | 1 | 1 | 1 | 0 | S | 2.0 | 6 | 3 |
4 | 5 | 3 | 0 | 0 | 0 | S | 0.0 | 6 | 1 |
train_data.drop("Ticket", axis=1, inplace = True)
Embarked 는 승선한 항구를 의미한다.
C = Cherbourg, Q = Queenstown, S = Southampton
total_set['Embarked'].unique()
array(['S', 'C', 'Q', nan], dtype=object)
total_set['Embarked'].value_counts()
S 914 C 270 Q 123 Name: Embarked, dtype: int64
total_set.loc[total_set['Embarked'].isnull()]
PassengerId | Pclass | Sex | SibSp | Parch | Embarked | name_code | Age_value | Fare_value | |
---|---|---|---|---|---|---|---|---|---|
61 | 62 | 1 | 1 | 0 | 0 | NaN | 1.0 | 7 | 3 |
829 | 830 | 1 | 1 | 0 | 0 | NaN | 2.0 | 12 | 3 |
위에서 확인할 때 2개의 NaN 값이 있었으므로, 가장 개수가 많은 S 로 채워준다.
total_set['Embarked'].fillna('S', inplace=True)
total_set['Embarked'].value_counts()
S 916 C 270 Q 123 Name: Embarked, dtype: int64
total_set['Embarked'].fillna('S', inplace=True)
train_data['Embarked'].fillna('S', inplace=True)
sns.factorplot('Embarked', 'Survived', data=train_data)
plt.show()
Port C 가 생존률이 약 0.55 로 높은 것을 볼 수 있다.
각 클래스별로, Embarked 분포를 살펴보겠다.
생존률이 높은 Port C 는 1st 의 구성이 가장 많고,
생존률이 낮은 Port S 는 3rd class 의 남성이 가장 많이 탑승했음을 알 수 있다.
pd.crosstab([total_set.Pclass, total_set.Sex] ,total_set.Embarked,margins=True).style.background_gradient(cmap='summer_r')
Embarked | C | Q | S | All | |
---|---|---|---|---|---|
Pclass | Sex | ||||
1 | 0 | 70 | 1 | 108 | 179 |
1 | 71 | 2 | 71 | 144 | |
2 | 0 | 17 | 5 | 149 | 171 |
1 | 11 | 2 | 93 | 106 | |
3 | 0 | 70 | 57 | 366 | 493 |
1 | 31 | 56 | 129 | 216 | |
All | 270 | 123 | 916 | 1309 |
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 의 여성은 생존률이 낮았음을 볼 수 있다.
total_set['Embarked'].replace( ["S","C","Q"], [0, 1, 2] , inplace = True)
train_data['Embarked'].replace( ["S","C","Q"], [0, 1, 2] , inplace = True)
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 의 여성은 생존률이 낮았음을 볼 수 있다.
total_set.to_pickle('total_set.pickle')
train_data.to_pickle('train_data.pickle')
total_set.isnull().sum()
PassengerId 0 Pclass 0 Sex 0 SibSp 0 Parch 0 Embarked 0 name_code 0 Age_value 0 Fare_value 0 dtype: int64
train_data.isnull().sum()
PassengerId 0 Survived 0 Pclass 0 Sex 0 Age 0 SibSp 0 Parch 0 Embarked 0 name_code 0 Fare_value 0 dtype: int64
'머신러닝' 카테고리의 다른 글
[Ensemble_2] RandomForest (랜덤포레스트) (0) | 2018.11.15 |
---|---|
[Ensemble_1] Bagging (배깅) (0) | 2018.11.09 |
[데이터전처리_3] Category Data 처리 (0) | 2018.10.17 |
[데이터전처리_2] missing value 처리 (0) | 2018.10.17 |
[데이터전처리_1] Feature Scaling (0) | 2018.10.16 |
- Total
- Today
- Yesterday
- 계정조정계열
- 환율데이터
- 블록해쉬
- Dash 와 html 차이
- M1M2비율
- M1/M2
- 객사오
- 마연굴
- 환매시점
- 리치고
- dash
- Forgiving
- ChatGPT
- 통화량 데이타
- 연금저축
- 위경도변환
- 연금등록
- 김성일 작가님
- 리치고 주식
- 환율이평선
- 내 연금조회
- 원계열
- 말잔
- 경제는 어떻게 움직이는가
- 프로그래스바 표시
- 블록해쉬구현
- 경제주체별 M2
- pandas apply
- 주소를 위경도 변환
- Dash.html
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |