캐글의 [Titanic Dataset] 을 활용하여 타이타닉 생존자를 예측하는 모델을 만들어봤다.
https://www.kaggle.com/datasets/yasserh/titanic-dataset
Titanic Dataset
Titanic Survival Prediction Dataset
www.kaggle.com
데이터 로드 및 확인
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore', category=UserWarning)
df = pd.read_csv("./data/titanic_dataset.csv")
df

df.info()

df.describe()

# Name 데이터 확인 - 불필요한 컬럼이라 판단되면 삭제
df["Name"]

# Ticket 데이터 확인 - 불필요한 데이터라 판단되면 삭제
df["Ticket"].value_counts()

# Cabin 데이터 확인 - 불필요한 컬럼이라 판단되면 삭제
df["Cabin"].value_counts()

# Embarked 데이터 확인 - 불필요한 데이터라 판단되면 삭제
df["Embarked"].value_counts()

# SibSp 데이터 확인 - 불필요한 데이터라 확인되면 삭제
df["SibSp"].value_counts()

# Parch 데이터 확인 - 불필요한 데이터라 판단되면 삭제
df["Parch"].value_counts()

데이터 시각화
cat_cols = ["Pclass", "Sex", "SibSp", "Parch", "Embarked", "Survived"]
num_cols = ["Age", "Fare"]
# 범주형 데이터 시각화
figs, axes = plt.subplots(2, 3, figsize=(12, 8))
axes_flat = axes.flatten()
for i, col in enumerate(cat_cols):
ax = axes_flat[i]
data_count = df[col].value_counts().sort_index()
ax.bar(data_count.index.astype(str), data_count.values, color="C"+str(i), alpha=0.7, edgecolor="black")
ax.set_title(f"Bar Chart: {col}")
ax.set_xlabel("Categories")
ax.set_ylabel("Count")
ax.tick_params(axis="x", rotation=45) # x축 글자가 겹치므로 45도 회전
plt.tight_layout()
plt.show()

# 수치형 데이터 시각화
fig, axes = plt.subplots(1, 2, figsize=(13, 5))
for i, col_name in enumerate(num_cols):
ax = axes[i]
# 히스토그램 그리기
ax.hist(df[col_name], bins=10, color="C"+str(i), alpha=0.7, edgecolor="black")
# 개별 차트 제목 및 라벨 설정
ax.set_title(f"Histogram: {col_name}")
ax.set_xlabel("Values")
ax.set_ylabel("Frequency")
# 격자선 추가
ax.grid(axis="y", alpha=0.5)
plt.tight_layout()
plt.show()

전처리 전략
1. PassengerId, Name, Ticket 컬럼은 삭제
2. Cabin 컬럼은 null 데이터가 많아서 삭제 하기로 결정
3. Age 컬럼은 null 데이터를 특정값으로 대체하기 어려워서 null 값 삭제
4. Embarked 컬럼은 null 데이터를 특정값으로 대체하기 어려워서 null 값 삭제
5. 범주형 컬럼(Pclass, Sex, SibSp, Parch, Embarked) 은 모두 원핫 인코딩
6. Age 는 StandardScaler로 스케일링
7. Fare 는 RobustScaler로 스케일링
df_prep = df.copy()
df_prep = df_prep.drop(labels=["PassengerId", "Name", "Ticket", "Cabin"], axis=1)
df_prep = df_prep.dropna()
df_prep = df_prep.reset_index(drop=True)
df_prep.info()

from sklearn.preprocessing import OneHotEncoder
# Company, TypeName, OpSys 는 원핫인코딩
encoder = OneHotEncoder(sparse_output=False)
encoded_data = encoder.fit_transform(df_prep[["Pclass", "Sex", "SibSp", "Parch", "Embarked"]])
# 인코딩 된 데이터를 데이터프레임으로 변환
encoded_df = pd.DataFrame(
encoded_data, columns=encoder.get_feature_names_out(["Pclass", "Sex", "SibSp", "Parch", "Embarked"])
)
# 기존 데이터셋에서 인코딩한 컬럼을 제거하고 인코딩된 데이터를 붙이기
df_encoded = df_prep.drop(columns=["Pclass", "Sex", "SibSp", "Parch", "Embarked"])
df_encoded = pd.concat([df_encoded, encoded_df], axis=1)
from sklearn.model_selection import train_test_split
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, RobustScaler
robust_col = ["Fare"]
standard_col = ["Age"]
X = df_encoded.drop(labels=["Survived"], axis=1)
y = df_encoded["Survived"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)
# 전처리 파이프라인 구성
preprocessor = ColumnTransformer(
transformers = [
("robust", RobustScaler(), robust_col),
("std", StandardScaler(), standard_col)
],
remainder="passthrough"
)
모델 학습 및 평가 - XGBoost
from xgboost import XGBClassifier
from imblearn.pipeline import Pipeline as ImbPipeline
from imblearn.over_sampling import SMOTE
from sklearn.model_selection import GridSearchCV
# XGBoost 전용 파이프라인 구성
pipeline_xgb = ImbPipeline(
[
("preprocessor", preprocessor),
("classifier", XGBClassifier(random_state=42, eval_metric="logloss"))
]
)
# XGBoost 하이퍼파라미터 그리드 설정
param_grid_xgb = {
"classifier__n_estimators": [50, 100, 150, 200],
"classifier__max_depth": [3, 5, 7, 9],
"classifier__learning_rate": [0.01, 0.05, 0.1, 0.2]
}
# GridSearchCV 설정
grid_search_xgb = GridSearchCV(
estimator=pipeline_xgb,
param_grid=param_grid_xgb,
cv=5,
scoring="accuracy",
n_jobs=1,
verbose=2
)
# 원본 데이터로 학습 시작
print("===== XGBoost GridSearchCV 학습 시작 =====")
grid_search_xgb.fit(X_train, y_train)
print("최적의 파라미터: ", grid_search_xgb.best_params_)
# 최적 모델 추출 및 예측
best_xgb_model = grid_search_xgb.best_estimator_
from sklearn.metrics import classification_report
from sklearn.metrics import accuracy_score
y_pred_xgb = best_xgb_model.predict(X_test)
# 성능 지표
print(classification_report(y_test, y_pred_xgb, target_names=["Not[0]", "Survived(1)"]))
print(f"Accuracy Score: {accuracy_score(y_test, y_pred_xgb)}")

