인공지능

Tabular Data - 타이타닉 생존자 분류

별은_StarIs_Dev 2025. 2. 2. 23:59
반응형

 

활용데이터

titanic.xls
0.27MB
titanic_test30.xls
0.03MB
titanic_train.xls
0.28MB

 

 

목적

 - 머신러닝을 통해 타이타닉 생존자 예측을 해보자.

 

1. 데이터 불러오기 및 전처리

#pandas : 데이터프레임 형태로 데이터를 다루기 위해 사용
#numpy : 수치 연산을 지원
#pickle, joblib : 모델 저장 및 불러오기를 위해 사용

import pandas as pd
import numpy as np
import pickle
import joblib

train = pd.read_excel('./data_folder/titanic_train.xls')
test30 = pd.read_excel('./data_folder/titanic_test30.xls')

#필요없는 변수 제거
train_copy = train.drop(columns=['name','home.dest','boat','cabin','body','embarked'])

 - 이름, 탑승지, 보트번호 등 학습에 크게 도움이 되지 않는 변수 제거

 

2. 범주형 데이터 인코딩

#LabelEncoder : 텍스트 형태의 범주형 데이터를 숫자로 변환
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
train_copy['sex'] = le.fit_transform(train_copy['sex'])

 

3. 변수의 영향력 확인(탐색적 데이터 분석)

#범주형 변수와 생존률의 관계 - 카이제곱 검정
from scipy.stats import chi2_contingency
col_list = ['pclass', 'sex', 'sibsp', 'parch']
for i in col_list:
	cross_outcome = pd.crosstab(train_copy[i], train_copy['survived'])
    chi2_result = chi2_contingency(cross_outcome)
    print(f"{i}는 생존에 영향이 있다 : {chi2_result[1]}")

 

카이제곱 검정

 - 두 범주형 변수 간의 연관성이 통계적으로 유의미 한지 확인하는 방법

 - p-value를 리턴하게 하고  p-value가 0.05이하일 경우 생존률과의 관련성이 높다고 판단

 

#연속형 변수와 생존률과의 관계 - 분산분석(ANOVA)
train_filtered = train_copy.copy()
#먼저 숫자형으로 변환하고 결측치 제거
train_filtered['age'] = pd.to_numeric(train_filtered['age'], errors='coerce')
train_filtered['ticket'] = pd.to_numeric(train_filtered['ticket'], errors='coerce')
train_filtered['fare'] = pd.to_numeric(train_filtered['fare'], errors='coerce')
train_filtered = train_filtered.dropna(subset=['age', 'ticket', 'fare'])

 

 

 

pd.to_numeric : 문자열 형태의 데이터를 숫자로 바꿈

dropna : 결측값이 있는 행을 제거

 

#ANOVA분석
from scipy.stats import f_oneway
col_list = ['age', 'ticket', 'fare']
for i in col_list:
    data_list = []
    for survived in train_filtered['survived'].unique():
        data_list.append(train_filtered[train_filtered['survived'] == survived][i])
    
    f_statistics, p_value = f_oneway(*data_list)
    print(f"{i} {f_statistics}, {p_value}")

 - p-value를 리턴하게 하고  p-value가 0.05이하일 경우 생존률과의 관련성이 높다고 판단

age가 관련성이 낮아서 제

train_filtered = train_filtered.drop(columns=['age'])

 

 

4. 데이터 준비 - 특성과 타깃 분리 및 학습/테스트 데이터 분할

#학습/테스트 데이터 분할
#특성과 타깃 분리하기
x = train_filtered.drop(columns=['survived'])
y = train_filtered['survived']

 

특성(Features, x) : 생존 예측에 사용될 변수들

타깃(Target, y) : 예측ㅎ하고자 하는 값인 생존 여부

#데이터 분할
from sklearn.model_selection import train_test_split
train_x, test_x, train_y, test_y = train_test_split(x, y, test_size=0.3, random_state=2024)

train_test_split : 데이터를 학습/검증용 데이터로 나눈다, 여기서는 7:3으로 학습:테스트를 분할

 

 

5. 다양한 머신러닝 모델 학습 및 평가

 - 결정트리 : 데이터를 여러 기준을 통해 분할하여 결정 규칙을 만드는 방식

