본문 바로가기
Code Example

Support Vector Machine(SVM)을 활용한 타이타닉 생존자 예측

by Oceanlighth AI 2023. 3. 16.
Support Vector Machine을 이용하여 타이타닉 생존자 예측하기

오늘은 Support Vector Machine 이용하여  타이타닉호의 생존자를 예측해보도록 하겠습니다.

 

이번에도 Kaggle에서 가져온 데이터를 사용해 보도록 하겠습니다.

train.csv
0.06MB
test.csv
0.03MB

Library 불러오기
import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score

 

데이터 불러오기
#데이터 경로의 경우 사용자의 환경에 맞게 설정해야 합니다.
df_train = pd.read_csv("C:/Users/User/Downloads/train.csv", encoding = "UTF-8")
df_test = pd.read_csv("C:/Users/User/Downloads/test.csv", encoding = "UTF-8")

 

 

데이터의 특징 파악하기

데이터의 특징을 파악하기 위해 다음과 같은 코드를 작성했습니다.

df_train.info()

해당 코드를 통해 Column의 개수와 결측치, 변수 형태에 대해서 알 수 있습니다. 

그림 1. train 데이터 구조에 대해서 확인하기

마찬가지로 test데이터에 대한 정보 또한 위와 같은 방법으로 확인할 수 있습니다.

 

df_test.info()

그림 2. test 데이터 구조에 대해서 확인하기

우리가 불러온 데이터에 결측치들이 존재한다는 것을 확인할 수 있습니다.

 

또한 우리가 가지고 있는 자료는 int, float와 같은 수치로된 데이터와 object 즉, 문자로 된 데이터들이 같이 있음을 확인할 수 있습니다.

 

결측치에 대한 처리와 데이터들을 수치데이터로 통일하기 위해 데이터 전처리 과정을 진행하겠습니다.

 

데이터 전처리

 

먼저 결측치에 대한 처리를 진행하도록 하겠습니다. 결측치에 대한 처리는 나이와 승선요금의 경우 해당 열에서 가지고 있는 정보의 평균치를 적용하여 채워넣도록 하겠습니다.

 

승선지에 경우에는 해당 데이터에서 가장 적게 나온 값, 즉 최빈값으로 채워넣도록 하겠습니다.

 

df_train['Age'] = df_train["Age"].fillna(df_train['Age'].mean())
df_train['Fare'] = df_train["Fare"].fillna(df_train['Fare'].mean())
df_train['Embarked'] = df_train["Embarked"].fillna(df_train["Embarked"].mode().iloc[0])
df_test['Age'] = df_test["Age"].fillna(df_test['Age'].mean())
df_test['Fare'] = df_test["Fare"].fillna(df_test['Fare'].mean())
df_test['Embarked'] = df_test["Embarked"].fillna(df_test["Embarked"].mode().iloc[0])

결측치가 제대로 채워졌는지 확인해 보겠습니다.

그림 3. 데이터들의 결측치 처리 확인

Cabin 즉, 선실과 같은 경우에는 결과 예측에 영향을 주지 않기 때문에 학습 시 독립변수에서 배제하도록 하겠습니다.

 

다음은 데이터 수치화 작업을 진행하도록 하겠습니다.

 

성별의 경우 male/female 두가지 정보를 가지고 있으니 male = 0, female = 1로 치환하였고, 승선지의 경우 S = 1, C = 2, Q = 3으로 치환하도록 하겠습니다.

df_train['Sex'] = df_train['Sex'].map({'male':0, 'female':1})
df_train['Embarked'] = df_train['Embarked'].map({'S':0, 'C':1, 'Q':2})
df_test['Sex'] = df_test['Sex'].map({'male':0, 'female':1})
df_test['Embarked'] = df_test['Embarked'].map({'S':0, 'C':1, 'Q':2})

해당 코드를 통해 문자열을 숫자열로 치환할 수 있습니다.

그림 4. 문자열을 숫자열로 치환하기

 

우리가 가지고 있는 Pclass 정보는 1이 가장 높은등급이고 3이 가장 낮은 등급입니다. 따라서 숫자가 클수록 낮은 등급을 가지게 됩니다. 

 

또한 승선지의 경우에도 각 숫자가 가지는 정보가 높고 낮음이 중요하지 않습니다.

 

해당 문제를 해결하기 위해 우리는 해당 숫자마다의 index를 만들어 One-Hot Encoding을 하도록 하겠습니다. 

즉, 하나의 Pclass Column을 1 의 경우에는 [1, 0, 0], 2의 경우에는 [0, 1, 0], 3의 경우에는 [0, 0, 1]와 같이 세 개의 Column으로 만들어 보도록 하겠습니다. 

승선지의 경우에도 위와같은 처리를 하도록 하겠습니다.

 

#Train data의 One-hot Encoding
tr_pclass_dummies = pd.get_dummies(df_train['Pclass'], prefix='Pclass')
tr_embarked_dummies = pd.get_dummies(df_train['Embarked'], prefix='Embarked')
df_train = pd.concat([df_train, tr_pclass_dummies, tr_embarked_dummies], axis=1)
df_train = df_train.drop(['Pclass', 'Embarked'], axis=1)