모델 학습 및 평가 - RandomForestClassifier
from sklearn.ensemble import RandomForestClassifier
from imblearn.pipeline import Pipeline as ImbPipeline
from imblearn.over_sampling import SMOTE
from sklearn.model_selection import GridSearchCV
# RandomForestClassifier 전용 파이프라인 구성
pipeline_rf = ImbPipeline(
[
("preprocessor", preprocessor),
("classifier", RandomForestClassifier(random_state=42))
]
)
# RandomForestClassifier 하이퍼파라미터 그리드 설정
param_grid_rf = {
"classifier__n_estimators": [50, 100, 200, 300],
"classifier__max_depth": [10, 20, None],
"classifier__min_samples_split": [2, 5, 7, 10],
"classifier__min_samples_leaf": [1, 2, 4, 8]
}
# GridSearchCV 설정
grid_search_rf = GridSearchCV(
estimator=pipeline_rf,
param_grid=param_grid_rf,
cv=5,
scoring="recall",
n_jobs=1,
verbose=2
)
# 원본 데이터로 학습 시작
print("===== RandomForestClassifier GridSearchCV 학습 시작 =====")
grid_search_rf.fit(X_train, y_train)
print("최적의 파라미터: ", grid_search_rf.best_params_)
# 최적 모델 추출 및 예측
best_rf_model = grid_search_rf.best_estimator_
from sklearn.metrics import classification_report
from sklearn.metrics import accuracy_score
# 테스트 데이터로 예측 수행
y_pred_rf = best_rf_model.predict(X_test)
# 성능 지표
print(classification_report(y_test, y_pred_rf, target_names=["Not[0]", "Survived(1)"]))
print(f"Accuracy Score: {accuracy_score(y_test, y_pred_rf)}")

모델 학습 및 평가 - LGBMClassifier
from lightgbm import LGBMClassifier
# LightGBM 전용 파이프라인 구성
pipeline_lgbm = ImbPipeline([
('preprocessor', preprocessor),
('classifier', LGBMClassifier(random_state=42, verbose=-1)) # 로그 출력 최소화
])
# LightGBM 하이퍼파라미터 그리드 설정
param_grid_lgbm = {
'classifier__n_estimators': [100, 200, 300],
'classifier__max_depth': [3, 5, 7, -1], # -1은 제한 없음
'classifier__num_leaves': [15, 31, 63],
'classifier__learning_rate': [0.01, 0.05, 0.1]
}
# GridSearchCV 설정
grid_search_lgbm = GridSearchCV(
estimator=pipeline_lgbm,
param_grid=param_grid_lgbm,
cv=5,
scoring="recall",
n_jobs=1,
verbose=2
)
# 원본 데이터로 학습 시작
print("===== LightGBM GridSearchCV 시작 =====")
grid_search_lgbm.fit(X_train, y_train)
print("최적의 파라미터: ", grid_search_lgbm.best_params_)
# 최적 모델 추출 및 예측
best_lgbm_model = grid_search_lgbm.best_estimator_
from sklearn.metrics import classification_report
from sklearn.metrics import accuracy_score
# 테스트 데이터로 예측 수행
y_pred_lgbm = best_lgbm_model.predict(X_test)
# 성능 지표
print(classification_report(y_test, y_pred_lgbm, target_names=["Not[0]", "Survived(1)"]))
print(f"Accuracy Score: {accuracy_score(y_test, y_pred_lgbm)}")

'AICE' 카테고리의 다른 글
| [AICE PROFESSIONAL 준비] 상품명으로 식품 카테고리 분류 (0) | 2026.06.19 |
|---|---|
| [AICE PROFESSIONAL 준비] 아보카도 가격 예측 (0) | 2026.06.18 |
| [AICE PROFESSIONAL 준비] 랩탑 가격 예측 (0) | 2026.06.17 |
| [AICE PROFESSIONAL 준비] 토마토 질병 분류 (0) | 2026.06.16 |
| [AICE PROFESSIONAL 준비] 한국어 혐오 댓글 (0) | 2026.06.16 |