[2장-3] 타이타닉 생존자 예측 ML 구현
https://colab.research.google.com/drive/1pho8HoLe11nTAIvwRglZY83W2eTKs2IO?usp=sharing
Titanic_240206
Colaboratory notebook
colab.research.google.com
1) 사전작업
* 데이터 전처리
- NULL값, 불필요한 속성 제거, 인코딩 수행
*모델학습 및 검증,예측,평가
- 결정트리, 랜덤포레스트, 로지스틱회귀, K폴드 교차 검증, cross_val_score(), gridsearchCV()
2) 파일 불러오기
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
titanic_df = pd.read_csv('/train.csv')
titanic_df.head(3)
2-1) 속성 설명
- Passengerid: 탑승자 데이터 일련번호
- survived: 생존 여부, 0 = 사망, 1 = 생존
- Pclass: 티켓의 선실 등급, 1 = 일등석, 2 = 이등석, 3 = 삼등석
- sex: 탑승자 성별
- name: 탑승자 이름
- Age: 탑승자 나이
- sibsp: 같이 탑승한 형제자매 또는 배우자 인원수
- parch: 같이 탑승한 부모님 또는 어린이 인원수
- ticket: 티켓 번호
- fare: 요금
- cabin: 선실 번호
- embarked: 중간 정착 항구 C = Cherbourg, Q = Queenstown, S = Southampton
3) 데이터 정보 보기(info사용)
titanic_df.info()
3-1) describe로 사분위표 보기
titanic_df.describe()
# transpose(): #transpose는 행과 열을 바꿔서 볼 때 사용
titanic_df.describe().transpose()
4) 속성 정리(NULL값 처리)
- age를 평균 값으로 사용 → mean 사용
- cabin은 null값이 너무 많기 때문에 N으로 넣어버리기
- embarked도 중요한 속성이 아니기 때문에 N으로 바꿔버리기
# 결측값을 mean 평균값으로 채우기
#fillna(~로 채워라), age를 mean값으로 넣자, inplace=true 즉시 적용하는 것
titanic_df['Age'].fillna(titanic_df['Age'].mean(), inplace=True)
# null값을 평균값, 0 등으로 처리할때는 fillna(0, inplace=True)을 사용하여 대체
# 특정컬럼의 결측치값만 대체하고 싶을 때는 데이터프레임['특정 컬럼명'].fillna(0, inplace=True)를 사용
titanic_df['Cabin'].fillna('N', inplace=True)
titanic_df['Embarked'].fillna('N', inplace=True)
# null 값 개수 확인
titanic_df.isnull().sum()
titanic_df.isnull().sum().sum()
5-1) object 컬럼 타입 확인
# object 컬럼 타입 추출
titanic_df.dtypes[titanic_df.dtypes =='object']
# index.tolist() : 인덱스를 리스트로 출력
titanic_df.dtypes[titanic_df.dtypes =='object'].index.tolist()
print('성별 값 분포: \n', titanic_df['Sex'].value_counts())
print('cabin 값 분포포: \n', titanic_df['Cabin'].value_counts())
print('Embarked 값 분포포: \n', titanic_df['Embarked'].value_counts())
# 맨 앞자리만 출력
titanic_df['Cabin'].str[:1]
titanic_df['Cabin']=titanic_df['Cabin'].str[:1]
titanic_df['Cabin'].head()
5-2) 성별과 생존을 묶기(groupby 사용)
titanic_df.groupby(['Sex','Survived'])
- count 확인
titanic_df.groupby(['Sex','Survived']).count()
titanic_df.groupby(['Sex','Survived'])['Survived'].count()
# value_counts(). 각각의 값이 나온 횟수를 센다
titanic_df['Survived'].value_counts()
sns.barplot(x='Pclass',y='Survived', hue='Sex', data=titanic_df)
- 3등급의 사람들은 여자, 남자 모두 생존률이 낮다
6-1) 나이대 별로 생존률 예측
6-2) label encoding 진행
- cabin, sex, embarked 세개 돌려서 숫자로 바꾸기
# 불필요한 feature 삭제
# LabelEncoder: 문자를 수치화
from sklearn.preprocessing import LabelEncoder
# Null 처리 함수
def fillna(df):
df['Age'].fillna(df['Age'].mean(),inplace=True)
df['Cabin'].fillna('N', inplace=True)
df['Embarked'].fillna('N', inplace=True)
return df
# 머신러닝 알고리즘에 불필요한 피처 제거
def drop_features(df):
df.drop(['Passengerld', 'Name', 'Ticket'], axis=1, inplace=True)
return df
# 레이블 인코딩 수행.
def format_features(df):
df['Cabin']=df['Cabin'].str[:1]
features =['Cabin','Sex','Embarked']
for feature in feature:
le =LabelEncoder()
le=le.fit(df[feature])
df[feature]=le.transform(df[feature])
return df
# 앞에서 설정한 Data Preprocessing 함수 호출
def transform_features(df):
df=fillna(df)
df=drop_features(df)
df=format_features(df)
return df
titanic_df.head()
# 원본 데이터를 재로딩 하고, feature데이터 셋과 Label 데이터 셋 추출.
titanic_df = pd.read_csv('./titanic_train.csv')
y_titanic_df = titanic_df['Survived']
X_titanic_df= titanic_df.drop('Survived',axis=1, inplace=False)
X_titanic_df = transform_features(X_titanic_df)
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test=train_test_split(X_titanic_df, y_titanic_df, \
test_size=0.2, random_state=11)
print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)
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(solver='liblinear')
# DecisionTreeClassifier 학습/예측/평가
dt_clf.fit(X_train , y_train)
dt_pred = dt_clf.predict(X_test)
print('DecisionTreeClassifier 정확도: {0:.4f}'.format(accuracy_score(y_test, dt_pred)))
# RandomForestClassifier 학습/예측/평가
rf_clf.fit(X_train , y_train)
rf_pred = rf_clf.predict(X_test)
print('RandomForestClassifier 정확도:{0:.4f}'.format(accuracy_score(y_test, rf_pred)))
# LogisticRegression 학습/예측/평가
lr_clf.fit(X_train , y_train)
lr_pred = lr_clf.predict(X_test)
print('LogisticRegression 정확도: {0:.4f}'.format(accuracy_score(y_test, lr_pred)))
X_titanic_df.values[[0, 1, 2, 3, 4, 5]]
from sklearn.model_selection import KFold
def exec_kfold(clf, folds=5):
# 폴드 세트를 5개인 KFold객체를 생성, 폴드 수만큼 예측결과 저장을 위한 리스트 객체 생성.
kfold = KFold(n_splits=folds)
scores = []
# KFold 교차 검증 수행.
for iter_count , (train_index, test_index) in enumerate(kfold.split(X_titanic_df)):
# X_titanic_df 데이터에서 교차 검증별로 학습과 검증 데이터를 가리키는 index 생성
X_train, X_test = X_titanic_df.values[train_index], X_titanic_df.values[test_index]
y_train, y_test = y_titanic_df.values[train_index], y_titanic_df.values[test_index]
# Classifier 학습, 예측, 정확도 계산
clf.fit(X_train, y_train)
predictions = clf.predict(X_test)
accuracy = accuracy_score(y_test, predictions)
scores.append(accuracy)
print("교차 검증 {0} 정확도: {1:.4f}".format(iter_count, accuracy))
# 5개 fold에서의 평균 정확도 계산.
mean_score = np.mean(scores)
print("평균 정확도: {0:.4f}".format(mean_score))
# exec_kfold 호출
exec_kfold(dt_clf , folds=5)
from sklearn.model_selection import cross_val_score
scores = cross_val_score(dt_clf, X_titanic_df , y_titanic_df , cv=5)
for iter_count,accuracy in enumerate(scores):
print("교차 검증 {0} 정확도: {1:.4f}".format(iter_count, accuracy))
print("평균 정확도: {0:.4f}".format(np.mean(scores)))
from sklearn.model_selection import GridSearchCV
GridSearchCV란 머신러닝에서 모델의 성능향상을 위해 쓰이는 기법
- 사용자가 직접 모델의 하이퍼 파라미터의 값을 리스트로 입력하면 값에 대한 경우의 수마다 예측 성능을 측정 평가하여 비교하면서 최적의 하이퍼 파라미터 값을 찾는 과정을 진행
from sklearn.model_selection import GridSearchCV
parameters = {'max_depth':[2,3,5,10],
'min_samples_split':[2,3,5], 'min_samples_leaf':[1,5,8]}
grid_dclf = GridSearchCV(dt_clf, param_grid=parameters, scoring='accuracy', cv=5)
grid_dclf.fit(X_train, y_train)
print('GridSearchCV 최적 하이퍼 파라미터 :', grid_dclf.best_params_)
print('GridSearchCV 최고 정확도: {0:.4f}'.format(grid_dclf.best_score_))
best_dclf = grid_dclf.best_estimator_
# GridSearchCV의 최적 하이퍼 파라미터로 학습된 Estimator로 예측 및 평가 수행.
dpredictions = best_dclf.predict(X_test)
accuracy = accuracy_score(y_test , dpredictions)
print('테스트 세트에서의 DecisionTreeClassifier 정확도 : {0:.4f}'.format(accuracy))