from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
model_DTC = DecisionTreeClassifier()
model_DTC.fit(train_x, train_y)
pred_DTC = model_DTC.predict(test_x)
acc_DTC = accuracy_score(test_y, pred_DTC)
print(acc_DTC)

 

 

 - 랜덤포레스트 : 여러 개의 결정 트리를 학습시킨 후, 각 트리의 결과를 종합해 최종예측, 과적합을 줄임

from sklearn.ensemble import RandomForestClassifier
model_RFC = RandomForestClassifier()
model_RFC.fit(train_x, train_y)
pred_RFC = model_RFC.predict(test_x)
acc_RFC = accuracy_score(test_y, pred_RFC)
print(acc_RFC)

 

 

 - XGBoost : 부스팅기법 중 하나로, 여러 약한 학습기를 순차적으로 학습시켜 오차를 보완하는 방식

from xgboost import XGBClassifier
model_XGC = XGBClassifier()
model_XGC.fit(train_x, train_y)
pred_XGC = model_XGC.predict(test_x)
acc_XGC = accuracy_score(test_y, pred_XGC)
print(acc_XGC)

 

 

- 딥러닝모델(DNN) : Keras의 Sequential 모델을 사용

from keras.models import Sequential
from keras.layers import Dense

model_DNN = Sequential()
model_DNN.add(Dense(6, activation='softmax'))
model_DNN.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
history = model_DNN.fit(train_x, train_y, epochs=30, verbose=1)
pred_DNN = model_DNN.predict(test_x)
acc_DNN = accuracy_score(test_y, np.argmax(pred_DNN, axis=1))
print(acc_DNN)

 

 

6. 모델 성능 비교 및 시각화

 - 바 차트로 네 모델의 성능을 확인하기

import matplotlib.pyplot as plt
lists = ['DTC', 'RFC', 'XGC', 'DNN']
values = [acc_DTC, acc_RFC, acc_XGC, acc_DNN]
plt.bar(lists, values)
plt.show()

 

 - 예제에서는 XGC가 가장 좋았음

 

7. 최종 모델 저장 및 새로운 데이터에 대한 예측

#최종모델 선택 및 저장
result_model = model_XGC
joblib.dump(result_model, 'result_model_XGC.pkl')

#테스트 데이터 전처리 및 평가
#학습데이터와 동일한 방식으로 테스트데이터도 전처리하여 모델에 맞게 변환
test30 = test30.drop(columns=['name','home.dest','boat','cabin','body','embarked'])
test30['sex'] = le.fit_transform(test30['sex'])
test30['age'] = pd.to_numeric(test30['age'], errors='coerce')
test30['ticket'] = pd.to_numeric(test30['ticket'], errors='coerce')
test30['fare'] = pd.to_numeric(test30['fare'], errors='coerce')
test30 = test30.dropna(subset=['age', 'ticket', 'fare'])
test30 = test30.drop(columns=['age'])

test_y = test30['survived']
test_x = test30.drop(columns=['survived'])

#모델 불러오기 및 예측
load_model = joblib.load('result_model_XGC.pkl')
predictions = load_model.predict(test_x)
accuracy = accuracy_score(test_y, predictions)
accuracy

 

#정답파일 만들기
result_pd = pd.DataFrame(test_x)
result_pd['Outcome'] = predictions
result_pd.to_csv('./result.csv', index=False)

 

8. 결론

 - 위의 과정을 살펴보면 다음과 같다.

1) 데이터 전처리

2) 탐색적 분석

3) 모델 학습

4) 모델 평가 및 선택

5) 모델 저장 및 재사용

 

9. 최종코드

import pandas as pd
import numpy as np
import pickle
import joblib

train = pd.read_excel('./data_folder/titanic_train.xls')
test30 = pd.read_excel('./data_folder/titanic_test30.xls')

#필요없는 변수 제거
train_copy = train.drop(columns=['name','home.dest','boat','cabin','body','embarked'])

import pandas as pd
import numpy as np
import pickle
import joblib

train = pd.read_excel('./data_folder/titanic_train.xls')
test30 = pd.read_excel('./data_folder/titanic_test30.xls')

#필요없는 변수 제거
train_copy = train.drop(columns=['name','home.dest','boat','cabin','body','embarked'])

from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
train_copy['sex'] = le.fit_transform(train_copy['sex'])

