# 5. 실전 데이터 분석: 타이타닉 데이터셋

## 📚 학습 목표
- 실제 데이터셋을 활용한 데이터 분석 과정 이해
- 데이터 로딩과 탐색적 데이터 분석(EDA) 수행
- 결측치 처리와 데이터 전처리 기법 습득
- 통계적 분석과 시각화를 통한 인사이트 도출

## 🔍 문제 설명

타이타닉 데이터셋은 데이터 분석과 머신러닝 학습에서 가장 유명한 데이터셋 중 하나입니다. 1912년 타이타닉호 침몰 사고에서 승객들의 생존 여부와 관련된 다양한 정보를 포함하고 있어, 데이터 분석의 전 과정을 연습하기에 적합합니다.

### 실전 활용 사례
- **데이터 분석**: 실제 비즈니스 데이터 분석 과정 학습
- **머신러닝**: 분류 모델 개발을 위한 데이터 전처리
- **통계 분석**: 요인별 생존율 분석
- **시각화**: 데이터 인사이트를 시각적으로 표현

## 📝 문제

### 문제 5-1: 데이터 로딩과 탐색
1. 타이타닉 데이터셋을 로드하고 기본 정보를 확인하세요.
2. 데이터의 형태, 컬럼명, 데이터 타입을 파악하세요.
3. 결측치 현황을 확인하고 분석하세요.

### 문제 5-2: 데이터 전처리
4. 결측치를 적절한 방법으로 처리하세요.
5. 범주형 변수를 수치형으로 변환하세요.
6. 새로운 특성을 생성하세요.

### 문제 5-3: 탐색적 데이터 분석
7. 성별에 따른 생존율을 분석하세요.
8. 좌석 등급에 따른 생존율을 분석하세요.
9. 나이와 생존율의 관계를 분석하세요.

### 문제 5-4: 고급 분석
10. 여러 변수를 조합한 생존율 분석을 수행하세요.
11. 시각화를 통해 인사이트를 도출하세요.
12. 통계적 검정을 통해 유의성을 확인하세요.

## 💡 해답 및 설명

### 해답 5-1: 데이터 로딩과 탐색

```python
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats

# 한글 폰트 설정
plt.rcParams['font.family'] = 'DejaVu Sans'
plt.rcParams['axes.unicode_minus'] = False

# 1. 타이타닉 데이터셋 로드
url = 'https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv'
titanic = pd.read_csv(url)

print("데이터셋 기본 정보:")
print(f"데이터 형태: {titanic.shape}")
print(f"컬럼명: {list(titanic.columns)}")
print(f"인덱스: {titanic.index}")

# 2. 데이터 타입과 기본 정보 확인
print("\n데이터 타입:")
print(titanic.dtypes)

print("\n기본 통계 정보:")
print(titanic.describe())

print("\n데이터 미리보기:")
print(titanic.head())

# 3. 결측치 현황 확인
print("\n결측치 현황:")
missing_data = titanic.isnull().sum()
missing_percent = (missing_data / len(titanic)) * 100
missing_info = pd.DataFrame({
    '결측치 개수': missing_data,
    '결측치 비율(%)': missing_percent
})
print(missing_info[missing_info['결측치 개수'] > 0])

# 결측치 시각화
plt.figure(figsize=(10, 6))
missing_info[missing_info['결측치 개수'] > 0]['결측치 비율(%)'].plot(kind='bar')
plt.title('컬럼별 결측치 비율')
plt.ylabel('결측치 비율 (%)')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
```

### 해답 5-2: 데이터 전처리

