{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "b56553cc",
   "metadata": {},
   "source": [
    "# Part 6: 머신러닝 모델링과 평가\n",
    "\n",
    "**⬅️ 이전 시간: [Part 5.6: 머신러닝/딥러닝을 위한 미적분](../05.6_calculus_for_ml/part_5.6_calculus_for_ml.md)**\n",
    "**➡️ 다음 시간: [Part 7: 딥러닝 기초와 PyTorch](../07_deep_learning/part_7_deep_learning.md)**\n",
    "\n",
    "---\n",
    "\n",
    "## 🗺️ 학습 로드맵: 이제 실제 AI 모델을 만들어봅시다!\n",
    "\n",
    "### 🎯 이번 파트의 목적\n",
    "이제 선형대수와 미적분의 기초를 다졌으니, **실제 머신러닝 모델을 만들어보겠습니다!** 이전 파트들의 모든 지식이 하나로 합쳐지는 순간입니다.\n",
    "\n",
    "### 🔗 이전 파트들의 지식이 어떻게 활용되는지\n",
    "- **Part 5 (AI Core Libraries)**: NumPy, Pandas로 데이터를 다루고 전처리\n",
    "- **Part 5.5 (Linear Algebra)**: 벡터와 행렬로 데이터를 표현하고 변환\n",
    "- **Part 5.6 (Calculus)**: 기울기 하강법으로 모델을 최적화\n",
    "- **이번 파트 (Machine Learning)**: 모든 것을 결합하여 실제 예측 모델 구축\n",
    "\n",
    "### 🚀 머신러닝의 핵심 구성 요소\n",
    "- **데이터 시각화**: Matplotlib, Seaborn으로 패턴 발견\n",
    "- **지도학습**: 정답이 있는 데이터로 패턴 학습\n",
    "- **모델 평가**: 훈련/테스트 분리로 일반화 성능 측정\n",
    "- **전처리**: 피처 스케일링으로 모델 성능 향상\n",
    "\n",
    "### 📈 학습 진행도\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c5dc7de3",
   "metadata": {},
   "outputs": [],
   "source": [
    "Part 5: AI Core Libraries ✅\n",
    "Part 5.5: Linear Algebra ✅\n",
    "Part 5.6: Calculus ✅\n",
    "Part 6: Machine Learning 🔄 (현재)\n",
    "Part 7: Deep Learning ⏳"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1763f852",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "### 🎯 이제 할 수 있는 것들\n",
    "- **실제 예측 모델 구축**: 집값 예측, 고객 이탈 예측 등\n",
    "- **데이터 기반 의사결정**: 시각화를 통한 인사이트 도출\n",
    "- **모델 성능 최적화**: 하이퍼파라미터 튜닝, 앙상블 기법\n",
    "- **실무 프로젝트**: 전체 머신러닝 파이프라인 구축\n",
    "\n",
    "---\n",
    "\n",
    "<br>\n",
    "\n",
    "> ## 1. 학습 목표 (Learning Objectives)\n",
    ">\n",
    "> 이번 파트가 끝나면, 여러분은 다음을 할 수 있게 됩니다.\n",
    "> \n",
    "> - Matplotlib와 Seaborn을 사용하여 데이터의 분포, 관계, 추세를 시각화하고 인사이트를 도출할 수 있습니다.\n",
    "> - 지도학습, 훈련/테스트 데이터 분할의 개념을 설명할 수 있습니다.\n",
    "> - Scikit-learn의 `fit()`, `predict()` 인터페이스를 사용하여 머신러닝 모델을 훈련하고, 새로운 데이터에 대한 예측을 만들 수 있습니다.\n",
    "> - 피처 스케일링(StandardScaler, MinMaxScaler)과 같은 핵심 전처리 기법을 모델 성능 향상을 위해 적용할 수 있습니다.\n",
    "> - 데이터 불러오기부터 전처리, 훈련, 평가까지 이어지는 머신러닝의 전체 파이프라인을 코드로 구현할 수 있습니다.\n",
    "\n",
    "<br>\n",
    "\n",
    "> ## 2. 핵심 요약 (Key Summary)\n",
    "> \n",
    "> 이 파트에서는 데이터에서 패턴을 발견하고 미래를 예측하는 머신러닝의 전 과정을 학습합니다. Matplotlib와 Seaborn을 이용한 데이터 시각화로 숨겨진 인사이트를 찾는 법을 배우고, Scikit-learn 라이브러리를 통해 지도학습의 기본 개념과 모델 훈련/평가 프로세스를 익힙니다. 훈련/테스트 데이터 분리, 피처 스케일링 등 핵심적인 데이터 전처리 기법을 적용하여 모델의 성능을 향상시키는 방법을 실습하며, 머신러닝 프로젝트의 전체 파이프라인을 직접 구축해 봅니다.\n",
    "> \n",
    "> - **핵심 키워드**: `데이터 시각화`, `Matplotlib`, `Seaborn`, `Scikit-learn`, `지도학습(Supervised Learning)`, `훈련/테스트 분리(Train/Test Split)`, `데이터 전처리(Preprocessing)`, `피처 스케일링(Feature Scaling)`, `모델 평가(Evaluation)`, `정확도(Accuracy)`\n",
    "\n",
    "<br>\n",
    "\n",
    "> ## 3. 도입: 데이터에서 지혜를 캐내는 기술 (Introduction)\n",
    ">\n",
    "> 이전 파트에서 우리는 NumPy와 Pandas로 데이터를 자유자재로 다루는 법을 배웠습니다. 하지만 숫자로만 가득한 표는 우리에게 많은 것을 알려주지 않습니다. 이번 파트에서는 데이터에 '생명'을 불어넣는 두 가지 핵심 기술, **시각화**와 **머신러닝**을 배웁니다.\n",
    "> \n",
    "> - **시각화**는 데이터 속에 숨겨진 패턴과 이야기를 발견하는 '눈'이 되어줄 것입니다.\n",
    "> - **머신러닝**은 그 패턴을 학습하여 미래를 예측하는 '두뇌' 역할을 합니다.\n",
    "> \n",
    "> Scikit-learn이라는 강력한 도구를 통해, 우리는 이 모든 과정을 직접 체험해볼 것입니다.\n",
    "> \n",
    "> > [!TIP]\n",
    "> > 본 파트의 모든 예제 코드는 `../../source_code/part_6_machine_learning.py` 파일에서 직접 실행하고 수정해볼 수 있습니다.\n",
    "\n",
    "---\n",
    "\n",
    "<br>\n",
    "\n",
    "> ## 4. 데이터 시각화: 그림으로 데이터와 대화하기\n",
    "> \n",
    "> > **🎯 1-2일차 목표:** Matplotlib와 Seaborn으로 데이터를 시각화하여 인사이트를 발견합니다.\n",
    "> \n",
    "> 데이터를 숫자로만 보는 것은 숲을 보지 못하고 나무만 보는 것과 같습니다. 시각화는 데이터 속에 숨겨진 패턴, 관계, 이상치를 한눈에 파악하게 해주는 강력한 도구입니다.\n",
    "> \n",
    "> - **Matplotlib**: 파이썬 시각화의 근간. 거의 모든 종류의 그래프를 그릴 수 있습니다. (비유: 하얀 도화지)\n",
    "> - **Seaborn**: Matplotlib을 더 쉽고 예쁘게 사용하도록 만든 고수준 라이브러리. 통계 기능이 특화되어 있습니다. (비유: 밑그림과 색칠 도구가 갖춰진 스케치북)\n",
    "> \n",
    "> #### 4-1. 어떤 그래프를 언제 쓸까?\n",
    "> - **선 그래프 (Line Plot)**: 시간에 따른 주가 변화처럼, 연속적인 데이터의 **추세**를 볼 때\n",
    "> - **막대 그래프 (Bar Plot)**: 반별 평균 키처럼, 여러 그룹 간의 값을 **비교**할 때\n",
    "> - **산점도 (Scatter Plot)**: 공부 시간과 성적처럼, 두 변수 간의 **관계**나 분포를 볼 때\n",
    "> - **히스토그램 (Histogram)**: 우리 반 학생들의 키 분포처럼, 데이터의 **분포**를 볼 때\n",
    "> - **히트맵 (Heatmap)**: 여러 변수들 간의 상관관계를 한눈에 **색상**으로 파악할 때\n",
    "> \n",
    "> #### 4-2. Seaborn 실전 예제\n",
    "> "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6ab10ec7",
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "\n",
    "# Seaborn에 내장된 'tips' 데이터셋 사용\n",
    "tips = sns.load_dataset(\"tips\")\n",
    "\n",
    "# 1. 산점도: 총 식사 금액과 팁 사이의 관계\n",
    "plt.figure(figsize=(8, 6))\n",
    "sns.scatterplot(x=\"total_bill\", y=\"tip\", data=tips, hue=\"smoker\", size=\"size\")\n",
    "plt.title(\"Total Bill vs Tip Amount\")\n",
    "plt.xlabel(\"Total Bill ($)\")\n",
    "plt.ylabel(\"Tip ($)\")\n",
    "plt.grid(True)\n",
    "plt.show()\n",
    "\n",
    "# 2. 막대 그래프: 요일별 평균 팁\n",
    "plt.figure(figsize=(8, 6))\n",
    "sns.barplot(x=\"day\", y=\"tip\", data=tips, errorbar=None) # errorbar=None은 신뢰구간 제거\n",
    "plt.title(\"Average Tip by Day of the Week\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8d259f44",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "---\n",
    "\n",
    "<br>\n",
    "\n",
    "> ## 4.5. 머신러닝의 종류: 어떤 문제를 풀고 싶은가?\n",
    "> \n",
    "> 본격적으로 모델을 만들기 전에, 머신러닝이 해결할 수 있는 문제의 종류를 이해하는 것은 매우 중요합니다. 머신러닝은 크게 **지도학습, 비지도학습, 강화학습** 세 가지로 나뉩니다.\n",
    "> \n",
    "> | 학습 유형 | 핵심 아이디어 | 대표적인 예시 | 주요 알고리즘 |\n",
    "> | :--- | :--- | :--- | :--- |\n",
    "> | **지도학습<br>(Supervised)** | **'정답'이 있는 데이터**로 학습 | 스팸 메일 분류, 집값 예측, 이미지 분류 (개/고양이) | 선형 회귀, 로지스틱 회귀, SVM, 결정 트리, 랜덤 포레스트 |\n",
    "> | **비지도학습<br>(Unsupervised)** | **'정답'이 없는 데이터**에서 패턴 발견 | 고객 그룹 분석, 토픽 모델링, 이상 탐지 | K-평균 군집, 주성분 분석(PCA) |\n",
    "> | **강화학습<br>(Reinforcement)** | **'보상'**을 최대화하는 행동을 학습 | 알파고(바둑), 자율주행, 로봇 제어 | Q-러닝, SARSA, DQN |\n",
    "> \n",
    "> ![머신러닝 종류](https://i.imgur.com/8aE5E9U.png)\n",
    "> \n",
    "> 이번 파트에서는 이 중에서 가장 널리 사용되고 산업적으로도 중요한 **지도학습**에 집중하여, '정답'이 주어진 데이터를 통해 미래를 예측하는 모델을 만드는 방법을 깊이 있게 다룰 것입니다.\n",
    "\n",
    "---\n",
    "\n",
    "<br>\n",
    "\n",
    "> ## 5. Scikit-learn으로 첫 머신러닝 모델 만들기\n",
    "> \n",
    "> > **🎯 3-4일차 목표:** Scikit-learn을 사용하여 머신러닝의 기본 프로세스(학습, 예측, 평가)를 이해합니다.\n",
    "> \n",
    "> ### 5-1. 머신러닝의 핵심: 훈련과 시험\n",
    "> - **지도학습(Supervised Learning)**: **입력(문제)**과 **정답**이 있는 데이터를 사용해, 문제와 정답 사이의 '패턴'을 기계에 학습시키는 방법입니다.\n",
    "> \n",
    "> > [!NOTE] 비유: 머신러닝은 '공부'와 '시험' 과정입니다.\n",
    "> > - **훈련 데이터 (Training Data)**: 모델이 학습하는 데 사용하는 **'교과서/모의고사'**.\n",
    "> > - **테스트 데이터 (Test Data)**: 모델의 최종 성능을 평가하기 위해, 학습 과정에서 **전혀 사용하지 않은 새로운 '수능 문제'**.\n",
    "> >\n",
    "> > 훈련 데이터로만 반복해서 시험 보면 100점이 나오겠지만, 진짜 실력이라고 할 수 없겠죠? 그래서 우리는 훈련/테스트 데이터를 엄격히 분리하여 모델의 **일반화 성능**(처음 보는 데이터에 대한 예측 능력)을 측정합니다.\n",
    "> \n",
    "> ### 5-2. 핵심 개념: 과적합, 과소적합, 그리고 편향-분산 트레이드오프\n",
    "> \n",
    "> 모델을 훈련시킬 때 가장 흔하게 마주치는 문제는 **과적합(Overfitting)**과 **과소적합(Underfitting)**입니다.\n",
    "> \n",
    "> - **과소적합 (Underfitting)**: 모델이 너무 단순해서 데이터의 내재된 패턴을 제대로 학습하지 못하는 상태입니다. **훈련 데이터에서도 성능이 낮고, 테스트 데이터에서도 성능이 낮은** 특징을 보입니다. (비유: 시험 범위의 절반만 공부한 학생)\n",
    "> - **과적합 (Overfitting)**: 모델이 훈련 데이터에만 너무 과도하게 맞춰져, 노이즈나 특정 패턴까지 전부 외워버린 상태입니다. **훈련 데이터에서는 성능이 매우 높지만, 새로운 테스트 데이터에서는 성능이 급격히 떨어지는** 특징을 보입니다. (비유: 모의고사 족보만 달달 외워, 새로운 유형의 수능 문제에 대처하지 못하는 학생)\n",
    "> \n",
    "> 이 두 문제는 **모델의 복잡도(Model Complexity)**와 깊은 관련이 있으며, 이를 **편향-분산 트레이드오프(Bias-Variance Tradeoff)** 라고 부릅니다.\n",
    "> \n",
    "> ![Bias-Variance Tradeoff](https://i.imgur.com/2s42p4s.png)\n",
    "> \n",
    "> - **편향 (Bias)**: 모델이 실제 관계와 얼마나 다른지를 나타냅니다. 편향이 높으면 모델이 너무 단순하여 과소적합 경향을 보입니다.\n",
    "> - **분산 (Variance)**: 데이터의 작은 변화에 모델이 얼마나 민감하게 변하는지를 나타냅니다. 분산이 높으면 모델이 너무 복잡하여 과적합 경향을 보입니다.\n",
    "> \n",
    "> 우리의 목표는 **편향과 분산이 모두 낮은, 즉 전체 오류가 최소가 되는 '최적의 균형점(Optimal Balance)'**을 찾는 것입니다.\n",
    "> \n",
    "> ### 5-3. Scikit-learn 기본 4단계 프로세스\n",
    "> Scikit-learn은 다음과 같은 통일된 인터페이스를 제공하여 누구나 쉽게 머신러닝 모델을 만들 수 있게 해줍니다.\n",
    "> \n",
    "> 1.  **모델 객체 생성**: `model = ModelName()`\n",
    "> 2.  **모델 학습**: `model.fit(X_train, y_train)` (훈련 데이터로 공부)\n",
    "> 3.  **예측**: `predictions = model.predict(X_test)` (테스트 데이터로 시험)\n",
    "> 4.  **평가**: `score = accuracy_score(y_test, predictions)` (채점)\n",
    "> \n",
    "> "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "48d0241e",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.tree import DecisionTreeClassifier\n",
    "from sklearn.metrics import accuracy_score\n",
    "import seaborn as sns\n",
    "import numpy as np\n",
    "\n",
    "# 데이터 로드 (붓꽃 데이터)\n",
    "iris = sns.load_dataset(\"iris\")\n",
    "X, y = iris.drop(\"species\", axis=1), iris[\"species\"]\n",
    "\n",
    "# 1. 데이터 분리 (훈련 80%, 테스트 20%)\n",
    "# stratify=y : 훈련/테스트 데이터의 클래스 비율을 원본과 동일하게 유지\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)\n",
    "\n",
    "# 2. 모델 생성 및 학습\n",
    "model = DecisionTreeClassifier(random_state=42)\n",
    "model.fit(X_train, y_train)\n",
    "\n",
    "# 3. 예측\n",
    "predictions = model.predict(X_test)\n",
    "\n",
    "# 4. 평가 (정확도)\n",
    "accuracy = accuracy_score(y_test, predictions)\n",
    "print(f\"정확도: {accuracy:.4f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e7f494e5",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "### 5-4. 모델 성능을 높이는 데이터 전처리\n",
    "모델의 성능은 알고리즘만큼이나 **'데이터의 품질'**에 크게 좌우됩니다. \"Garbage In, Garbage Out\" (쓰레기를 넣으면 쓰레기가 나온다) 라는 말이 있을 정도입니다.\n",
    "\n",
    "- **피처 스케일링(Feature Scaling)**: 변수들의 단위를 맞춰줍니다. (예: 키(cm)와 몸무게(kg) -> 0~1 사이 값으로 표준화)\n",
    "    - **StandardScaler**: 평균 0, 표준편차 1로 변환. (분포가 정규분포에 가까울 때 효과적)\n",
    "    - **MinMaxScaler**: 최솟값 0, 최댓값 1로 변환. (모든 값을 0과 1 사이로 만들고 싶을 때)\n",
    "\n",
    "> [!NOTE] 스케일러의 수학적 원리\n",
    "> \n",
    "> - **StandardScaler (표준화)**: 각 특성의 평균(μ)을 0, 표준편차(σ)를 1로 만듭니다.\n",
    ">   \\[ z = \\frac{x - \\mu}{\\sigma} \\]\n",
    ">   이는 데이터의 분포를 정규분포와 유사하게 만들어, 거리 기반 알고리즘(e.g., SVM, 로지스틱 회귀)이나 경사 하강법을 사용하는 모델의 성능을 향상시키는 데 도움을 줍니다.\n",
    "> \n",
    "> - **MinMaxScaler (정규화)**: 각 특성의 모든 값을 0과 1 사이로 조정합니다.\n",
    ">   \\[ x' = \\frac{x - \\min(x)}{\\max(x) - \\min(x)} \\]\n",
    ">   이미지 픽셀 값을 0~255에서 0~1 사이로 변환하거나, 신경망 모델의 입력으로 사용할 때 자주 사용됩니다.\n",
    "> \n",
    "> "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1aa85831",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import StandardScaler, MinMaxScaler\n",
    "import numpy as np\n",
    "\n",
    "data = np.array([[170, 70], [180, 85], [160, 55]], dtype=float)\n",
    "\n",
    "scaler_std = StandardScaler()\n",
    "scaled_std = scaler_std.fit_transform(data)\n",
    "print(\"StandardScaler 결과:\\n\", scaled_std)\n",
    "\n",
    "scaler_minmax = MinMaxScaler()\n",
    "scaled_minmax = scaler_minmax.fit_transform(data)\n",
    "print(\"\\nMinMaxScaler 결과:\\n\", scaled_minmax)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "56b0cff2",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "### 5-5. 모델 상세 평가: 정확도를 넘어서\n",
    "\n",
    "모델의 성능을 단순히 '정확도(Accuracy)' 하나만으로 평가하는 것은 때로는 위험할 수 있습니다. 특히 데이터가 불균형할 때(예: 스팸 메일 1%, 정상 메일 99%)는 더욱 그렇습니다.\n",
    "\n",
    "#### 혼동 행렬 (Confusion Matrix)\n",
    "모델의 예측이 얼마나 헷갈렸는지(confused)를 보여주는 표입니다.\n",
    "\n",
    "- **TN (True Negative)**: 음성(Negative)을 음성으로 올바르게 예측\n",
    "- **FP (False Positive)**: 음성(Negative)을 양성(Positive)으로 잘못 예측 (Type I Error)\n",
    "- **FN (False Negative)**: 양성(Positive)을 음성(Negative)으로 잘못 예측 (Type II Error)\n",
    "- **TP (True Positive)**: 양성(Positive)을 양성으로 올바르게 예측\n",
    "\n",
    "![Confusion Matrix](https://i.imgur.com/A4EGF24.png)\n",
    "\n",
    "#### 정밀도, 재현율, F1-Score\n",
    "- **정밀도 (Precision)** = `TP / (TP + FP)`\n",
    "  - 모델이 \"양성\"이라고 예측한 것들 중, 실제로 양성이었던 것의 비율입니다.\n",
    "  - **\"스팸이라고 예측한 메일 중, 진짜 스팸은 얼마나 되는가?\"**\n",
    "  - FP(정상 메일을 스팸으로 처리)를 낮추는 것이 중요할 때 사용합니다. (예: 유튜브 키즈 콘텐츠 필터링)\n",
    "- **재현율 (Recall)** = `TP / (TP + FN)`\n",
    "  - 실제 양성인 것들 중, 모델이 양성으로 예측한 것의 비율입니다.\n",
    "  - **\"실제 암 환자 중, 모델이 암이라고 진단한 비율은 얼마인가?\"**\n",
    "  - FN(암 환자를 정상으로 진단)을 낮추는 것이 중요할 때 사용합니다. (예: 의료 진단, 금융 사기 탐지)\n",
    "- **F1-Score** = `2 * (Precision * Recall) / (Precision + Recall)`\n",
    "  - 정밀도와 재현율의 조화 평균입니다. 두 지표가 모두 중요할 때 사용하며, 데이터가 불균형할 때 정확도보다 훨씬 신뢰할 수 있는 지표입니다.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6b296ed0",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import confusion_matrix, precision_score, recall_score, f1_score\n",
    "\n",
    "# ... (이전 코드에서 predictions, y_test가 생성되었다고 가정) ...\n",
    "\n",
    "# 혼동 행렬\n",
    "conf_matrix = confusion_matrix(y_test, predictions)\n",
    "print(\"Confusion Matrix:\\n\", conf_matrix)\n",
    "\n",
    "# 정밀도, 재현율, F1-점수\n",
    "precision = precision_score(y_test, predictions, average='macro') # 다중 클래스일 경우 average 지정\n",
    "recall = recall_score(y_test, predictions, average='macro')\n",
    "f1 = f1_score(y_test, predictions, average='macro')\n",
    "\n",
    "print(f\"Precision: {precision:.4f}\")\n",
    "print(f\"Recall: {recall:.4f}\")\n",
    "print(f\"F1 Score: {f1:.4f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0a8a2833",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "### 5-6. 심화: 어떤 모델을 언제 사용해야 할까? (Model Selection Guide)\n",
    "\n",
    "Scikit-learn에는 수많은 머신러닝 모델이 존재합니다. 문제의 종류, 데이터의 특성, 그리고 우리가 추구하는 목표(성능, 해석 가능성, 속도 등)에 따라 최적의 모델은 달라집니다. 여기서는 가장 대표적인 **분류(Classification)** 모델 몇 가지를 비교하고, 언제 어떤 모델을 선택하는 것이 좋은지에 대한 가이드라인을 제시합니다.\n",
    "\n",
    "| 모델 | 핵심 아이디어 | 장점 | 단점 | 언제 사용하면 좋을까? |\n",
    "| :--- | :--- | :--- | :--- | :--- |\n",
    "| **로지스틱 회귀<br>(Logistic Regression)** | 데이터가 특정 클래스에 속할 확률을 선형 결정 경계로 예측 | 빠르고, 간단하며, **해석이 용이함**. 모델의 계수가 각 특성의 중요도를 나타냄. | 복잡한 비선형 관계를 학습하기 어려움. | **모델의 해석**이 중요할 때 (e.g., 금융, 의료), 베이스라인 모델로 사용하기 좋음. |\n",
    "| **결정 트리<br>(Decision Tree)** | 데이터를 '예/아니오' 질문(규칙)의 연속으로 나누어 예측 | **결과를 이해하기 쉬움 (White Box)**. 시각화가 가능함. 스케일링이 필요 없음. | **과적합(Overfitting) 위험이 높음**. 데이터의 작은 변화에도 모델이 크게 변동될 수 있음. | 규칙 기반으로 데이터를 설명하고 싶을 때. (e.g., 고객 이탈 원인 분석) |\n",
    "| **랜덤 포레스트<br>(Random Forest)** | 여러 개의 작은 결정 트리들을 만들어, 그 결과를 **투표(Voting)**하여 종합. (앙상블 기법) | **성능이 매우 우수함**. 과적합에 강하고 안정적임. | 결정 트리보다 **해석이 어려움 (Black Box)**. 훈련 속도가 느리고 메모리를 더 많이 사용. | **높은 예측 성능**이 가장 중요할 때. 대부분의 분류 문제에서 좋은 성능을 보임. |\n",
    "| **서포트 벡터 머신<br>(SVM)** | 클래스 간의 **마진(Margin)을 최대화**하는 결정 경계를 찾음. | 고차원 데이터에서 잘 작동하며, 과적합에 강함. | 데이터가 많을 때 훈련 속도가 매우 느림. 파라미터 튜닝에 민감함. | 특성(Feature)이 매우 많은 복잡한 데이터셋 (e.g., 이미지, 바이오인포매틱스)에 효과적. |\n",
    "\n",
    "> [!NOTE] 핵심 질문: 해석 가능성(Interpretability) vs. 성능(Performance)\n",
    "> - **해석이 중요하다면?** -> Logistic Regression, Decision Tree\n",
    "> - **성능이 중요하다면?** -> Random Forest, Gradient Boosting (더 발전된 앙상블), SVM\n",
    ">\n",
    "> 실무에서는 먼저 Logistic Regression이나 Decision Tree 같은 간단한 모델로 베이스라인을 설정하고, 점차 Random Forest나 Gradient Boosting과 같은 복잡한 모델로 성능을 높여가는 방식을 많이 사용합니다.\n",
    "\n",
    "이 가이드는 시작점일 뿐이며, 최고의 모델을 찾는 유일한 방법은 **직접 여러 모델을 실험해보고, 교차 검증(Cross-validation)을 통해 성능을 객관적으로 평가하는 것**입니다.\n",
    "\n",
    "### 5-7. 핵심 개념: 교차 검증 (Cross-Validation)\n",
    "\n",
    "우리가 데이터를 훈련/테스트 세트로 한 번 나누는 것은 마치 모의고사를 딱 한 번만 보고 수능 점수를 예측하는 것과 같습니다. 이 분할이 어떻게 되었는지에 따라 성능이 우연히 좋거나 나쁘게 나올 수 있습니다.\n",
    "\n",
    "**교차 검증(Cross-Validation)**은 이 문제를 해결하기 위해 데이터를 여러 번 다른 방식으로 나누어 학습과 평가를 반복하는 방법입니다. 가장 널리 쓰이는 방법은 **K-겹 교차 검증(K-Fold Cross-Validation)**입니다.\n",
    "\n",
    "1. 전체 데이터를 K개의 '겹(Fold)'으로 나눕니다.\n",
    "2. 첫 번째 겹을 테스트 데이터로 사용하고, 나머지 K-1개 겹을 훈련 데이터로 사용하여 모델을 학습하고 평가합니다.\n",
    "3. 두 번째 겹을 테스트 데이터로 사용하고, 나머지를 훈련 데이터로 사용하여 다시 학습하고 평가합니다.\n",
    "4. 이 과정을 K번 반복하여, K개의 성능 점수를 얻습니다.\n",
    "5. 최종적으로 이 K개의 점수를 평균내어 모델의 일반화된 성능을 추정합니다.\n",
    "\n",
    "![K-Fold Cross Validation](https://i.imgur.com/0K3jTf7.png)\n",
    "\n",
    "> [!NOTE] 장점:\n",
    "> - 데이터를 더 효율적으로 사용하며, 모델의 성능을 훨씬 더 안정적이고 신뢰성 있게 평가할 수 있습니다.\n",
    "> - 특정 데이터 분할에 따른 성능 변동의 위험을 줄여줍니다.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "87dc7faf",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import cross_val_score\n",
    "\n",
    "# 모델 생성\n",
    "model = DecisionTreeClassifier(random_state=42)\n",
    "\n",
    "# 5-겹 교차 검증 수행\n",
    "# cv=5 : 5개의 폴드로 나눔\n",
    "# scoring='accuracy' : 평가 지표로 정확도 사용\n",
    "scores = cross_val_score(model, X_train, y_train, cv=5, scoring='accuracy')\n",
    "\n",
    "print(f\"교차 검증 점수: {scores}\")\n",
    "print(f\"평균 정확도: {scores.mean():.4f} (+/- {scores.std() * 2:.4f})\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "874311d5",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "### 5-8. 실제 기업 적용 사례 (Real-world Enterprise Use Cases)\n",
    "\n",
    "우리가 배운 머신러닝 기술은 단순히 학문적인 개념에 머무르지 않고, 오늘날 수많은 글로벌 기업들의 핵심 서비스를 구동하는 엔진이 되고 있습니다. 몇 가지 대표적인 사례를 통해 머신러닝이 실제로 어떻게 가치를 창출하는지 살펴보겠습니다.\n",
    "\n",
    "| 기업 | 적용 분야 | 사용 기술 및 모델 (추정) | 비즈니스 가치 |\n",
    "| :--- | :--- | :--- | :--- |\n",
    "| **Netflix** | **영화/드라마 추천 시스템** | 협업 필터링, 콘텐츠 기반 필터링, 랭킹 알고리즘 (e.g., Logistic Regression, Gradient Boosting) | 개인화된 콘텐츠 추천을 통해 **고객 이탈률을 낮추고**, 사용자 만족도를 극대화. (매년 1조 원 이상의 가치 창출) |\n",
    "| **Google** | **Gmail 스팸 필터** | 지도 학습 분류기 (e.g., Naive Bayes, Logistic Regression), 딥러닝(RNN, Transformer) | 매일 수십억 개의 스팸 메일을 99.9% 이상의 정확도로 차단하여, **사용자 경험을 보호**하고 보안 위협을 감소시킴. |\n",
    "| **Google** | **검색 결과 랭킹 (RankBrain)** | 학습-투-랭크(Learning to Rank) 알고리즘 | 이전에는 없었던 새로운 검색어(전체 검색의 15%)에 대해 **가장 관련성 높은 결과를 추론**하여 제시. 검색 품질 향상. |\n",
    "| **Meta (Facebook)** | **뉴스피드 랭킹** | 랭킹 알고리즘, 대규모 추천 시스템 | 수천 개의 잠재적 게시물 중 사용자에게 가장 흥미로울 만한 콘텐츠를 예측하여 보여줌으로써, **플랫폼 체류 시간을 늘리고** 광고 효율을 높임. |\n",
    "| **Amazon** | **상품 추천 (Customers who bought this item also bought...)** | 협업 필터링 (Item-to-Item), 개인화 랭킹 | 사용자의 구매 패턴을 분석하여 관련 상품을 추천함으로써, **객단가(Average Order Value)를 높이고** 새로운 상품을 발견할 기회를 제공. |\n",
    "\n",
    "> [!NOTE] 시사점: 문제 정의의 중요성\n",
    "> 위 사례들의 공통점은 기술 자체가 목적이 아니라, '고객 이탈 방지', '사용자 경험 보호', '관련성 높은 정보 제공'과 같은 **명확한 비즈니스 문제를 해결하기 위해 머신러닝을 '도구'로 사용했다는 점**입니다. 성공적인 머신러닝 프로젝트를 위해서는 \"어떤 모델을 쓸까?\" 보다 \"**어떤 문제를 풀고 싶은가?**\"를 먼저 정의하는 것이 중요합니다.\n",
    "\n",
    "---\n",
    "\n",
    "## 7. 심화 토론: 무엇이 잘못될 수 있을까?\n",
    "\n",
    "Scikit-learn을 사용하면 몇 줄의 코드로 쉽게 모델을 만들 수 있지만, 그 과정에는 수많은 함정이 존재합니다. \"동작하는\" 코드를 넘어 \"올바른\" 코드를 작성하기 위해 다음 주제들에 대해 함께 토론해보세요.\n",
    "\n",
    "1.  **전처리 순서가 초래한 데이터 누수(Data Leakage)**\n",
    "    -   **상황**: 한 동료가 효율성을 위해 전체 데이터셋 `X`에 대해 `StandardScaler`를 먼저 적용(`fit_transform`)한 후, 그 결과를 `train_test_split`으로 나누어 모델을 학습시켰습니다. 코드는 오류 없이 잘 동작했고, 테스트 정확도도 꽤 높게 나왔습니다.\n",
    "    -   **토론**:\n",
    "        -   이 접근 방식의 무엇이 치명적인 실수일까요? 테스트셋의 정보가 훈련 과정에 어떻게 \"누수\"되었을까요? (힌트: `fit` 메소드는 데이터의 평균과 표준편차를 계산합니다.)\n",
    "        -   피처 스케일링과 같은 전처리 단계를 올바르게 적용하는 파이프라인은 어떤 순서로 구성되어야 할까요? 왜 그 순서가 중요한가요?\n",
    "\n",
    "2.  **\"완벽한\" 테스트 점수에 대한 의심**\n",
    "    -   **상황**: 타이타닉 생존자 예측 문제를 해결하기 위해 여러 모델과 특성을 조합해본 결과, 마침내 제공된 테스트셋에 대해 100%의 정확도를 달성했습니다.\n",
    "    -   **토론**:\n",
    "        -   이 결과를 기뻐해야 할까요, 아니면 의심해야 할까요? \"완벽한\" 점수가 나올 수 있는 잠재적인 원인들은 무엇일까요? (예: 타겟 변수가 특성에 포함됨, 테스트셋이 너무 작거나 대표성이 없음, 특정 테스트셋에 대한 과적합 등)\n",
    "        -   실제 서비스를 만든다고 가정할 때, 왜 최종 성능 검증을 위해 단 한 번만 사용하는 별도의 \"검증(validation) 데이터셋\"을 따로 떼어놓는 것이 중요한지 토론해보세요.\n",
    "\n",
    "3.  **특성 중요도(Feature Importance)의 섣부른 해석**\n",
    "    -   **상황**: 고객 이탈 예측을 위해 만든 랜덤 포레스트 모델이 '월 청구요금'을 가장 중요한 특성으로 지목했습니다. 이 결과를 보고, 마케팅팀은 모든 고객의 요금을 인하하는 캠페인을 기획하려 합니다.\n",
    "    -   **토론**:\n",
    "        -   이러한 의사 결정이 왜 섣부른 판단일 수 있을까요? 랜덤 포레스트는 특성 중요도를 어떤 방식으로 계산하나요?\n",
    "        -   높은 특성 중요도가 '인과 관계'를 의미할까요, 아니면 단순한 '상관 관계'일 가능성이 높을까요? 이처럼 중요한 비즈니스 결정을 내리기 전에, 어떤 추가적인 분석이나 실험을 수행해야 할까요?\n",
    "\n",
    "## 8. 되짚어보기 (Summary)\n",
    "\n",
    "이번 주 우리는 데이터에서 패턴을 찾아 미래를 예측하는 머신러닝의 세계를 여행했습니다.\n",
    "\n",
    "- **시각화는 눈**: Matplotlib와 Seaborn으로 데이터 속에 숨겨진 이야기를 보는 법을 배웠습니다.\n",
    "- **머신러닝은 뇌**: Scikit-learn을 사용해 '훈련'과 '시험'이라는 과정을 거쳐 예측 모델을 만드는 법을 익혔습니다.\n",
    "- **데이터는 생명**: \"Garbage In, Garbage Out.\" 좋은 예측을 위해서는 결측치 처리, 피처 스케일링과 같은 데이터 전처리가 필수임을 이해했습니다.\n",
    "\n",
    "이제 여러분은 데이터를 분석하고 예측 모델을 만들 수 있는 기본적인 역량을 갖추었습니다.\n",
    "\n",
    "---\n",
    "## 9. 트러블슈팅 (Troubleshooting)\n",
    "\n",
    "- **그래프에 한글이 깨져서 `□□□` 형태로 나오나요?**\n",
    "  - Matplotlib가 기본적으로 한글 폰트를 지원하지 않기 때문입니다. 아래 코드를 실행하여 시스템에 맞는 한글 폰트를 설정해주어야 합니다.\n",
    "\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "81a68f34",
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "    # For Windows\n",
    "    # plt.rcParams['font.family'] = 'Malgun Gothic'\n",
    "    # For macOS\n",
    "    # plt.rcParams['font.family'] = 'AppleGothic'"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1584d11c",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "- **`fit_transform()`은 훈련 데이터에만 사용하고, `transform()`은 테스트 데이터에 사용하라는 말이 무슨 뜻인가요?**\n",
    "  - `fit()`은 데이터로부터 스케일링에 필요한 정보(e.g., 평균, 표준편차, 최소/최대값)를 '학습'하는 과정입니다. `transform()`은 학습된 정보를 바탕으로 데이터를 변환합니다. `fit_transform()`은 이 두 과정을 한 번에 수행합니다. 테스트 데이터는 '미래의 데이터'를 의미하므로, 훈련 데이터로 `fit()`한 스케일러를 사용하여 `transform()`만 적용해야 합니다.\n",
    "\n",
    "- **모델의 성능이 너무 낮게 나오나요?**\n",
    "  - 여러 가능성이 있습니다.\n",
    "    - **데이터 전처리**: 결측치를 적절히 처리했나요? 범주형 변수(e.g., 'sex')를 숫자로 변환했나요? 피처 스케일링이 필요한 모델인데 적용했나요?\n",
    "    - **특성 선택**: 모델에 너무 적은 특성을 사용했거나, 반대로 예측에 도움이 되지 않는 불필요한 특성을 너무 많이 사용했을 수 있습니다.\n",
    "    - **모델 선택**: 현재 문제에 적합하지 않은 모델을 사용했을 수 있습니다. 'Model Selection Guide'를 참고하여 다른 모델을 시도해보세요.\n",
    "    - **과적합/과소적합**: 훈련 데이터의 점수는 높은데 테스트 데이터의 점수가 현저히 낮다면 과적합(Overfitting)을, 둘 다 낮다면 과소적합(Underfitting)을 의심해볼 수 있습니다.\n",
    "\n",
    "- **`ValueError: Input contains NaN, infinity or a value too large for dtype('float64').` 오류가 발생했나요?**\n",
    "  - 모델의 입력 데이터(`X_train`)에 결측치(NaN), 무한대(infinity) 값이 포함되어 있다는 의미입니다. 모델을 학습시키기 전, `X_train.isnull().sum()` 과 같은 코드로 결측치를 확인하고, `fillna()` 등을 사용하여 적절히 처리해야 합니다.\n",
    "\n",
    "더 자세한 문제 해결 가이드나 다른 동료들이 겪은 문제에 대한 해결책이 궁금하다면, 아래 문서를 참고해주세요.\n",
    "\n",
    "- **➡️ [Geumdo-Docs: TROUBLESHOOTING.md](../../../TROUBLESHOOTING.md)**\n",
    "\n",
    "---\n",
    "\n",
    "## 10. 더 깊이 알아보기 (Further Reading)\n",
    "\n",
    "### 실전 코드 & 튜토리얼\n",
    "- [Scikit-learn 공식 예제 갤러리](https://scikit-learn.org/stable/auto_examples/index.html): 다양한 모델과 데이터셋에 대한 예제 코드의 보고\n",
    "- [Seaborn 공식 튜토리얼](https://seaborn.pydata.org/tutorial.html): 더 아름답고 전문적인 시각화를 위한 가이드\n",
    "- [Kaggle](https://www.kaggle.com/): 전 세계 데이터 과학자들이 모여 경쟁하는 플랫폼. 'Titanic'과 같은 다양한 입문용 프로젝트를 체험할 수 있습니다.\n",
    "\n",
    "### 이론 및 개념 심화\n",
    "- **[An Introduction to Statistical Learning (ISLR)](https://www.statlearning.com/)**: 머신러닝의 바이블로 불리는 명저. 통계적 이론 배경을 탄탄히 다지고 싶다면 필독을 권합니다. (PDF 무료 제공)\n",
    "- **[StatQuest 유튜브 채널](https://www.youtube.com/c/statquest)**: 결정 트리, 로지스틱 회귀 등 머신러닝의 핵심 개념들을 가장 직관적이고 명쾌하게 설명해주는 채널입니다.\n",
    "- **[Scikit-learn: 모델 평가 지표 가이드](https://scikit-learn.org/stable/modules/model_evaluation.html)**: 본문에서 다룬 정확도 외에 정밀도, 재현율, F1-score 등 다양한 평가 지표에 대한 상세한 설명과 사용법을 제공합니다.\n",
    "- **[Seeing-Theory](https://seeing-theory.brown.edu/index.html)**: 확률 및 통계의 핵심 개념들을 인터랙티브 시각화 자료를 통해 체험하며 배울 수 있는 사이트입니다.\n",
    "\n",
    "---\n",
    "\n",
    "## 🚀 캡스톤 미니 프로젝트: 모델 성능 비교 및 파이프라인 구축\n",
    "\n",
    "이번 장에서는 머신러닝의 전체 흐름을 배웠습니다. 하지만 실전 프로젝트에서는 단 하나의 모델만 만들어보는 경우는 거의 없습니다. 어떤 모델이 이 문제에 가장 적합한지, 그리고 데이터 전처리가 성능에 어떤 영향을 미치는지 체계적으로 '실험'하고 '비교'하는 과정이 필수적입니다.\n",
    "\n",
    "이번 미니 프로젝트의 목표는 Scikit-learn의 `Pipeline`을 사용하여 데이터 전처리(스케일링)와 모델 훈련을 하나의 파이프라인으로 묶고, 여러 다른 모델의 성능을 체계적으로 비교하여 최적의 모델을 찾는 과정을 경험하는 것입니다.\n",
    "\n",
    "### 프로젝트 목표\n",
    "\n",
    "Scikit-learn의 내장 데이터셋인 붓꽃(Iris) 데이터를 사용하여, 다음 세 가지 모델의 성능을 '전처리 적용 전/후'로 나누어 비교하고, 그 결과를 보고서로 작성합니다.\n",
    "1.  Logistic Regression\n",
    "2.  Decision Tree Classifier\n",
    "3.  Random Forest Classifier\n",
    "\n",
    "**최종 분석 리포트 (예시):**\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f6bc3e57",
   "metadata": {},
   "outputs": [],
   "source": [
    "*** Model Performance Comparison Report ***\n",
    "\n",
    "[Without Scaling]\n",
    "- LogisticRegression Accuracy: 0.9333\n",
    "- DecisionTreeClassifier Accuracy: 1.0000\n",
    "- RandomForestClassifier Accuracy: 1.0000\n",
    "\n",
    "[With StandardScaler]\n",
    "- LogisticRegression Accuracy: 1.0000\n",
    "- DecisionTreeClassifier Accuracy: 1.0000\n",
    "- RandomForestClassifier Accuracy: 1.0000\n",
    "\n",
    "[Analysis]\n",
    "- 스케일링을 적용했을 때 Logistic Regression의 성능이 향상되었습니다.\n",
    "- 트리 기반 모델인 Decision Tree와 Random Forest는 스케일링의 영향을 받지 않았습니다.\n",
    "- ..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6c77713d",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "### 단계별 구현 가이드\n",
    "\n",
    "**1. 데이터 준비**\n",
    "- `sklearn.datasets`에서 `load_iris` 함수를 사용해 데이터를 불러오세요.\n",
    "- `train_test_split`을 사용하여 데이터를 훈련셋과 테스트셋으로 분리합니다.\n",
    "\n",
    "**2. 모델 비교 실험 (스케일링 미적용)**\n",
    "- 비교할 모델들을 리스트에 담으세요: `[LogisticRegression(), DecisionTreeClassifier(), RandomForestClassifier()]`\n",
    "- `for` 루프를 사용해 각 모델을 순회하며 다음을 반복합니다.\n",
    "  - 모델을 훈련 데이터로 학습 (`fit`)\n",
    "  - 테스트 데이터로 예측 (`predict`)\n",
    "  - 정확도(`accuracy_score`)를 계산하고 결과를 저장\n",
    "\n",
    "**3. Scikit-learn `Pipeline`으로 전처리 및 모델링 자동화**\n",
    "- 데이터 전처리와 모델 학습을 하나의 객체로 묶어주는 `Pipeline`을 사용해 봅시다. 이는 데이터 누수(Data Leakage)를 방지하는 매우 중요한 실무 기법입니다.\n",
    "- `from sklearn.pipeline import Pipeline`\n",
    "- `from sklearn.preprocessing import StandardScaler`\n",
    "- 다시 모델 리스트를 순회하며, 각 모델에 대해 `StandardScaler`와 모델을 포함하는 파이프라인을 생성합니다.\n",
    "  - `pipe = Pipeline([('scaler', StandardScaler()), ('classifier', model)])`\n",
    "- 전체 파이프라인을 훈련 데이터로 학습시키고(`pipe.fit`), 테스트 데이터로 정확도를 평가합니다.\n",
    "\n",
    "**4. 결과 보고 및 분석**\n",
    "- 위 두 실험(스케일링 전/후)의 결과를 보기 좋게 출력하세요.\n",
    "- 결과에 대한 분석을 1~2줄로 덧붙여 보세요.\n",
    "  - 왜 Logistic Regression 모델의 성능은 스케일링 후 변했는데, 트리 기반 모델들은 변하지 않았을까요? (힌트: 각 모델이 데이터를 어떻게 바라보는지 생각해보세요. 거리 기반 vs 규칙 기반)\n",
    "\n",
    "**전체 코드 구조:**\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d83cd89c",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "from sklearn.datasets import load_iris\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "from sklearn.tree import DecisionTreeClassifier\n",
    "from sklearn.ensemble import RandomForestClassifier\n",
    "from sklearn.metrics import accuracy_score\n",
    "from sklearn.pipeline import Pipeline\n",
    "\n",
    "# 1. 데이터 준비\n",
    "iris = load_iris()\n",
    "X, y = iris.data, iris.target\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)\n",
    "\n",
    "# 2. 비교할 모델 리스트\n",
    "models = [\n",
    "    LogisticRegression(max_iter=1000),\n",
    "    DecisionTreeClassifier(random_state=42),\n",
    "    RandomForestClassifier(random_state=42)\n",
    "]\n",
    "\n",
    "# 3. 실험: 스케일링 전/후 성능 비교\n",
    "results_no_scaling = {}\n",
    "results_with_scaling = {}\n",
    "\n",
    "print(\"--- Starting Model Evaluation ---\")\n",
    "\n",
    "for model in models:\n",
    "    model_name = model.__class__.__name__\n",
    "    \n",
    "    # 스케일링 없이 학습 및 평가\n",
    "    model.fit(X_train, y_train)\n",
    "    pred_no_scaling = model.predict(X_test)\n",
    "    results_no_scaling[model_name] = accuracy_score(y_test, pred_no_scaling)\n",
    "\n",
    "    # 파이프라인으로 스케일링 적용 후 학습 및 평가\n",
    "    pipe = Pipeline([\n",
    "        ('scaler', StandardScaler()),\n",
    "        ('classifier', model)\n",
    "    ])\n",
    "    pipe.fit(X_train, y_train)\n",
    "    pred_with_scaling = pipe.predict(X_test)\n",
    "    results_with_scaling[model_name] = accuracy_score(y_test, pred_with_scaling)\n",
    "\n",
    "# 4. 결과 출력\n",
    "print(\"\\n*** Model Performance Comparison Report ***\\n\")\n",
    "print(\"[Without Scaling]\")\n",
    "for model_name, acc in results_no_scaling.items():\n",
    "    print(f\"- {model_name} Accuracy: {acc:.4f}\")\n",
    "\n",
    "print(\"\\n[With StandardScaler]\")\n",
    "for model_name, acc in results_with_scaling.items():\n",
    "    print(f\"- {model_name} Accuracy: {acc:.4f}\")\n",
    "\n",
    "print(\"\\n[Analysis]\")\n",
    "print(\"로지스틱 회귀와 같은 거리 기반 알고리즘은 피처 스케일링에 영향을 받지만,\")\n",
    "print(\"결정 트리 기반 알고리즘은 각 피처를 독립적으로 보기 때문에 스케일링의 영향을 거의 받지 않습니다.\")\n",
    "print(\"---------------------------------------\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4ffa55b4",
   "metadata": {},
   "source": [
    "\n",
    "이러한 체계적인 실험 과정을 통해, 여러분은 단순히 하나의 모델을 만드는 것을 넘어, 주어진 문제와 데이터에 가장 적합한 해결책을 '찾아내는' 데이터 과학자의 역량을 기르게 될 것입니다.\n",
    "\n",
    "---\n",
    "\n",
    "## ✅ Part 6 완료 체크리스트\n",
    "\n",
    "### 🎯 달성 목표 확인\n",
    "다음 항목들을 모두 완료했다면 머신러닝의 핵심을 이해한 것입니다!\n",
    "\n",
    "#### 📊 데이터 시각화 능력\n",
    "- [ ] Matplotlib와 Seaborn으로 다양한 그래프 생성\n",
    "- [ ] 데이터의 분포, 관계, 추세를 시각화하여 인사이트 도출\n",
    "- [ ] 적절한 그래프 유형 선택 (산점도, 히스토그램, 히트맵 등)\n",
    "- [ ] 시각화를 통한 데이터 품질 문제 발견\n",
    "\n",
    "#### 🤖 머신러닝 모델링 능력\n",
    "- [ ] 지도학습의 개념과 훈련/테스트 분할 이해\n",
    "- [ ] Scikit-learn의 fit(), predict() 인터페이스 활용\n",
    "- [ ] 다양한 분류 모델 (로지스틱 회귀, 결정 트리, 랜덤 포레스트) 구현\n",
    "- [ ] 모델 성능 평가 지표 (정확도, 정밀도, 재현율) 이해\n",
    "\n",
    "#### 🔧 데이터 전처리 능력\n",
    "- [ ] 피처 스케일링 (StandardScaler, MinMaxScaler) 적용\n",
    "- [ ] 결측치 처리 및 범주형 변수 인코딩\n",
    "- [ ] 데이터 누수 방지를 위한 전처리 순서 이해\n",
    "- [ ] Pipeline을 활용한 전처리 자동화\n",
    "\n",
    "#### 📈 실무 프로젝트 능력\n",
    "- [ ] 전체 머신러닝 파이프라인 구축\n",
    "- [ ] 여러 모델의 성능 비교 및 분석\n",
    "- [ ] 과적합/과소적합 문제 진단 및 해결\n",
    "- [ ] 실제 비즈니스 문제에 머신러닝 적용\n",
    "\n",
    "### 🚀 다음 단계 준비 완료\n",
    "- [ ] 딥러닝 학습을 위한 기초 준비\n",
    "- [ ] 신경망 구조와 역전파 이해\n",
    "- [ ] PyTorch 프레임워크 학습 동기 부여\n",
    "\n",
    "## 🎯 이제 할 수 있는 것들\n",
    "\n",
    "### 🚀 즉시 활용 가능한 기술\n",
    "- **실제 예측 모델 구축**: 집값 예측, 고객 이탈 예측, 스팸 메일 분류\n",
    "- **데이터 기반 의사결정**: 시각화를 통한 인사이트 도출 및 비즈니스 분석\n",
    "- **모델 성능 최적화**: 하이퍼파라미터 튜닝, 앙상블 기법 적용\n",
    "- **실무 머신러닝 파이프라인**: 데이터 전처리부터 모델 배포까지 전체 과정\n",
    "\n",
    "### 💼 포트폴리오 프로젝트 아이디어\n",
    "- **부동산 가격 예측 시스템**: 다양한 특성을 활용한 집값 예측 모델\n",
    "- **고객 이탈 예측 대시보드**: 시각화와 머신러닝을 결합한 분석 도구\n",
    "- **신용카드 사기 탐지 시스템**: 이상 탐지 알고리즘 구현\n",
    "- **추천 시스템**: 협업 필터링과 콘텐츠 기반 필터링 결합\n",
    "\n",
    "### 🔬 실무 적용 예시\n",
    "- **금융**: 신용 평가, 리스크 관리, 포트폴리오 최적화\n",
    "- **의료**: 질병 진단, 약물 효과 예측, 환자 결과 예측\n",
    "- **마케팅**: 고객 세분화, 캠페인 효과 예측, 가격 최적화\n",
    "- **제조업**: 품질 관리, 예측 정비, 공정 최적화\n",
    "\n",
    "### 📋 캡스톤 프로젝트 완료도\n",
    "- [ ] 모델 성능 비교 실험 수행\n",
    "- [ ] Pipeline을 활용한 전처리 자동화\n",
    "- [ ] 결과 분석 및 보고서 작성\n",
    "- [ ] 실무 적용 가능한 인사이트 도출\n",
    "\n",
    "> **💡 체크리스트 완료 후**: \n",
    "> 80% 이상 완료했다면 다음 파트(Part 7: 딥러닝)로 진행하세요!\n",
    "> 미완료 항목이 있다면 해당 섹션을 다시 학습하고 실습해보세요.\n",
    "\n",
    "---\n",
    "\n",
    "**⬅️ 이전 시간: [Part 5.6: 머신러닝/딥러닝을 위한 미적분](../05.6_calculus_for_ml/part_5.6_calculus_for_ml.md)**\n",
    "**➡️ 다음 시간: [Part 7: 딥러닝 기초와 PyTorch](../07_deep_learning/part_7_deep_learning.md)**\n"
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 5
}
