컴공생 누르지 마세요! 컴공생 울어요.
[ML] HA2 part1 (2) RandomForest with Titanic dataset 본문
📢 학교 수업에서 수행한 과제입니다.
이번 게시글에서는 titanic dataset에 대해 Random Forest 모델을 학습시켜 볼 것이다.
구글 코랩에서 코드를 작성 및 실행하였으며, 전체 코드는 지난 게시글을 참고하라.
- 지난 게시글
[ML] HA2 part1 (1) Decision trees with Breast cancer dataset
https://kwonppo.tistory.com/38
[ML] HA2 part1 (1) Decision trees with Breast cancer dataset
HA2 part1은 'Decision trees with Breast cancer dataset'과 'RandomForest with Titanic dataset' 두 가지로 이루어져 있다. 이번 게시글에서는 우선 Decision trees에 대해 다룰 것이다. 구글 코랩에서 코드를 작성 및 실행
kwonppo.tistory.com
그럼 우선 titanic dataset을 import한다.
!wget --no-check-certificate 'https://docs.google.com/uc?export=download&id=1Z-IGKwjJ2z-tzJUFa9pWmG3BdMULbTqm' -O titanic.csv
그 다음으로 데이터 preprocessing을 진행해준다.
print('\nNull Values in data \n{}'.format(df2.isnull().sum()))
print('\nDuplicated values in data {}'.format(df2.duplicated().sum()))
# Preprocess Embarked column
print('Embarkation per ports \n{}'.format(df2['Embarked'].value_counts()))
# since the most common port is Southampton the chances are that the missing one is from there
df2['Embarked'].fillna(value='S', inplace=True)
print('Embarkation per ports after filling \n{}'.format(df2['Embarked'].value_counts()))
# Preprocess Age column
mean_age_miss = df2[df2["Name"].str.contains('Miss.', na=False)]['Age'].mean().round()
mean_age_mrs = df2[df2["Name"].str.contains('Mrs.', na=False)]['Age'].mean().round()
mean_age_mr = df2[df2["Name"].str.contains('Mr.', na=False)]['Age'].mean().round()
mean_age_master = df2[df2["Name"].str.contains('Master.', na=False)]['Age'].mean().round()
print('Mean age of Miss. title {}'.format(mean_age_miss))
print('Mean age of Mrs. title {}'.format(mean_age_mrs))
print('Mean age of Mr. title {}'.format(mean_age_mr))
print('Mean age of Master. title {}'.format(mean_age_master))
def fill_age(name_age):
name = name_age[0]
age = name_age[1]
if pd.isnull(age):
if 'Mr.' in name:
return mean_age_mr
if 'Mrs.' in name:
return mean_age_mrs
if 'Miss.' in name:
return mean_age_miss
if 'Master.' in name:
return mean_age_master
if 'Dr.' in name:
return mean_age_master
if 'Ms.' in name:
return mean_age_miss
else:
return age
df2['Age'] = df2[['Name', 'Age']].apply(fill_age,axis=1)
# Preprocess Cabin column
df2['Cabin'] = pd.Series(['X' if pd.isnull(ii) else ii[0] for ii in df2['Cabin']])
print('Mean Fare of Cabin B {}'.format(df2[df2['Cabin']=='B']['Fare'].mean()))
print('Mean Fare of Cabin C {}'.format(df2[df2['Cabin']=='C']['Fare'].mean()))
print('Mean Fare of Cabin D {}'.format(df2[df2['Cabin']=='D']['Fare'].mean()))
print('Mean Fare of Cabin E {}'.format(df2[df2['Cabin']=='E']['Fare'].mean()))
def reasign_cabin(cabin_fare):
cabin = cabin_fare[0]
fare = cabin_fare[1]
if cabin=='X':
if (fare >= 113.5):
return 'B'
if ((fare < 113.5) and (fare > 100)):
return 'C'
if ((fare < 100) and (fare > 57)):
return 'D'
if ((fare < 57) and (fare > 46)):
return 'D'
else:
return 'X'
else:
return cabin
df2['Cabin'] = df2[['Cabin', 'Fare']].apply(reasign_cabin, axis=1)
# Check again if any col holds NULL
print('\nNull Values in data \n{}'.format(df2.isnull().sum()))
# Lastly, change the categorical features into numerical values
categories = {"female": 1, "male": 0}
df2['Sex']= df2['Sex'].map(categories)
categories = {"S": 1, "C": 2, "Q": 3}
df2['Embarked']= df2['Embarked'].map(categories)
categories = {"X": 1, "C": 2, "E": 3, "G": 4, "D": 5, "A": 6, "B": 7, "F": 8, "T": 9}
df2['Cabin'] = df2['Cabin'].map(categories)
# Drop unnecessary columns
# dropping columns
df2 = df2.drop(['Name','Ticket','PassengerId'], axis=1)
이제 전처리를 완료하였다. 데이터 형태를 확인해보자.
df2.head()
본격적인 training 전, dataset을 train set과 test set으로 나눠준다.
X = df2[['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Cabin', 'Embarked']]
y = df2['Survived']
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size= 0.2, random_state=0)
그 다음, data를 normalize 하기 위해 StandardScaler function을 사용한다.
from sklearn.preprocessing import StandardScaler
def scaler_samples(train_X,test_X):
scaler = StandardScaler()
train_X = scaler.fit_transform(train_X)
test_X = scaler.transform(test_X)
return train_X, test_X
x_train, x_test = scaler_samples(x_train, x_test)
그럼 이제 본격적으로 preprocessed titanic dataset에 대해 Random Forest model을 학습해보자. 주어진 input feature를 통해 해당 passenger가 살 수 있는지 없는지를 predict하는 모델을 만들 것이다.
이때, n_estimator = 20, criterion = "entropy"를 사용하였다.
from sklearn.ensemble import RandomForestClassifier
clf = RandomForestClassifier(n_estimators=20, criterion="entropy", max_depth=100, min_samples_split=2, max_features="sqrt", random_state=0)
clf.fit(x_train, y_train)
이제 fit한 모델에 대해 accuracy와 confusion matirx를 확인해보자.
from sklearn.metrics import accuracy_score
y_pred = clf.predict(x_test)
acc = accuracy_score(y_test, y_pred)
print("Accuracy: ", acc)
from sklearn.metrics import confusion_matrix
confusion_matrix(y_test, y_pred)
이제 importance score 기반 feature ranking을 확인해보자.
import seaborn as sns
import matplotlib.pyplot as plt
feature_imp = pd.Series(clf.feature_importances_, index=X.columns).sort_values(ascending=False)
plt.figure(figsize=(10,6))
sns.barplot(x=feature_imp, y=feature_imp.index)
# Add labels to graph
plt.xlabel('Feature Importance Score')
plt.ylabel('Features')
plt.title("Feature Rankings")
plt.tight_layout()
Age, Fare, Sex가 more important feature인 것을 확인할 수 있다.
그럼 이제 Grid Search를 이용하여 Hyperparameter tuning을 수행해보자.
from sklearn.model_selection import GridSearchCV
param_grid = {'n_estimators': [20, 50, 100, 200],
'criterion': ['gini', 'entropy']}
grid = GridSearchCV(RandomForestClassifier(), param_grid, refit=True, verbose=3)
grid.fit(x_train, y_train)
tuning 결과를 확인해보자.
# the best parameters
print(grid.best_params_)
# the model accuracy
grid_pred = grid.predict(x_test)
print("Accuracy: {}".format(accuracy_score(y_test, grid_pred)))
# the confusion matrix
confusion_matrix(y_test, grid_pred)
그럼 이제 hyperparameter tuning 전후 performance를 비교해보자.
(1) Accuracy 비교
튜닝 전의 accuracy: 0.8156424581005587
튜닝 후의 accuracy: 0.8268156424581006
튜닝 후 accuracy가 소폭 증가했음을 알 수 있다.
(2) Confusion matrix 비교
튜닝 전의 confusion matrix: array([[99, 11], [22, 47]])
튜닝 후의 confusion matrix: array([[98, 12], [19, 50]])
정답 클래스가 0인 경우에 대해서는 예측 클래스가 정답 클래스와 같은 표본의 수가 1 줄어들었지만, 정답 클래스가 1인 경우에 대해서는 예측 클래스가 정답 클래스와 같은 표본의 수가 3 늘었음을 알 수 있다.
따라서 hyperparameter tuning을 통해 model performance가 향상되었다고 볼 수 있다.
'STUDY > 기계학습' 카테고리의 다른 글
[ML] HA2 part2 PCA & K-NN (0) | 2023.02.08 |
---|---|
[ML] HA2 part1 (1) Decision trees with Breast cancer dataset (1) | 2022.12.19 |
[ML] HA1 part2 Support vector machines with Iris dataset (0) | 2022.12.19 |
[ML] HA1 part1 (3) Gaussian discriminant analysis (Gaussian Naive Bayes) with iris dataset (0) | 2022.12.19 |
[ML] HA1 part1 (2) Logistic regression with Titanic dataset (0) | 2022.12.19 |