ML - 2. Titanic 생존 분석 _ titanic disaster kaggle

jaam._.mini·2024년 1월 17일
0
# !pip install plotly_express
import pandas as pd

titanic_url = 'http://raw.githubusercontent.com/PinkWink/ML_tutorial/master/dataset/titanic.xls'
titanic = pd.read_excel(titanic_url)
titanic.head(2)




1. 데이터 정리



생존상황 확인

import matplotlib.pyplot as plt
import seaborn as sns
# plt.subplots : 그래프 2개 한번에 그리기 (1행, 2열로)
f, ax = plt.subplots(1,2,figsize=(18,8))

# titanic['survived'].value_counts() : [0]비생존자, [1]생존자
# .plot.pie : 동그란 그래프로 그리자
titanic['survived'].value_counts().plot.pie(
    explode=[0, 0.05], # 조각들 멀어지기
    autopct='%1.1f%%', # 소수점 첫째 자리까지 수치 입력
    ax=ax[0], # ax를 첫번째로 그려줘
    shadow=True # 그림자 생김
)
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')

plt.show()

2) 성별

f, 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 and Unsurvived')

plt.show()

3) 경제력

  • crosstab : 2번째 컬럼을 구분지어 주고, 인덱스에 1번째 컬럼을 담아 줌
  • margins=True : 합계
pd.crosstab(titanic['pclass'], titanic['survived'], margins=True)

4) 등급/성별 _FacetGrid

# FacetGrid(변수 지정, 행, 컬럼, 높이, 넓이)
grid = sns.FacetGrid(titanic, row='pclass', col='sex', height=4, aspect=2)

# hist을 넣어라, 나이를 기준으로, 투명도는 0.8로, 수평축의 간격)
grid.map(plt.hist, 'age', alpha=.8, bins=20)

# 각 격자 안의 색상에 대한 범레 지정
grid.add_legend();

5) 나이

import plotly.express as px

# px에 히스토그램을 그려줘(데이터는 타이타닉, 컬럼은 나이)
fig = px.histogram(titanic, x='age')
fig.show()

6) 선실 등급별

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

7) 나이 5단계 정리

# age_cat :라는 새로운 (컬럼) 만들
titanic['age_cat'] = pd.cut(
    titanic['age'], # titanic 데이터의 age 컬 
    bins = [0,7,15,30,60,100],
    include_lowest = True,
    labels = ['baby', 'teen', 'young', 'adult', 'old']
    # 0-7:baby, 7-15:teen, 15-30:young, 30-60:adult, 60-100:old
)

titanic.head(2)

8) 나이/성별/등급

plt.figure(figsize=(12,4))

plt.subplot(131) #1행3열 중 1번째
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)

# plt.subplots_adjust(top=1, bottom=0.1, left=0.1, right=1, hspace=0.5, wspace=0.5)

9) 남여/나이

# 남여의 나이별 생존 현황
f, ax = plt.subplots(nrows=1, ncols=2, figsize=(14, 6))

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

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

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

ax[0].legend()
ax[0].set_title('Female')

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

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

ax[1].legend()
ax[1].set_title('Male')