```python
# 4. 결측치 처리
print("결측치 처리:")

# Age 결측치 처리 (평균값으로 대체)
age_mean = titanic['Age'].mean()
titanic['Age'].fillna(age_mean, inplace=True)
print(f"Age 결측치를 평균값({age_mean:.1f})으로 대체")

# Cabin 결측치 처리 (결측치가 많으므로 'Unknown'으로 대체)
titanic['Cabin'].fillna('Unknown', inplace=True)
print("Cabin 결측치를 'Unknown'으로 대체")

# Embarked 결측치 처리 (최빈값으로 대체)
embarked_mode = titanic['Embarked'].mode()[0]
titanic['Embarked'].fillna(embarked_mode, inplace=True)
print(f"Embarked 결측치를 최빈값({embarked_mode})으로 대체")

# 결측치 처리 후 확인
print("\n결측치 처리 후 현황:")
print(titanic.isnull().sum())

# 5. 범주형 변수 수치화
print("\n범주형 변수 수치화:")

# Sex 변수 수치화
titanic['Sex_numeric'] = titanic['Sex'].map({'male': 0, 'female': 1})
print("Sex 변수 수치화 완료")

# Embarked 변수 수치화
embarked_mapping = {'S': 0, 'C': 1, 'Q': 2}
titanic['Embarked_numeric'] = titanic['Embarked'].map(embarked_mapping)
print("Embarked 변수 수치화 완료")

# 6. 새로운 특성 생성
print("\n새로운 특성 생성:")

# 가족 크기 (SibSp + Parch + 1)
titanic['FamilySize'] = titanic['SibSp'] + titanic['Parch'] + 1
print("FamilySize 특성 생성 완료")

# 혼자 여행하는지 여부
titanic['IsAlone'] = (titanic['FamilySize'] == 1).astype(int)
print("IsAlone 특성 생성 완료")

# 나이 그룹
titanic['AgeGroup'] = pd.cut(titanic['Age'], 
                            bins=[0, 12, 18, 35, 60, 100], 
                            labels=['Child', 'Teenager', 'Young Adult', 'Adult', 'Senior'])
print("AgeGroup 특성 생성 완료")

# 요금 그룹
titanic['FareGroup'] = pd.qcut(titanic['Fare'], 
                              q=4, 
                              labels=['Low', 'Medium', 'High', 'Very High'])
print("FareGroup 특성 생성 완료")

print("\n새로 생성된 특성들:")
print(titanic[['FamilySize', 'IsAlone', 'AgeGroup', 'FareGroup']].head())
```

### 해답 5-3: 탐색적 데이터 분석

```python
# 7. 성별에 따른 생존율 분석
print("성별에 따른 생존율 분석:")
gender_survival = titanic.groupby('Sex')['Survived'].agg(['count', 'sum', 'mean'])
gender_survival.columns = ['전체 인원', '생존자 수', '생존율']
print(gender_survival)

# 시각화
plt.figure(figsize=(12, 5))

plt.subplot(1, 2, 1)
sns.countplot(data=titanic, x='Sex', hue='Survived')
plt.title('성별 생존자 수')
plt.ylabel('인원 수')

plt.subplot(1, 2, 2)
sns.barplot(data=titanic, x='Sex', y='Survived')
plt.title('성별 생존율')
plt.ylabel('생존율')

plt.tight_layout()
plt.show()

# 8. 좌석 등급에 따른 생존율 분석
print("\n좌석 등급에 따른 생존율 분석:")
class_survival = titanic.groupby('Pclass')['Survived'].agg(['count', 'sum', 'mean'])
class_survival.columns = ['전체 인원', '생존자 수', '생존율']
print(class_survival)

# 시각화
plt.figure(figsize=(12, 5))

plt.subplot(1, 2, 1)
sns.countplot(data=titanic, x='Pclass', hue='Survived')
plt.title('좌석 등급별 생존자 수')
plt.ylabel('인원 수')

plt.subplot(1, 2, 2)
sns.barplot(data=titanic, x='Pclass', y='Survived')
plt.title('좌석 등급별 생존율')
plt.ylabel('생존율')

plt.tight_layout()
plt.show()

# 9. 나이와 생존율의 관계 분석
print("\n나이와 생존율의 관계 분석:")

# 나이 그룹별 생존율
age_survival = titanic.groupby('AgeGroup')['Survived'].agg(['count', 'sum', 'mean'])
age_survival.columns = ['전체 인원', '생존자 수', '생존율']
print(age_survival)

# 나이 분포와 생존율
plt.figure(figsize=(15, 5))

plt.subplot(1, 3, 1)
sns.histplot(data=titanic, x='Age', hue='Survived', multiple='stack')
plt.title('나이 분포와 생존 여부')

plt.subplot(1, 3, 2)
sns.boxplot(data=titanic, x='Survived', y='Age')
plt.title('생존 여부별 나이 분포')

plt.subplot(1, 3, 3)
sns.barplot(data=titanic, x='AgeGroup', y='Survived')
plt.title('나이 그룹별 생존율')
plt.xticks(rotation=45)

plt.tight_layout()
plt.show()
```

