In [4]:
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import StandardScaler

# 1. 시각화 설정 (너비 100%를 위해 figsize를 크게 설정)
plt.style.use('seaborn-v0_8')
plt.rcParams['font.family'] = 'D2Coding'
plt.rcParams['axes.unicode_minus'] = False

# 데이터 로드
df = sns.load_dataset('titanic')

# ---------------------------------------------------------
# [시각화 1-4] 전처리 공정 대시보드 (20 x 12 대형 사이즈)
# ---------------------------------------------------------
fig, axes = plt.subplots(2, 2, figsize=(20, 12)) # 너비를 20으로 설정하여 100% 효과
fig.suptitle('머신러닝 전처리 및 특성 공학 시각화', fontsize=22, fontweight='bold')

# (1) 결측치 현황
sns.heatmap(df.isnull(), yticklabels=False, cbar=False, cmap='viridis', ax=axes[0, 0])
axes[0, 0].set_title("1. 데이터 결측치 현황 (노란색이 빈 값)", fontsize=15)

# 전처리 수행
df['age'] = df['age'].fillna(df['age'].median())
df['embarked'] = df['embarked'].fillna('S')
df['fare'] = df['fare'].fillna(df['fare'].median())

# (2) 특성 공학: 가족 수 변수 생성
df['FamilySize'] = df['sibsp'] + df['parch'] + 1
# 경고 해결: x와 hue를 동일하게 설정하고 legend=False 추가
sns.barplot(x='FamilySize', y='survived', hue='FamilySize', data=df, 
            palette='Blues', ax=axes[0, 1], legend=False)
axes[0, 1].set_title("2. 특성 공학: 가족 수에 따른 생존율", fontsize=15)

# (3) 상관관계 분석
df['sex_num'] = df['sex'].map({'male': 0, 'female': 1})
df['embarked_num'] = df['embarked'].map({'S': 0, 'C': 1, 'Q': 2})
corr_features = ['survived', 'pclass', 'sex_num', 'age', 'fare', 'embarked_num', 'FamilySize']
sns.heatmap(df[corr_features].corr(), annot=True, fmt=".2f", cmap='coolwarm', ax=axes[1, 0])
axes[1, 0].set_title("3. 특성 공학 후 변수 간 상관계수", fontsize=15)

# (4) 스케일링 전후 비교
scaler = StandardScaler()
fare_scaled = scaler.fit_transform(df[['fare']])
sns.kdeplot(df['fare'], label='원본 요금', ax=axes[1, 1], color='red', fill=True, alpha=0.3)
sns.kdeplot(fare_scaled.flatten(), label='스케일링 후 요금', ax=axes[1, 1], color='blue', fill=True, alpha=0.3)
axes[1, 1].set_title("4. 데이터 스케일링: 단위 표준화 비교", fontsize=15)
axes[1, 1].legend()

plt.tight_layout(rect=[0, 0.03, 1, 0.95])
plt.show()

# ---------------------------------------------------------
# [시각화 5] 최종 모델 변수 중요도 (너비 20 x 6 와이드 사이즈)
# ---------------------------------------------------------
features = ['pclass', 'sex_num', 'age', 'fare', 'embarked_num', 'FamilySize']
X = df[features]
y = df['survived']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)

plt.figure(figsize=(20, 6)) # 하단 그래프도 너비 100%
importances = pd.Series(model.feature_importances_, index=features).sort_values(ascending=False)

# 경고 해결: y를 hue에 할당하고 legend=False 설정
sns.barplot(x=importances, y=importances.index, hue=importances.index, 
            palette='magma', legend=False)

plt.title("랜덤 포레스트가 판단한 핵심 생존 요소 (Feature Importance)", fontsize=18)
plt.xlabel("중요도 수치", fontsize=12)
plt.ylabel("데이터 특징", fontsize=12)
plt.grid(axis='x', linestyle='--', alpha=0.7)
plt.show()
No description has been provided for this image
No description has been provided for this image