Titanic 생존자 예측
① 데이터 확인 & EDA
다음 데이터셋을 이용하였습니다.
https://www.kaggle.com/c/titanic/data
Survived - 생존유무, target 값. (0 = 사망, 1 = 생존)
Name - 탑승객 성명
Pclass - 티켓 클래스. (1 = 1st, 2 = 2nd, 3 = 3rd)
Sex - 성별
Age - 나이(세)
SibSp - 함께 탑승한 형제자매, 배우자 수 총합
Parch - 함께 탑승한 부모, 자녀 수 총합
Embarked - 탑승 항구
Fare - 탑승 요금
Ticket - 티켓 넘버
Cabin - 객실 넘버
1. 라이브러리 및 데이터 살펴보기
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
plt.rc('font', family='Malgun Gothic')
plt.rc('axes', unicode_minus=False)
import warnings
warnings.filterwarnings(action='ignore')
train = pd.read_csv("C:/data/titanic/train.csv")
test = pd.read_csv("C:/data/titanic/test.csv")
submission = pd.read_csv("C:/data/titanic/gender_submission.csv")
먼저 데이터를 확인해보자
train.head()
test.head()
print(train.shape) #(891, 12)
print(test.shape) #(418, 11)
submission.head()
- 우리는 Survived 컬럼인 생존 여부를 예측해야 한다.
train data, test data의 결측치를 확인해보자
train.isnull().sum()
test.isnull().sum()
- train data에는 Age, Cabin, Embarked 컬럼에 결측치가 존재한다
- test data에는 Age, Fare, Cabin 컬럼에 결측치가 존재한다
이러한 결측치를 missingno를 이용하면 시각화해볼 수 있다
# 결측치 시각화
import missingno as msno
msno.matrix(train, figsize=(12, 5))
- 결측치를 시각화해서 한 눈에 보기에 좋은 라이브러리인 것 같다
2. EDA
2-1. target 변수 ( Survived )
# 생존비율 확인
train["Survived"].value_counts()
plt.figure(figsize=(8, 5))
labels = ['사망', '생존']
train['Survived'].value_counts().plot.pie(explode=[0, 0.08],
shadow=True,
autopct='%1.1f%%',
labels=labels)
- 사망 비율은 61.6%, 생존 비율은 38.4%로 사망한 탑승객의 수가 더 많은 것이 확인 된다.
2-2. 성별 ( Sex )
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
axes[0].set_title("성별 탑승자 수 \n", size=15)
sns.countplot(x="Sex", data=train, ax=axes[0])
axes[1].set_title("성별 생존자 수 \n", size=15)
sns.countplot(x="Sex", hue="Survived", data=train, ax=axes[1])
axes[1].legend(labels = ['사망', '생존'])
- 남성의 탑승자 수가 더 많지만 여성의 생존자 수가 더 많다
성별에 따른 생존률을 비교해보면
# 성별 생존률
sur = train[['Sex', 'Survived']].groupby('Sex').mean().plot.bar()
sur.set_title("성별 생존률 \n")
train[['Sex', 'Survived']].groupby('Sex').mean()
- 여성의 생존률은 약 74.2%, 남성의 생존률은 약 18.9%로 여성의 생존률이 압도적으로 높은 것이 확인된다.
- 남성보다 여성을 먼저 구조한 것으로 보임
2-3. 티켓 클래스 ( Pclass )
이번에는 티켓 클래스별로 어떤 생존률을 보이고 있는지 확인해보자
train[['Pclass', 'Survived']].groupby('Pclass').mean()
- 1등석의 생존률은 약 63%, 2등석의 생존률은 약 47.3%, 3등석의 생존률은 약 24.2%이다.
- 3등석 탑승객들이 많이 사망한 것으로 보인다.
이를 시각화해서 살펴보면 다음과 같다
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
axes[0].set_title("클래스별 탑승수 \n", size=15)
sns.countplot(data=train, x='Pclass', ax=axes[0])
axes[1].set_title("클래스별 생존/사망 수 \n", size=15)
sns.countplot(x="Pclass", hue="Survived", data=train, ax=axes[1])
axes[1].legend(labels = ['사망', '생존'])
- 3등석 탑승객이 가장 많고, 3등석 탑승객의 사망 인원수 또한 가장 많다.
- 상대적으로 1등석 탑승객들은 많이 살아남은 것으로 보인다.
실제로 클래스별 생존률을 확인해보면
# class별 생존률
sur = train[['Pclass', 'Survived']].groupby(['Pclass']).mean().plot.bar()
sur.set_title('class별 생존률', size=15)
- 1등석이 가장 높은 생존률을 보이고 3등석이 가장 낮은 생존률을 보인다.
- 티켓 클래스는 생존 여부에 영향을 끼치는 것으로 보인다.
2-4. 나이 ( Age )
train['Age'].describe()
- 탑승객들의 평균 나이는 30세이다. 나이의 분포를 살펴보자
plt.figure(figsize=(8, 5))
sns.distplot(train['Age'], bins=25)
- 탑승객들의 나이는 주로 20~40세에 분포하고 있다.
나이가 생존여부에 영향을 끼치는지 확인하기 위해 생존/사망 탑승객을 나누어 비교해봤다.
sur = train[train['Survived'] == 1]
dead = train[train['Survived'] == 0]
plt.figure(figsize=(8, 5))
sns.distplot(sur['Age'], bins=25, hist=False)
sns.distplot(dead['Age'], bins=25, hist=False)
- 비슷하긴 하지만 어린 나이의 탑승객들의 생존률이 비교적 높고 20-30세의 생존률은 비교적 낮은 것으로 보인다.
2-5. 함께 탑승한 가족의 수 ( SibSp, Parch )
SibSp - 함께 탑승한 형제자매, 배우자 수 총합
Parch - 함께 탑승한 부모, 자녀 수 총합
SibSp, Parch 모두 가족의 수 이므로 비슷한 경향을 띌 것으로 생각된다.
두 컬럼을 함께 확인해보자
fig, axes = plt.subplots(2, 2, figsize=(12, 12))
axes[0][0].set_title("SibSp별 탑승자 수", size=15)
sns.countplot(x="SibSp", data=train, ax=axes[0][0], palette="Set2")
axes[0][1].set_title("Parch별 탑승자 수", size=15)
sns.countplot(x="Parch", data=train, ax=axes[0][1], palette="Set2")
axes[1][0].set_title("SibSp별 생존 여부", size=15)
sns.countplot(x="SibSp", hue="Survived", data=train, ax=axes[1][0], palette="Set2")
axes[1][0].legend(loc='upper right')
axes[1][1].set_title("Parch별 생존 여부", size=15)
sns.countplot(x="Parch", hue="Survived", data=train, ax=axes[1][1], palette="Set2")
axes[1][1].legend(loc='upper right')
- 혼자 탑승한 탑승객이 가장 많다
- 생존 여부를 확인해보면 혼자 탑승한 사람들이 많이 사망한 것을 확인할 수 있다.
실제로 SibSp, Parch별로 생존률을 확인해보면
train[['SibSp', 'Survived']].groupby(['SibSp']).mean()
train[['Parch', 'Survived']].groupby(['Parch']).mean()
- SibSp - 함께 탑승한 형제자매, 배우자 수 총합
- 혼자 탑승한 사람보다 3명, 4명의 SibSp와 탑승한 탑승객들의 사망률이 가장 높다.
- Parch - 함께 탑승한 부모, 자녀 수 총합
- 부모, 자녀 없이 혼자 탑승한 사람의 사망률이 가장 높다.
2-6. 탑승 항구 ( Embarked )
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
axes[0].set_title("성별 탑승자 수 \n", size=15)
sns.countplot(x="Embarked", data=train, ax=axes[0])
axes[1].set_title("성별 생존 여부 \n", size=15)
sns.countplot(x="Embarked", hue="Survived", data=train, ax=axes[1])
axes[1].legend(labels = ['사망', '생존'])
- S항구 탑승객이 가장 많았으며 사망한 인원 역시 S항구 탑승객이 가장 많다.
사망 인원수가 아닌 항구별 사망 비율을 확인해봤을때도 여전히
train[['Embarked', 'Survived']].groupby(['Embarked']).mean()
- S항구 탑승객의 사망률이 가장 높다
항구별로 사망률에 왜 차이가 나는지 확인해보기 위해 항구별 탑승객의 티켓 클래스와 동승자를 확인해 보았다.
2-6-1. 항구별 탑승객들의 티켓 클래스
pc1 = train[train['Pclass'] == 1]['Embarked'].value_counts()
pc2 = train[train['Pclass'] == 2]['Embarked'].value_counts()
pc3 = train[train['Pclass'] == 3]['Embarked'].value_counts()
pc = pd.DataFrame([pc1, pc2, pc3])
pc.index = ['1st class', '2nd class', '3rd class']
fig, ax = plt.subplots(figsize=(8, 5))
pc.plot(kind='bar', stacked=True, ax=ax)
- 3등석에 S항구 탑승객들이 많은 것을 확인할 수 있다.
- 위에서 3등석의 사망률이 가장 높았듯이 3등석에 S항구 탑승객들이 많이 때문에 S항구 탑승객들의 사망률이 높은 것으로 보인다.
2-6-2. 항구별 탑승객들의 동승자
fig, ax = plt.subplots(1, 2, figsize=(12, 5))
sns.countplot(data=train, x='SibSp', hue='Embarked', ax=ax[0])
sns.countplot(data=train, x='Parch', hue='Embarked', ax=ax[1])
ax[0].legend(loc='upper right')
ax[1].legend(loc='upper right')
plt.show()
- 혼자 탑승한 탑승객의 수는 S항구 탑승객이 압도적으로 많았다.
2-7. 탑승 금액 ( Fare )
탑승 금액의 분포를 확인해보면
fig, ax = plt.subplots(figsize=(10,6))
# 분포 확인
sns.kdeplot(train[train['Survived']==1]['Fare'], ax=ax)
sns.kdeplot(train[train['Survived']==0]['Fare'], ax=ax)
# 축 범위
ax.set(xlim=(0, train['Fare'].max()))
ax.legend(['생존', '사망'])
plt.show()
- 탑승 금액이 적은 쪽은 사망률이 높은 것이 확인된다
- 위에서 보았듯이 탑승 클래스/탑승 금액에 따라 생존 여부에 영향을 끼치는 것으로 생각된다.
train.columns
# Index(['PassengerId', 'Survived', 'Pclass', 'Name', 'Sex', 'Age', 'SibSp',
# 'Parch', 'Ticket', 'Fare', 'Cabin', 'Embarked'], dtype='object')
Cabin은 결측치가 많고 PassengerID, Name, Ticket은 생존 여부와 연관이 없어 보인다.
이들을 제외한 나머지 컬럼들을 다 살펴보았다
다음 글에서는 Feature Engineering과 모델링을 이어서 해보자!
'Python > 데이터분석 실습' 카테고리의 다른 글
[Kaggle] Titanic 생존자 예측 ② Feature Engineering & 모델링 (0) | 2022.05.11 |
---|---|
[Kaggle] 자전거 수요 예측 ② Feature Engineering & 모델링 (0) | 2022.05.04 |
[Kaggle] 자전거 수요 예측 ① 데이터 확인 & EDA (0) | 2022.05.03 |
[Kaggle ] Pima Indians Diabetes 예측 ② 데이터 전처리 후 모델 학습/예측 (0) | 2022.03.01 |
[Kaggle] Pima Indians Diabetes 예측 ① EDA, 시각화 탐색 (0) | 2022.02.28 |