멋쟁이사자처럼 X K-DIGITAL Training - 07.05
[github] https://github.com/ijo0r98/likelion-kdigital/tree/main/semi-project-2
import warnings
warnings.filterwarnings("ignore")
import pandas as pd
import numpy as np
data_df = pd.read_csv('titanic.csv')
y_data = data_df[['Survived']] # target data
del data_df['Survived']
* 컬럼 정보
- PassengerId : 각 승객 고유번호
- Survived : 생존여부
- Pclass : 객실 등급 (1 / 2 / 3)
- Name : 승객 이름
- Sex : 성별
- Age : 나이
- SibSp : 동반한 형재자매, 배우자 수
- Parch : 동반한 부모, 자식 수
- Ticket : 티켓 고유번호
- Fare : 티켓 요금
- Cabin : 객실 번호
- Embarked : 승선한 항 (C-Cherbourg / Q-Queenstown / S-Southampton)
2-1. 결측치 확인
data_df.isnull().sum()
missionno 라이브러리로 결측치 시각화
import quilt
import missingno as msno
import matplotlib.pyplot as plt
msno.matrix(data_df)
msno.bar(data_df)
→ 결측치 있는 열: Age, Cabin, Embarked
2-1-1) Cabin (객실번호)
- 해당 열 삭제
del data_df['Cabin']
2-1-2) Embarked (승선한 항)
data_df[data_df.Embarked.isnull()]
- 두 승객 모두 1등급에 탑승한 승객
- 두 승객과 동일하게 1등급에 탑승한 승객들의 Embarked별 요금의 평균 구하여 비교
# 1등급 승객
class1st = data_df[data_df.Pclass == 1]
# 1등급 승객 중 각 Embarked별 Fare 평균
class1st_C = class1st[class1st.Embarked == 'C']['Fare'].mean()
class1st_S = class1st[class1st.Embarked == 'S']['Fare'].mean()
class1st_Q = class1st[class1st.Embarked == 'Q']['Fare'].mean()
print("Boarded from Cherbourg:", class1st_C)
print("Boarded from Southampton:", class1st_S)
print("Boarded from Queenstown:", class1st_Q)
>> Boarded from Cherbourg: 104.71852941176469
Boarded from Southampton: 70.36486220472443
Boarded from Queenstown: 90.0
- 1등급 승객 중 Embarked가 S, Q인 승객과 요금이 비슷함으로 두 항구에서 승선한 승객들의 비율 계산
# df.shape[0] >> 행의 수 (전체 데이터 수)
print("Southampton:", str(round(class1st[class1st['Embarked'] == 'S'].shape[0] / class1st.shape[0]*100, 2)) + "%")
print("Queenstown:", str(round(class1st[class1st['Embarked'] == 'Q'].shape[0] / class1st.shape[0]*100, 2)) + "%")
>> Southampton: 58.8%
Queenstown: 0.93%
- 둘 중 비율이 더 높은 S로 대체
data_df['Embarked'][61] = 'S'
data_df['Embarked'][829] = 'S'
2-1-3) Age (나이)
- 이름에 포함된 Mr, Mrs, Miss 등을 기준으로 이름 그룹 나눔
def get_name_group(name):
# Braund, Mr. Owen Harris
start = name.find(', ')
end = name.find('.')
return name[start+1:end]
data_df['name_group'] = data_df.Name.apply(get_name_group)
- 이름 그룹별로 나이 평균을 계산
age_group_mean = dict(data_df.groupby(['name_group'])['Age'].mean())
- 나이 정보가 없는 승객의 경우 해당 승객이 속한 이름 그룹의 나이 평균값으로 정보 대체
for index in data_df[data_df.Age.isnull()].index:
name = data_df.loc[index, 'name_group']
data_df.loc[index, 'Age'] = age_group_mean[name]
2-2. Feature 수치화, 범주화
2-2-1) Sex (성별)
# ('male', 'female') -> (0, 1)
data_df['Sex']=data_df['Sex'].replace(['male', 'female'], [0, 1])
2-2-2) Age (나이)
data_df['age_group'] = data_df['Age'].apply(lambda x: int(x/10))
2-2-3) Embarked (승선한 항)
def embarked_categorized(em):
if em == 'S':
return 0
elif em == 'C':
return 1
else:
return 2
data_df['emb_cat'] = data_df.Embarked.apply(embarked_categorized)
2-2-4) SibSp & Parch → companion (동행 여부)
- 티켓 번호가 같을 시 일행으로 보고 동일한 티켓의 수를 일행(companion) 수라고 가정
count_dict = dict(data_df['Ticket'].value_counts())
data_df['companion'] = data_df['Ticket'].apply(lambda x : count_dict[x])
- Sibsp, Parch 둘 다 0이고 티켓 넘버가 같은 것도 없을 경우 일행이 없는 것으로 간주
- 일행이 없을 때 0, 있을 때는 1
data_df['companion'] = [0 if data_df['SibSp'][x] == 0 and data_df['Parch'][x] == 0 and count_dict[data_df['Ticket'][x]] == 1 else 1 for x in data_df.index ]
2-2-5) Fare (요금)
data_df['fare_cat'] = pd.qcut(data_df['Fare'], 5) # 범주화
data_df['fare_cat'] = data_df['fare_cat'].astype('category').cat.codes ]
- pandas.qcut() : 주어진 개수의 범주로 나누기
pandas.cut() : 동일한 길이의 범주로 나누기
- astype('category') : 데이터 타입 'category'로 변경 예) 정수형은 .astype(‘int’)
- cat : 특수 메서드로 카테고리 속성, codes나 categorical 메서드 등에 쉽게 접근
2-3. Feature 선택 (X_data)
data_df.columns
>> Index(['PassengerId', 'Pclass', 'Name', 'Sex', 'Age', 'SibSp', 'Parch', 'Ticket', 'Fare', 'Embarked', 'name_group', 'age_group', 'emb_cat', 'companion', 'fare_cat'], dtype='object')
X_data = data_df[['Pclass', 'Sex', 'age_group', 'fare_cat', 'emb_cat', 'companion']]
- test data 30% / train data 70% / random_state=0 (랜덤 패턴)
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X_data, y_data, test_size=0.3, random_state=0)
(온갖 모델은 다 해볼 예정 ..! 🙄)
* 교차 검증 (CV, Cross Validation)
고정된 test set으로 모델의 성능을 검증하게 되면 test data에 과적합(overfitting)하게 됨
이를 해결하기 위해 train set을 train set과 validation set으로 분리하여 validation set을 사용하여 검증
총 데이터 개수가 적은 데이터셋에 대하여 정확도를 향상시킬 수 있음
* k-fold 교차검증
k 개의 fold를 만들어서 진행하는 교차 검증
(보통 회귀 모델에 사용되며 데이터가 독립적이고 동일한 분포를 가진 경우 사용)
1) 전체 데이터셋을 training set과 test set으로 나눈다
2) training set을 training + validation set 으로 사용하기 위해 k개의 fold로 나눈다.
3) 첫 번째 fold를 validation set으로 사용하고 나머지를 training set으로 사용
4) 모델을 학습시킨 뒤 validation set으로 평가
5) 다음 차례 fold로 3~4번 반복
6) 총 k개의 성능 결과가 나오며 이 k개의 평균을 해당 학습 모델의 성능이라 한다.
코드 예시)
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
# k-fold 설정
k_fold = KFold(n_splits=10, shuffle=True, random_state=0)
# 모델 생성
dt = DecisionTreeClassifier()
# 교차 검증 수행
score = cross_val_score(dt, iris.data, iris.target, cv=kfold, scoring="accuracy")
* sklearn의 kFold는 label을 고르게 분배하지 않아 shuffle=True 설정해주는 것이 좋음
- kFold(fold 수(k), 데이터 분할 전 섞을지 여부, 랜덤 패턴)
- cross_val_score(model, feature, target, cv설정값, scoring 평가 방법) : kfold 교차검증 수행하여 평균값으로 모델의 정확도(성능)를 알려줌
* StratifiedKFold 교차검증
더 고르게 분할됨
kfold = StratifiedKFold(n_splits=3)
* 모델의 성능 평가
주어진 test set에 대한 모델의 성능 평가
- accuracy_score() : sklearn 메서드
from sklearn.metrics import accuracy_score
accuracy_score(y_test, dt.predict(x_test))
- score() : 모델 객체 메서드
model.score(x_test, y_test)
4-0. 라이브러리
import warnings
warnings.filterwarnings(action='ignore')
# model
from sklearn import linear_model
from sklearn.neighbors import KNeighborsClassifier # kNN
from sklearn.tree import DecisionTreeClassifier # DC
from sklearn.ensemble import RandomForestClassifier # RF
from sklearn.naive_bayes import GaussianNB # NB
from sklearn.svm import SVC # SVC
from xgboost import XGBClassifier # XGB
from sklearn.metrics import accuracy_score # 모델 정확도 평가 (accuracy)
# k-fold
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
4-1. KNN
clf_kNN = KNeighborsClassifier(n_neighbors = 13)
scoring = 'accuracy'
score = cross_val_score(clf_kNN, X_data, y_data, cv=k_fold, n_jobs=1, scoring=scoring)
print(round(np.mean(score)*100,2))
>> 79.34
clf_kNN.fit(X_train, y_train)
>> KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski', metric_params=None, n_jobs=None, n_neighbors=13, p=2, weights='uniform')
predict_kNN = clf_kNN.predict(X_test)
accuracy_kNN = accuracy_score(y_test,predict_kNN)
>> 0.7873134328358209
4-2. Decision Tree
clf_DT = DecisionTreeClassifier()
scoring = 'accuracy'
score = cross_val_score(clf_DT, X_data, y_data, cv=k_fold, n_jobs=1, scoring=scoring)
>> 81.25
clf_DT.fit(X_train, y_train)
>> DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None, max_features=None, max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, min_samples_leaf=1, min_samples_split=2, min_weight_fraction_leaf=0.0, presort=False, random_state=None, splitter='best')
predict_DT = clf_DT.predict(X_test)
accuracy_DT = accuracy_score(y_test,predict_DT)
>> 0.8059701492537313
4-3. Random Forest
clf_RF = RandomForestClassifier(n_estimators=13)
scoring = 'accuracy'
score = cross_val_score(clf_RF, X_data, y_data, cv=k_fold, n_jobs=1, scoring=scoring)
>> 82.04
clf_RF.fit(X_train, y_train)
>> RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini', max_depth=None, max_features='auto', max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, min_samples_leaf=1, min_samples_split=2, min_weight_fraction_leaf=0.0, n_estimators=13, n_jobs=None, oob_score=False, random_state=None, verbose=0, warm_start=False)
predict_RF = clf_RF.predict(X_test)
accuracy_RF = accuracy_score(y_test,predict_RF)
>> 0.8246268656716418
4-4. Naive Bayes
clf_NB = GaussianNB()
scoring = 'accuracy'
score = cross_val_score(clf_NB, X_data, y_data, cv=k_fold, n_jobs=1, scoring=scoring)
>> 75.98
clf_NB.fit(X_train, y_train)
>> GaussianNB(priors=None, var_smoothing=1e-09)
predict_NB = clf_NB.predict(X_test)
accuracy_NB = accuracy_score(y_test,predict_NB)
>> 0.7723880597014925
4-5. SVM
clf_SVC = SVC(probability=True)
scoring = 'accuracy'
score = cross_val_score(clf_SVC, X_data, y_data, cv=k_fold, n_jobs=1, scoring=scoring)
>> 81.37
clf_SVC.fit(X_train, y_train)
>> SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, decision_function_shape='ovr', degree=3, gamma='auto_deprecated', kernel='rbf', max_iter=-1, probability=True, random_state=None, shrinking=True, tol=0.001, verbose=False)
predict_SVC = clf_SVC.predict(X_test)
accuracy_SVC = accuracy_score(y_test,predict_SVC)
>> 0.8059701492537313
4-6. Logistic Regression
clf_LR = linear_model.LogisticRegression()
scoring = 'accuracy'
score = cross_val_score(clf_LR, X_data, y_data, cv=k_fold, n_jobs=1, scoring=scoring)
>> 78.68
clf_LR.fit(X_train, y_train)
>> LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True, intercept_scaling=1, max_iter=100, multi_class='warn', n_jobs=None, penalty='l2', random_state=None, solver='warn', tol=0.0001, verbose=0, warm_start=False)
predict_LR = clf_LR.predict(X_test)
accuracy_LR = accuracy_score(y_test,predict_LR)
>> 0.7947761194029851
4-7. XGBoost
clf_XGB = XGBClassifier(seed = 0, n_jobs = -1, learning_rate = 0.1, n_estimators = 100, max_depth = 3)
scoring = 'accuracy'
score = cross_val_score(clf_XGB, X_data, y_data, cv=k_fold, n_jobs=1, scoring=scoring)
>> 81.37
clf_XGB.fit(X_train, y_train)
>> XGBClassifier(base_score=0.5, booster='gbtree', colsample_bylevel=1, colsample_bytree=1, gamma=0, learning_rate=0.1, max_delta_step=0, max_depth=3, min_child_weight=1, missing=None, n_estimators=100, n_jobs=-1, nthread=None, objective='binary:logistic', random_state=0, reg_alpha=0, reg_lambda=1, scale_pos_weight=1, seed=0, silent=True, subsample=1)
predict_XGB = clf_XGB.predict(X_test)
accuracy_XGB = accuracy_score(y_test, predict_XGB)
>> 0.835820895522388
[K-DIGITAL] 세미프로젝트2. 타이타닉 생존자 예측 모델 만들기(2) (0) | 2021.07.06 |
---|---|
[K-DIGITAL] 텍스트데이터 분석 TF-IDF과 유사도 계산 (0) | 2021.07.06 |
[K-DIGITAL] 머신러닝 알고리즘(5) 스태킹 앙상블(Stacking Ensemble), vecstack 실습 (0) | 2021.07.01 |
[K-DIGITAL] 머신러닝 알고리즘(4) KNN, K-means - sklearn 실습 (0) | 2021.07.01 |
[K-DIGITAL] 머신러닝 알고리즘(4) KNN, K-MEANS, PCA (0) | 2021.07.01 |
댓글 영역