### 해답 5-4: 고급 분석

```python
# 10. 여러 변수를 조합한 생존율 분석
print("여러 변수를 조합한 생존율 분석:")

# 성별과 좌석 등급 조합
gender_class_survival = titanic.groupby(['Sex', 'Pclass'])['Survived'].mean().unstack()
print("\n성별과 좌석 등급별 생존율:")
print(gender_class_survival)

# 시각화
plt.figure(figsize=(10, 6))
sns.heatmap(gender_class_survival, annot=True, fmt='.3f', cmap='YlOrRd')
plt.title('성별과 좌석 등급별 생존율 히트맵')
plt.tight_layout()
plt.show()

# 가족 크기별 생존율
family_survival = titanic.groupby('FamilySize')['Survived'].agg(['count', 'mean'])
family_survival.columns = ['인원 수', '생존율']
print("\n가족 크기별 생존율:")
print(family_survival)

# 11. 종합 시각화
plt.figure(figsize=(15, 10))

# 생존율 분포
plt.subplot(2, 3, 1)
titanic['Survived'].value_counts().plot(kind='pie', autopct='%1.1f%%')
plt.title('전체 생존율')

# 성별 생존율
plt.subplot(2, 3, 2)
sns.barplot(data=titanic, x='Sex', y='Survived')
plt.title('성별 생존율')

# 좌석 등급별 생존율
plt.subplot(2, 3, 3)
sns.barplot(data=titanic, x='Pclass', y='Survived')
plt.title('좌석 등급별 생존율')

# 나이 그룹별 생존율
plt.subplot(2, 3, 4)
sns.barplot(data=titanic, x='AgeGroup', y='Survived')
plt.title('나이 그룹별 생존율')
plt.xticks(rotation=45)

# 가족 크기별 생존율
plt.subplot(2, 3, 5)
sns.barplot(data=titanic, x='FamilySize', y='Survived')
plt.title('가족 크기별 생존율')

# 요금 그룹별 생존율
plt.subplot(2, 3, 6)
sns.barplot(data=titanic, x='FareGroup', y='Survived')
plt.title('요금 그룹별 생존율')
plt.xticks(rotation=45)

plt.tight_layout()
plt.show()

# 12. 통계적 검정
print("\n통계적 검정:")

# 성별과 생존율의 독립성 검정 (카이제곱 검정)
from scipy.stats import chi2_contingency
gender_survival_table = pd.crosstab(titanic['Sex'], titanic['Survived'])
chi2, p_value, dof, expected = chi2_contingency(gender_survival_table)
print(f"성별과 생존율 독립성 검정:")
print(f"카이제곱 통계량: {chi2:.4f}")
print(f"p-value: {p_value:.4f}")
print(f"결론: {'독립이 아님' if p_value < 0.05 else '독립'}")

# 좌석 등급과 생존율의 독립성 검정
class_survival_table = pd.crosstab(titanic['Pclass'], titanic['Survived'])
chi2, p_value, dof, expected = chi2_contingency(class_survival_table)
print(f"\n좌석 등급과 생존율 독립성 검정:")
print(f"카이제곱 통계량: {chi2:.4f}")
print(f"p-value: {p_value:.4f}")
print(f"결론: {'독립이 아님' if p_value < 0.05 else '독립'}")

# 나이와 생존율의 상관관계 (점이연상관계)
age_survived_corr = titanic['Age'].corr(titanic['Survived'])
print(f"\n나이와 생존율의 상관계수: {age_survived_corr:.4f}")
```

