본문 바로가기
개념정리/머신러닝

머신러닝 - 사이킷런으로 수행하는 타이타닉 생존자 예측

by 화영쌤 2023. 5. 11.
728x90

▷ 데이터 전처리 하기

- 관련 모듈 import 하기

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

 

- 데이터 불러오기

df = pd.read_csv('titanic_train.csv')

 

- 결측치 확인하기

df.isna().sum()

 

- 결측치 처리하기 ( 나이는 평균으로 처리, 선실번호 & 중간 정착항구는 N 으로 처리 )

df['Age'].fillna(df['Age'].mean(),inplace=True)
df['Cabin'].fillna('N',inplace=True)
df['Embarked'].fillna('N',inplace=True)

 

- 데이터 정제하기 ( 선실번호를 알파벳으로만 구분 ex) C48  → C )

df['Cabin'].str[:1]

 

- 그룹으로 묶기 ( 탑승자 성별 & 생존여부 ) 

df.groupby(['Sex','Survived'])['Survived'].count()

 

- 시각화하기

① 탑승자 성별 & 생존여부

sns.barplot(x='Sex',y='Survived',data=df)

 

② 객실등급 & 생존여부 & 성별

sns.barplot(x='Pclass',y='Survived',hue='Sex',data=df)

 

③ 나이 & 생존여부 & 성별

  •  나이 데이터 전처리하기
def get_category(age):
    cat=''
    if age <= -1:
        cat = 'Unknown'
    elif age <= 7:
        cat = 'Baby'
    elif age <= 13:
        cat = 'Child'
    elif age <= 19:
        cat = 'Teenager'
    elif age <= 26:
        cat = 'Student'
    elif age <= 35:
        cat = 'Young Adult'
    elif age <= 60:
        cat = 'Adult'
    else:
        cat = 'Elderly'
    return cat

 

  • 나이 데이터 적용하기
df['Age_cat'] = df['Age'].apply(get_category)

 

  • 시각화하기  ( 나이순으로 정렬하기 위해 list 안에 값을 넣고 barplot 안에 order 값으로 넣어줌 )
plt.figure(figsize=(8,6))
order_list=['Unknown','Baby','Child','Teenager','Student','Young Adult','Adult','Elderly']
sns.barplot(x='Age_cat',y='Survived',hue='Sex',data=df,order=order_list)
df.drop(columns='Age_cat',inplace=True)

 

- 문자열 카테고리 피처 → 숫자형 카테고리 피처로 변환

# 관련 모듈 import 하기
from sklearn.preprocessing import LabelEncoder

# 함수 생성하기
def encode_features(df):
    features = ['Cabin','Sex','Embarked']
    for feature in features:
        le = LabelEncoder()
        df[feature] = le.fit_transform(df[feature])
    return df

# 함수 적용하기
df = encode_features(df)

# 값 출력하기
df.head()


▷ 데이터 전처리 함수 만들기

# Null 처리 함수
def fillna(df):
    df['Age'].fillna(df['Age'].mean(),inplace=True)
    df['Cabin'].fillna('N',inplace=True)
    df['Embarked'].fillna('N',inplace=True)
    df['Fare'].fillna(0,inplace=True)
    return df

# 머신러닝 알고리즘에 불필요한 속성 제거
def drop_features(df):
    df.drop(['PassengerId','Name','Ticket'],axis=1,inplace=True)
    return df

# 레이블 인코딩 수행
def format_features(df):
    # 관련 모듈 import 하기
    from sklearn.preprocessing import LabelEncoder
    df['Cabin'] = df['Cabin'].str[:1]
    features = ['Cabin','Sex','Embarked']
    for feature in features:
        le = LabelEncoder()
        df[feature] = le.fit_transform(df[feature])
    return df

# 앞에서 설정한 데이터 전처리 함수 호출
def transform_features(df):
    df = fillna(df)
    df = drop_features(df)
    df = format_features(df)
    return df

 

- 원본 데이터를 재로딩하고, 피처 데이터 세트와 레이블 데이터 세트 추출

df = pd.read_csv('titanic_train.csv')
y = df['Survived']
x = df.drop(columns='Survived')
x = transform_features(x)


▷ 정확도 측정하기

# 관련 모듈 import 하기
from sklearn.model_selection import train_test_split

# train_test_split()를 이용해 테스트 데이터 테스트 추출하기
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.2,random_state=11)

 

- Clasifier 클래스를 통한 정확도 측정하기

# 관련 모듈 import 하기
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score

# 결정트리, Random Forest, 로지스틱 회귀를 위한 사이킷런 Classifier 클래스 생성
dt_clf = DecisionTreeClassifier(random_state = 11)
rf_clf = RandomForestClassifier(random_state = 11)
lr_clf = LogisticRegression()

# 학습하기
dt_clf.fit(x_train,y_train)
rf_clf.fit(x_train,y_train)
lr_clf.fit(x_train,y_train)

# 예측하기
dt_pred = dt_clf.predict(x_test)
rf_pred = rf_clf.predict(x_test)
lr_pred = lr_clf.predict(x_test)