from scipy.stats import chi2_contingency
col_list = ['pclass', 'sex', 'sibsp', 'parch']
for i in col_list:
    cross_outcome = pd.crosstab(train_copy[i], train_copy['survived'])
    chi2_result = chi2_contingency(cross_outcome)
    print(f"{i}는 생존에 영향이 있다 : {chi2_result[1]}")

#연속형 변수와 생존률과의 관계 - 분산분석(ANOVA)
train_filtered = train_copy.copy()
#먼저 숫자형으로 변환하고 결측치 제거
train_filtered['age'] = pd.to_numeric(train_filtered['age'], errors='coerce')
train_filtered['ticket'] = pd.to_numeric(train_filtered['ticket'], errors='coerce')
train_filtered['fare'] = pd.to_numeric(train_filtered['fare'], errors='coerce')
train_filtered = train_filtered.dropna(subset=['age', 'ticket', 'fare'])

#ANOVA분석
from scipy.stats import f_oneway
col_list = ['age', 'ticket', 'fare']
for i in col_list:
    data_list = []
    for survived in train_filtered['survived'].unique():
        data_list.append(train_filtered[train_filtered['survived'] == survived][i])
    
    f_statistics, p_value = f_oneway(*data_list)
    print(f"{i} {f_statistics}, {p_value}")

train_filtered = train_filtered.drop(columns=['age'])

#학습/테스트 데이터 분할
#특성과 타깃 분리하기
x = train_filtered.drop(columns=['survived'])
y = train_filtered['survived']

#데이터 분할
from sklearn.model_selection import train_test_split
train_x, test_x, train_y, test_y = train_test_split(x, y, test_size=0.3, random_state=2024)

from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
model_DTC = DecisionTreeClassifier()
model_DTC.fit(train_x, train_y)
pred_DTC = model_DTC.predict(test_x)
acc_DTC = accuracy_score(test_y, pred_DTC)
print(acc_DTC)

from sklearn.ensemble import RandomForestClassifier
model_RFC = RandomForestClassifier()
model_RFC.fit(train_x, train_y)
pred_RFC = model_RFC.predict(test_x)
acc_RFC = accuracy_score(test_y, pred_RFC)
print(acc_RFC)

from xgboost import XGBClassifier
model_XGC = XGBClassifier()
model_XGC.fit(train_x, train_y)
pred_XGC = model_XGC.predict(test_x)
acc_XGC = accuracy_score(test_y, pred_XGC)
print(acc_XGC)

from keras.models import Sequential
from keras.layers import Dense

model_DNN = Sequential()
model_DNN.add(Dense(6, activation='softmax'))
model_DNN.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
history = model_DNN.fit(train_x, train_y, epochs=30, verbose=1)
pred_DNN = model_DNN.predict(test_x)
acc_DNN = accuracy_score(test_y, np.argmax(pred_DNN, axis=1))
print(acc_DNN)

import matplotlib.pyplot as plt
lists = ['DTC', 'RFC', 'XGC', 'DNN']
values = [acc_DTC, acc_RFC, acc_XGC, acc_DNN]
plt.bar(lists, values)
plt.show()

#최종모델 선택 및 저장
result_model = model_XGC
joblib.dump(result_model, 'result_model_XGC.pkl')

#테스트 데이터 전처리 및 평가
#학습데이터와 동일한 방식으로 테스트데이터도 전처리하여 모델에 맞게 변환
test30 = test30.drop(columns=['name','home.dest','boat','cabin','body','embarked'])
test30['sex'] = le.fit_transform(test30['sex'])
test30['age'] = pd.to_numeric(test30['age'], errors='coerce')
test30['ticket'] = pd.to_numeric(test30['ticket'], errors='coerce')
test30['fare'] = pd.to_numeric(test30['fare'], errors='coerce')
test30 = test30.dropna(subset=['age', 'ticket', 'fare'])
test30 = test30.drop(columns=['age'])

test_y = test30['survived']
test_x = test30.drop(columns=['survived'])

#모델 불러오기 및 예측
load_model = joblib.load('result_model_XGC.pkl')
predictions = load_model.predict(test_x)
accuracy = accuracy_score(test_y, predictions)
accuracy


#정답파일 만들기
result_pd = pd.DataFrame(test_x)
result_pd['Outcome'] = predictions
result_pd.to_csv('./result.csv', index=False)
반응형