## 🔧 주요 분석 기법

### 데이터 탐색
- `df.info()`: 데이터 기본 정보
- `df.describe()`: 수치형 데이터 통계
- `df.isnull().sum()`: 결측치 확인
- `df.value_counts()`: 범주형 데이터 빈도

### 데이터 전처리
- `df.fillna()`: 결측치 채우기
- `df.map()`: 범주형 변수 수치화
- `pd.cut()`: 연속형 변수 구간화
- `pd.qcut()`: 분위수 기반 구간화

### 그룹화와 집계
- `df.groupby()`: 그룹별 분석
- `df.agg()`: 다양한 집계 함수 적용
- `df.unstack()`: 피벗 테이블 형태로 변환

### 시각화
- `sns.countplot()`: 범주형 데이터 빈도
- `sns.barplot()`: 평균값 비교
- `sns.heatmap()`: 상관관계 히트맵
- `sns.boxplot()`: 분포 비교

### 통계적 검정
- `chi2_contingency()`: 카이제곱 독립성 검정
- `corr()`: 상관계수 계산
- `ttest_ind()`: t-검정

## 📊 추가 연습문제

### 연습문제 1: 추가 특성 생성
```python
# 다음 특성들을 추가로 생성해보세요:
# 1. 승객의 호칭(Mr, Mrs, Miss, Dr 등)을 추출하여 새로운 컬럼을 만드세요.
# 2. 승선 항구별 생존율을 분석하세요.
# 3. 요금과 생존율의 관계를 분석하세요.
```

### 연습문제 2: 고급 시각화
```python
# 다음 시각화를 수행해보세요:
# 1. 나이, 요금, 가족 크기를 모두 고려한 3D 산점도를 그려보세요.
# 2. 생존자와 사망자의 나이 분포를 커널 밀도 추정으로 비교해보세요.
# 3. 좌석 등급별 요금 분포를 박스플롯으로 비교해보세요.
```

### 연습문제 3: 머신러닝 준비
```python
# 다음 작업을 수행해보세요:
# 1. 생존 예측을 위한 특성 선택을 수행하세요.
# 2. 특성 간 상관관계를 분석하세요.
# 3. 데이터를 훈련/테스트 세트로 분할하세요.
```

## ⚠️ 주의사항 및 팁

1. **결측치 처리**: 데이터의 특성에 따라 적절한 방법을 선택해야 합니다.
2. **범주형 변수**: 수치화 시 순서가 있는지 없는지를 고려해야 합니다.
3. **새로운 특성**: 도메인 지식을 활용하여 의미 있는 특성을 생성해야 합니다.
4. **시각화**: 데이터의 특성에 맞는 적절한 시각화 방법을 선택해야 합니다.
5. **통계적 검정**: 검정의 가정을 확인하고 적절한 검정 방법을 선택해야 합니다.

## 🎯 실전 활용 예제

### 예제 1: 고객 이탈 예측
```python
# 고객 이탈 데이터 분석 예제
# 타이타닉 데이터셋의 분석 방법을 고객 이탈 예측에 적용
```

### 예제 2: 신용카드 사기 탐지
```python
# 신용카드 사기 탐지 데이터 분석 예제
# 불균형 데이터셋에서의 분석 방법
```

### 예제 3: 주식 가격 예측
```python
# 주식 가격 예측을 위한 데이터 분석 예제
# 시계열 데이터의 특성 분석
```

## 📚 다음 단계

이제 실제 데이터셋을 활용한 데이터 분석을 익혔습니다. 다음 단계에서는:
- 더 복잡한 데이터 전처리 기법
- 고급 시각화 방법
- 머신러닝 모델 개발
- 모델 성능 평가

을 학습하게 됩니다.

---

**참고 자료:**
- [Kaggle 타이타닉 튜토리얼](https://www.kaggle.com/c/titanic)
- [Pandas 공식 문서](https://pandas.pydata.org/docs/)
- [Seaborn 시각화 가이드](https://seaborn.pydata.org/) 