# 평가하기
print(f'{dt_clf.__class__.__name__} 정확도 : {accuracy_score(y_test,dt_pred)}')
print(f'{rf_clf.__class__.__name__} 정확도 : {accuracy_score(y_test,rf_pred)}')
print(f'{lr_clf.__class__.__name__} 정확도 : {accuracy_score(y_test,lr_pred)}')

 

- 교차 검증을 통한 정확도 측정하기

① KFold 클래스

# 관련 모듈 import 하기
from sklearn.model_selection import KFold

# 함수 생성하기
def exec_kfold(x,clf,folds = 5):
	# 폴드 세트를 5개인 KFold 객체를 생성
    kfold = KFold(n_splits=folds)
    # 폴드 수만큼 예측결과 저장을 위한 리스트 객체 생성
    scores = []
    # KFold 교차 검증 수행
    for iter_count, (train_index,test_index) in enumerate(kfold.split(x)):
    	# x 데이터에서 교차 검증별로 학습과 검증 데이터를 가리키는 index 생성
        x_train,x_test = x.values[train_index],x.values[test_index]
        y_train,y_test = y.values[train_index],y.values[test_index]
        # Classifier 학습
        clf.fit(x_train,y_train)
        # Classifier 예측
        pred = clf.predict(x_test)
        # Classifier 정확도계산
        accuracy = accuracy_score(y_test,pred)
        scores.append(accuracy)
        # 교차 검증 정확도 출력(소수점 넷째자리까지)
        print(f'{iter_count} 교차 검증 정확도 : {accuracy:.4f}')
    # 5개 fold 에서의 평균 정확도 계산(소수점 넷째자리까지)
    print(f'평균 정확도 : {np.mean(scores):.4f}')

 

- 결정트리 정확도 계산하기

 

  • 교차 검증 전 정확도 ( 78.7% )

 

  • 교차 검증 후 정확도 ( 78.2% )
exec_kfold(x,dt_clf)

 

- Random Forest 정확도 계산하기

 

  • 교차 검증 전 정확도 ( 85.4% )

 

  • 교차 검증 후 정확도 ( 81.4% )
exec_kfold(x,rf_clf)

 

- 로지스틱 회귀 정확도 계산하기

 

  • 교차 검증 전 정확도 ( 84.9% )

 

  • 교차 검증 후 정확도 ( 78.6% )
exec_kfold(x,lr_clf)


② cross_val_score() API

# 관련 모듈 import 하기
from sklearn.model_selection import cross_val_score

 

- 결정트리 정확도 계산하기 ( 78.7% )

dt_s = cross_val_score(dt_clf,x,y,cv=5)
for iter_count,accuracy in enumerate(dt_s):
    print(f'교차검증 {iter_count}  정확도 : {accuracy}')
print(f'평균정확도 : {np.mean(dt_s)}')

 

- Random Forest 정확도 계산하기 ( 81.3% )

rf_s = cross_val_score(rf_clf,x,y,cv=5)
for iter_count,accuracy in enumerate(rf_s):
    print(f'교차검증 {iter_count}  정확도 : {accuracy}')
print(f'평균정확도 : {np.mean(rf_s)}')

 

- 로지스틱 회귀 정확도 계산하기 ( 78.6% )

lr_s = cross_val_score(lr_clf,x,y,cv=5)
for iter_count,accuracy in enumerate(lr_s):
    print(f'교차검증 {iter_count}  정확도 : {accuracy}')
print(f'평균정확도 : {np.mean(lr_s)}')


③ GridSearchCV 

# 관련 모듈 import 하기
from sklearn.model_selection import GridSearchCV

 

- 결정트리 정확도 계산하기 ( 87.1% )

param = {'max_depth':[2,3,5,10],
    	 'min_samples_split':[2,3,5],
    	 'min_samples_leaf':[1,5,8]}

grid_dtclf = GridSearchCV(dt_clf,param_grid=param,scoring='accuracy',cv=5)
grid_dtclf.fit(x_train,y_train)
print('최적 하이퍼 파라미터 : ',grid_dtclf.best_params_)
print('최고 정확도 : ',grid_dtclf.best_score_)

best_dtclf = grid_dtclf.best_estimator_
pred = best_dtclf.predict(x_test)
accuracy_score(y_test,pred)

 

- Random Forest 정확도 계산하기 ( 88.2% )

param = {'max_depth':[2,3,5,10],
    'min_samples_split':[2,3,5],
    'min_samples_leaf':[1,5,8],
    'n_estimators':[100,200]}
grid_rfclf = GridSearchCV(rf_clf,param_grid=param,scoring='accuracy',cv=5)
grid_rfclf.fit(x_train,y_train)
print('최적 하이퍼 파라미터 : ',grid_rfclf.best_params_)
print('최고 정확도 : ',grid_rfclf.best_score_)
best_rfclf = grid_rfclf.best_estimator_
pred = best_rfclf.predict(x_test)
accuracy_score(y_test,pred)