10) 이름-신분

  • (1) 데이터 확인

    import re
    
    for idx, dataset in titanic.iterrows():
        tmp = dataset['name']
    print(re.search('\,\s\w+(\s\w+)?\.', tmp).group())

    , Mr.

  • (2) 데이터 형태 가공

    import re
    
    title = []
    for idx, dataset in titanic.iterrows():
      tmp = dataset['name'] # 일시저장
    
      # ,로 시작 - \s한칸을 띄우고 - \w글자들이 나오다가 - ?몇글자 인지 모르겠지만 - .으로 끝남
      # 대상은 tmp
      # [2:-1] 두번째 ~ 마지막 -> , Mr.
      title.append(re.search('\,\s\w+(\s\w+)?\.', tmp).group()[2:-1])
    
    title

    ['Miss',
    'Master',
    'Miss',
    'Mr',
    'Mrs',
    'Mr',

  • (3) 컬럼으로 추가

    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(1)
  • (4) 타이틀:인덱스, 성별:컬럼

    pd.crosstab(titanic['title'], titanic['sex'])
  • (5-1) 호칭 정리

    titanic['title'] = titanic['title'].replace('Mlle', 'Miss')
    titanic['title'] = titanic['title'].replace('Mme', 'Miss')
    titanic['title'] = titanic['title'].replace('Ms', 'Miss')
    
    #여성 귀족
    Rare_f = ['Dona', 'Lady', 'the Countess']
    #남성 귀족
    Rare_m = ['Capt', 'Col', 'Don', 'Dr', 'Jonkheer',
              'Major', 'Master', 'Rev', 'Sir']
    
    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')
  • (5-2) 호칭 정리

    for each in Rare_f: # 여성용 호칭에서 하나씩 가져와서
        titanic['title'] = titanic['title'].replace(each, 'Rare_f') # 각가을 전부다 Rare_f로 바꾸겠다
    
    for each in Rare_m: # 여성용 호칭에서 하나씩 가져와서
        titanic['title'] = titanic['title'].replace(each, 'Rare_m') # 각가을 전부다 Rare_f로 바꾸겠다
  • (5-3) 호칭 확인

    titanic['title'].unique()

    array(['Miss', 'Rare_m', 'Mr', 'Mrs', 'Rare_f'], dtype=object)

  • (5-4) groupby

    # [groupby] https://trading-for-chicken.tistory.com/134
    # 특정 열을 지정하여 groupby할 경우 해당 열이 인덱스가 되는데, as_index=False로 하여 기존 인덱스 유지
    titanic[['title', 'survived']].groupby(['title'], as_index=False).mean()




2. ML을 이용한 주인공 생존율 예측


⭐ 1) str -> int

머신 러닝을 위해서 컬럼은 모두 숫자로 바꿔야 함

# 컬럼들 형태 확인
titanic.info()
titanic['sex'].unique()

array(['female', 'male'], dtype=object)

# 숫자 형태로 변경
# 3   sex        1309 non-null   object 

# LabelEncoder 모듈
# 라벨 인코더 모듈 : 문자 -> 숫자 로 만들어 주는 것
from sklearn.preprocessing import LabelEncoder

# 변수 지정
le = LabelEncoder()

# fit 훈련 : (데이터, 정답)
le.fit(titanic['sex'])

# gender 컬럼 생성 + transform(변환)
titanic['gender'] = le.transform(titanic['sex'])

titanic.head(2)

⭐ 2) 결측치 버리기

  • 위와 같이 컬럼 마다 데이터수 가 다름
  • ML을 위해 결측치는 버리고 가기로!
titanic = titanic[titanic['age'].notnull()] # 1046
titanic = titanic[titanic['fare'].notnull()] # 1308

⭐ 3) 훈련/테스트 나누기

titanic.columns

Index(['pclass', 'survived', 'name', 'sex', 'age', 'sibsp', 'parch', 'ticket',
'fare', 'cabin', 'embarked', 'boat', 'body', 'home.dest', 'age_cat',
'title', 'gender'],
dtype='object')

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)

⭐ 4) Decision tree

# DecisionTreeClassifier 모듈
from sklearn.tree import DecisionTreeClassifier
# 성능 확인 모듈
from sklearn.metrics import accuracy_score

dt = DecisionTreeClassifier(max_depth=4, random_state=13)

# 훈련(특성, 라벨)
dt.fit(X_train, y_train)

# 훈련을 완료한 dt에 예측(성능) 명령
pred = dt.predict(X_test)

# (참값, 예측값)
accuracy_score(y_test, pred)

0.7655502392344498


⭐ 5) 두 주인공의 생존확률?

import numpy as np

# Jack
# 3등석, 18살, 부모형제 없음, 자녀없음, 탑승료, 남성
Deca = np.array([[3, 18, 0, 0, 5, 1]])
print('Deca :', dt.predict_proba(Deca))
print('Deca :', dt.predict_proba(Deca)[0, 1]) # 위 값의 첫,두번째 값만 출력해줘

# Rose
# 1등석, 16살, 
Wins = np.array([[1, 16, 1, 1, 100, 0]])
print('Rose :', dt.predict_proba(Wins))
print('Rose :', dt.predict_proba(Wins)[0, 1])

Deca : [[0.83271375 0.16728625]]
Deca : 0.16728624535315986
Rose : [[0. 1.]]
Rose : 1.0

profile
비전공자의 데이터 공부법

0개의 댓글