[ML] Titanic: Survivor Prediction

박무연·2023년 3월 16일
0

🟤Mahine Learning

목록 보기
3/13
post-thumbnail

Titanic: Survivor Prediction

- 한명의 페르소나를 가정하고 정말 살 수 없었는지 알아보자!

EDA

- 생존 상황

  • pie 그래프와 countplot
fig, ax = plt.subplots(1,2, figsize=(18,8))
titanic['survived'].value_counts().plot(kind='pie',ax=ax[0],shadow=True, explode=[0,0.05] ,autopct='%.1f%%')
ax[0].set_title('Pie plot - survived')
ax[0].set_ylabel('')

sns.countplot(x='survived', data=titanic, ax=ax[1])
ax[1].set_title('Count plot - survived');

  • ax로 위치 지정!

- 성별에 따른 생존 상황

fig, ax = plt.subplots(1,2, figsize=(18,8))
sns.countplot(x='sex', data=titanic, ax=ax[0])
ax[0].set_title('Count of passengers of sex')
ax[0].set_ylabel('')

sns.countplot(x='sex', data=titanic, hue='survived' ,ax=ax[1])
ax[1].set_title('Sex : Survived')

plt.show()

  • ax[0] 에는 탑승객을 남여로 나눔
  • ax[1] 에는 hue에 생존여부를 주어 구분
  • 여성 생존 가능성이 높음

- 좌석(경제력)에 따른 생존률

  • 좌석과, 생존여부를 확인하기 위해 crosstab 사용
  • 두 범주형 컬럼이니깐 가능!
pd.crosstab(titanic['pclass'], titanic['survived'], margins= True)
  • 1등석의 생존률이 가장 높음

- 선실 등급별 성별

  • 여성 생존률이 높고, 1등석 생존률이 높으니깐 1등석에 여성이 많았나 확인 해보아야 한다
grid = sns.FacetGrid(titanic, row='pclass', col='sex', height = 4 , aspect = 2)
grid.map(plt.hist, 'age', alpha=0.8, bins=20)
grid.add_legend();

- 나이별 승객 현황

import plotly.express as px

fig = px.histogram(titanic, x='age')
fig.show()

  • plotly를 사용하면 마우스 오버시 정확한 값을 알 수 있다
  • 10대 20대 많다

- 등실별 생존률 연령

grid = sns.FacetGrid(titanic, row='pclass', col='survived', height = 4 , aspect = 2)
grid.map(plt.hist, 'age', alpha=0.8, bins=20)
grid.add_legend();

  • 선실등급이 높으면 생존률이 높아 보임

- 나이 5단계 정리

titanic['age_cat'] = pd.cut(titanic['age'], bins = [0,7,15,30,60,100],
       include_lowest=True,
       labels = ['baby', 'teen','young' , 'adult', 'old'])

titanic.head()

- 나이, 성별, 등급별 생존자 수 파악

plt.figure(figsize=(12,4))
plt.subplot(131)
sns.barplot(x='pclass', y='survived', data = titanic)

plt.subplot(132)
sns.barplot(x='age_cat', y='survived', data = titanic)

plt.subplot(133)
sns.barplot(x='sex', y='survived', data = titanic)

  • 생존이 1이니깐 값이 높으면 많이 생존 했다는 의미
  • barplot에서 보이는 값은 평균이다

- 남/여 나이별 생존 상황

fig, axes = plt.subplots(nrows=1, ncols=2, figsize = (14,6))

women = titanic[titanic['sex'] == 'female']
men = titanic[titanic['sex'] == 'male']

ax = sns.distplot(women[women['survived']==1]['age'], bins = 20,
                  label  = 'survived' ,ax=axes[0], kde=False)

ax = sns.distplot(women[women['survived']==0]['age'], bins = 40,
                  label = 'not_survived' ,ax=axes[0], kde=False)

ax.legend(); ax.set_title('female')

women = titanic[titanic['sex'] == 'female']
men = titanic[titanic['sex'] == 'male']

ax = sns.distplot(men[men['survived']==1]['age'], bins = 20,
                  label  = 'survived' ,ax=axes[1], kde=False)

ax = sns.distplot(men[men['survived']==0]['age'], bins = 40,
                  label = 'not_survived' ,ax=axes[1], kde=False)

ax.legend(); ax.set_title('Male')

plt.show()

  • bin : 그래프를 쪼개 주는 것
    - 몇개로 분포를 보일 것인가

- 신분 정보 파악

import re

title = []
for idx, dataset in titanic.iterrows():
    tmp = dataset['name']
    title.append(re.search('\,\s\w+(\s\w+)?\.', tmp).group()[2:-1])

titanic['title'] = title
titanic.head()

titanic['title'] = titanic['title'].replace('Mlle','Miss')
titanic['title'] = titanic['title'].replace('Ms','Miss')
titanic['title'] = titanic['title'].replace('Mme','Mrs')

Rare_f = ['Dona', 'Dr', 'Lady', 'the Countess']
Rare_m = ['Capt', 'Col', 'Don', 'Major', 'Rev', 'Sir', 'Jonkheer', 'Master' ]

for each in Rare_f:
    titanic['title'] = titanic['title'].replace(each, 'Rare_f')

for each in Rare_m:
    titanic['title'] = titanic['title'].replace(each, 'Rare_m')
  • 정규표현식으로 나타냈음
  • 이것은 공부가 필요..

- 신분에 따른 생존률

titanic[['title', 'survived']].groupby(['title'], as_index=False).mean()

머신러닝 생존자 예측

- object 컬럼 변경

  • sklearn : LabelEncoder
from sklearn.preprocessing import LabelEncoder

le = LabelEncoder()
le.fit(titanic['sex'])
titanic['gender'] = le.transform(titanic['sex'])
titanic.head()

- 결측치 드랍

titanic = titanic[titanic['age'].notnull()]
titanic = titanic[titanic['fare'].notnull()]

- 상관관계 확인

correlation_matirx = titanic.corr().round(1)
sns.heatmap(correlation_matirx, annot=True, cmap ='bwr')

- 특성 선택 및 데이터 나누기

  • sklearn : train_test_split
from sklearn.model_selection import train_test_split

X = titanic[['pclass', 'age', 'sibsp' , 'parch', 'fare', 'gender']]
y = titanic['survived']

X_train, X_test, y_train, y_test = train_test_split(X,y ,
                                                    test_size=0.2,
                                                    random_state=13)

- Dection Tree 및 평가

from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score

clf = DecisionTreeClassifier(max_depth=4, random_state=13)
clf.fit(X_train, y_train)

pred = clf.predict(X_test)
print(accuracy_score(y_test, pred))

생존률 예측

- 페르소나 만들기

  • 우리가 사용한 피쳐
  • pclass : 3
  • age : 18
  • sibsp : 0
  • parch : 0
  • fare : 5
  • gender : 1
persona = np.array([[3,18,0,0,5,1]])
clf.predict_proba(persona)[0,1]
  • predict_proba 를 사용하면 확률을 보여준다
  • 리스트안에 리스트 형태로 첫 번째 값은 0의 확률 두 번째 값은 1의 확률
profile
Easy day!

0개의 댓글