#Test data의 One-hot Encoding
te_pclass_dummies = pd.get_dummies(df_test['Pclass'], prefix='Pclass')
te_embarked_dummies = pd.get_dummies(df_test['Embarked'], prefix='Embarked')
df_test = pd.concat([df_test, te_pclass_dummies, te_embarked_dummies], axis=1)
df_test = df_test.drop(['Pclass', 'Embarked'], axis=1)

위의 코드를 통해 데이터들을 변환하였습니다.

그림 5. 데이터 변환하기

SibSp의 값에 대해 알아보도록 하겠습니다.

 

형제 또는 배우자가 같이 탑승했을 경우 그 수가 클수록 생존율이 낮은 경향을 보였습니다.

 

따라서 4라는 기준점을 두고 3보다 작을 경우 1, 3이상의 경우에는 0의 값을 가지는 새로운 Column을 생성하였습니다.

 

high_sibsp_threshold = 3
#3를 기준으로 3보다 작을 경우 1, 3이상일 경우 0의 값을 가지는 새로운 Column 생성
df_train['High_SibSp'] = (df_train['SibSp'] < high_sibsp_threshold).astype(int)
df_test['High_SibSp'] = (df_test['SibSp'] < high_sibsp_threshold).astype(int)

 

데이터 전처리가 모두 끝났습니다.

 

이제 train, test 데이터를 독립변수와 종속변수(x,y)로 나누어서 학습을 진행해보도록 하겠습니다.

데이터 학습과 예측

우리는 각각 train, test데이터를 가지고 있기 때문에 train_test_split을 사용하지 않고 하나씩 지정해서 사용하도록 하겠습니다.

 

x_train = df_train.drop(['PassengerId','Survived', 'Name', 'SibSp', 'Cabin', 'Ticket'], axis = 1)
y_train = df_train['Survived']

train 데이터에서 위의 항복들을 제외한 값을 독립변수 즉, x_train으로 두고 생존여부를 종속변수 즉, y_train으로 두었습니다. 

그림 6. 학습 데이터의 독립변수와 종속변수 설정

 

위의 두개의 데이터를 통한 학습을 진행해보도록 하겠습니다.

svm_model = SVC()

svm_model.fit(x_train, y_train)

위의 코드를 통해 학습을 완료한 후, 데이터 예측을 해보도록 하겠습니다.

 

x_test = df_test.drop(['PassengerId', 'Name', 'SibSp', 'Cabin', 'Ticket'], axis = 1)

x_test 데이터는 test 데이터의 독립변수로 설정하였습니다. x_train 데이터와 마찬가지로 위의 컬럼들을 제거하였습니다.

 

그림 7. test 데이터의 종속변수 설정

이제 학습한 모델을 토대로 x_test의 생존자를 예측해 보도록 하겠습니다.

 

y_pred = svm_model.predict(x_test)

 

그림 8. SVM 모델을 통해 학습한 test데이터의 독립변수에 대한 종속변수 예측

우리가 학습한 모델로 test데이터의 독립변수에 대한 종속변수를 예측하였습니다.

 

위에서 따로 y_test라는 항목을 따로 두지 않았기 때문에 이번에는 Kaggle에 우리가 예측한 항목을 csv 파일로 저장하여  제출해서 점수를 확인해 보도록 하겠습니다. 

 

from pandas import DataFrame
predictions_df = pd.DataFrame(y_pred, columns=['Survived'])

predictions_df['PassengerId'] = df_test['PassengerId']

predictions_df = predictions_df[['PassengerId', 'Survived']]

predictions_df.to_csv("predicted_survived_with_passengerid.csv", index=False)

Kaggle에 제출할 데이터는 test데이터에 존재하는 PassengerId와 우리가 예측한 생존여부 Survived 두가지 항목을 Column으로 만들어 csv 파일로 저장하였습니다.

 

데이터 검증

먼저 타이타닉 생존자 예측 사이트에 들어가보겠습니다.(https://www.kaggle.com/competitions/titanic/overview)

 

Titanic - Machine Learning from Disaster | Kaggle

 

www.kaggle.com

 

해당 사이트에 접속하게 되면 Submit Predictions라는 버튼이 있는데 우리가 저장한 csv파일을 제출할 수 있습니다.

 

그림 9. csv 파일 제출하기

 

그림 9.와 같이 우리가 저장한 csv 파일을 제출하면 점수가 나타나게 됩니다.

그림 10. 제출한 데이터 점수 확인하기

점수는 66점으로 낮은 점수가 나왔습니다. 

 

생존여부(종속변수)에 영향을 미치는 종속변수들을 파악하여 데이터 전처리와 학습을 진행하면 점수가 더 높게 나올 것입니다.

 

마치며

하나의 데이터를 가지고도 여러가지 전처리 방법과 모델, 모델 HyperParameter에 따라서 점수가 차이가 나게 됩니다. 

 

어떤 모델과 전처리 과정을 적용하는가는 자신이 가지고 있는 데이터의 특성에 따라서 선택할 수 있습니다.

 

support_vector_machine.ipynb
0.10MB

 

댓글