{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "58cf60d5-781f-4972-a394-6e6647d1ce93",
   "metadata": {},
   "source": [
    "## 타이타닉 데이터 세트 컬럼 설명\n",
    "\n",
    "* **pclass** (Passenger Class)\n",
    "  * 승객의 티켓 등급입니다. 1등석(1), 2등석(2), 3등석(3)으로 구분되며, 당시의 사회적·경제적 지위를 나타냅니다.\n",
    "\n",
    "* **survived**\n",
    "  * 생존 여부입니다. 생존자는 `1`, 사망자는 `0`으로 표시됩니다. 예측 모델에서 정답에 해당하는 변수입니다.\n",
    "\n",
    "* **name**\n",
    "  * 승객의 이름입니다. 성과 이름, 그리고 Miss, Mr, Master 같은 호칭이 함께 포함되어 있습니다.\n",
    "\n",
    "* **sex**\n",
    "  * 승객의 성별입니다. `female`(여성)과 `male`(남성)로 구분됩니다.\n",
    "\n",
    "* **age**\n",
    "  * 승객의 나이입니다. 1세 미만의 영유아는 소수점으로 표시되어 있습니다.\n",
    "\n",
    "* **sibsp** (Siblings / Spouses)\n",
    "  * 함께 탑승한 형제자매, 자매, 또는 배우자의 총 명수입니다.\n",
    "\n",
    "* **parch** (Parents / Children)\n",
    "  * 함께 탑승한 부모 또는 자녀의 총 명수입니다.\n",
    "\n",
    "* **ticket**\n",
    "  * 티켓의 고유 번호입니다.\n",
    "\n",
    "* **fare**\n",
    "  * 탑승 요금입니다. 당시에 지불한 영국 파운드 기준의 금액입니다.\n",
    "\n",
    "* **cabin**\n",
    "  * 객실 번호입니다. 선실의 위치를 나타내며, 누락된 값(NaN)이 많은 편입니다.\n",
    "\n",
    "* **embarked**\n",
    "  * 승선한 항구의 이름입니다. 앞 글자만 따서 표시됩니다.\n",
    "    * **S**: 사우샘프턴 (Southampton)\n",
    "    * **C**: 셰르부르 (Cherbourg)\n",
    "    * **Q**: 퀸즈타운 (Queenstown)\n",
    "\n",
    "* **boat**\n",
    "  * 생존자가 탑승했던 구조 보트의 번호입니다. (사망자나 보트를 타지 못한 경우 NaN으로 표시됩니다.)\n",
    "\n",
    "* **body**\n",
    "  * 사망자 중 시신을 수습한 경우에 부여된 시신 번호입니다.\n",
    "\n",
    "* **home.dest**\n",
    "  * 승객의 거주지와 향후 목적지 정보입니다."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "af5047fa-95fe-4a0c-9358-bdc89d91cee0",
   "metadata": {},
   "source": [
    "`train_test_split()` 이용"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "5964bfec-f18a-4ec6-82c8-1dc27cb75d43",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "from sklearn.metrics import accuracy_score, classification_report\n",
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "# 1. 데이터 불러오기\n",
    "df = pd.read_excel(\"data/titanic.xls\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "70253db4-80d0-4378-abb3-c876cd35771d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>pclass</th>\n",
       "      <th>survived</th>\n",
       "      <th>name</th>\n",
       "      <th>sex</th>\n",
       "      <th>age</th>\n",
       "      <th>sibsp</th>\n",
       "      <th>parch</th>\n",
       "      <th>ticket</th>\n",
       "      <th>fare</th>\n",
       "      <th>cabin</th>\n",
       "      <th>embarked</th>\n",
       "      <th>boat</th>\n",
       "      <th>body</th>\n",
       "      <th>home.dest</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>Allen, Miss. Elisabeth Walton</td>\n",
       "      <td>female</td>\n",
       "      <td>29.0000</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>24160</td>\n",
       "      <td>211.3375</td>\n",
       "      <td>B5</td>\n",
       "      <td>S</td>\n",
       "      <td>2</td>\n",
       "      <td>NaN</td>\n",
       "      <td>St Louis, MO</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>Allison, Master. Hudson Trevor</td>\n",
       "      <td>male</td>\n",
       "      <td>0.9167</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>113781</td>\n",
       "      <td>151.5500</td>\n",
       "      <td>C22 C26</td>\n",
       "      <td>S</td>\n",
       "      <td>11</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Montreal, PQ / Chesterville, ON</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>Allison, Miss. Helen Loraine</td>\n",
       "      <td>female</td>\n",
       "      <td>2.0000</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>113781</td>\n",
       "      <td>151.5500</td>\n",
       "      <td>C22 C26</td>\n",
       "      <td>S</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Montreal, PQ / Chesterville, ON</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>Allison, Mr. Hudson Joshua Creighton</td>\n",
       "      <td>male</td>\n",
       "      <td>30.0000</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>113781</td>\n",
       "      <td>151.5500</td>\n",
       "      <td>C22 C26</td>\n",
       "      <td>S</td>\n",
       "      <td>NaN</td>\n",
       "      <td>135.0</td>\n",
       "      <td>Montreal, PQ / Chesterville, ON</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>Allison, Mrs. Hudson J C (Bessie Waldo Daniels)</td>\n",
       "      <td>female</td>\n",
       "      <td>25.0000</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>113781</td>\n",
       "      <td>151.5500</td>\n",
       "      <td>C22 C26</td>\n",
       "      <td>S</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Montreal, PQ / Chesterville, ON</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   pclass  survived                                             name     sex  \\\n",
       "0       1         1                    Allen, Miss. Elisabeth Walton  female   \n",
       "1       1         1                   Allison, Master. Hudson Trevor    male   \n",
       "2       1         0                     Allison, Miss. Helen Loraine  female   \n",
       "3       1         0             Allison, Mr. Hudson Joshua Creighton    male   \n",
       "4       1         0  Allison, Mrs. Hudson J C (Bessie Waldo Daniels)  female   \n",
       "\n",
       "       age  sibsp  parch  ticket      fare    cabin embarked boat   body  \\\n",
       "0  29.0000      0      0   24160  211.3375       B5        S    2    NaN   \n",
       "1   0.9167      1      2  113781  151.5500  C22 C26        S   11    NaN   \n",
       "2   2.0000      1      2  113781  151.5500  C22 C26        S  NaN    NaN   \n",
       "3  30.0000      1      2  113781  151.5500  C22 C26        S  NaN  135.0   \n",
       "4  25.0000      1      2  113781  151.5500  C22 C26        S  NaN    NaN   \n",
       "\n",
       "                         home.dest  \n",
       "0                     St Louis, MO  \n",
       "1  Montreal, PQ / Chesterville, ON  \n",
       "2  Montreal, PQ / Chesterville, ON  \n",
       "3  Montreal, PQ / Chesterville, ON  \n",
       "4  Montreal, PQ / Chesterville, ON  "
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "fe6a588a-0b03-46e7-8bea-f409f71ea406",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.DataFrame'>\n",
      "RangeIndex: 1309 entries, 0 to 1308\n",
      "Data columns (total 14 columns):\n",
      " #   Column     Non-Null Count  Dtype  \n",
      "---  ------     --------------  -----  \n",
      " 0   pclass     1309 non-null   int64  \n",
      " 1   survived   1309 non-null   int64  \n",
      " 2   name       1309 non-null   str    \n",
      " 3   sex        1309 non-null   str    \n",
      " 4   age        1046 non-null   float64\n",
      " 5   sibsp      1309 non-null   int64  \n",
      " 6   parch      1309 non-null   int64  \n",
      " 7   ticket     1309 non-null   object \n",
      " 8   fare       1308 non-null   float64\n",
      " 9   cabin      295 non-null    str    \n",
      " 10  embarked   1307 non-null   str    \n",
      " 11  boat       486 non-null    object \n",
      " 12  body       121 non-null    float64\n",
      " 13  home.dest  745 non-null    str    \n",
      "dtypes: float64(3), int64(4), object(2), str(5)\n",
      "memory usage: 143.3+ KB\n"
     ]
    }
   ],
   "source": [
    "df.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "c896f4ec-fbf3-40da-b35b-91d01bae2f0f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 2. 데이터 전처리 (Preprocessing)\n",
    "# 예측에 필요하지 않거나 결측치가 너무 많은 컬럼을 제거합니다.\n",
    "drop_cols = [\"name\", \"ticket\", \"cabin\", \"boat\", \"body\", \"home.dest\"]\n",
    "df = df.drop(drop_cols, axis=1)\n",
    "\n",
    "# 결측치(Missing Value) 처리\n",
    "# 나이(age)와 요금(fare)의 빈 곳은 각 컬럼의 평균값으로 채웁니다.\n",
    "df[\"age\"] = df[\"age\"].fillna(df[\"age\"].mean())\n",
    "df[\"fare\"] = df[\"fare\"].fillna(df[\"fare\"].mean())\n",
    "\n",
    "# 탑승 항구(embarked)의 빈 곳은 가장 빈도가 높은 'S'로 채웁니다.\n",
    "df[\"embarked\"] = df[\"embarked\"].fillna(\"S\")\n",
    "\n",
    "# 범주형(Categorical) 데이터 변환\n",
    "# 성별(sex)과 탑승 항구(embarked)를 0과 1의 독립된 변수로 변환합니다.\n",
    "df = pd.get_dummies(df, columns=[\"sex\", \"embarked\"], drop_first=True)\n",
    "\n",
    "# 3. 데이터 분할\n",
    "# 예측 대상인 survived를 y로, 나머지 특징들을 X로 설정합니다.\n",
    "X = df.drop(\"survived\", axis=1)\n",
    "y = df[\"survived\"]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "50c1d4c3-e994-4a61-b9ca-09be7ea1b9b9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>pclass</th>\n",
       "      <th>survived</th>\n",
       "      <th>age</th>\n",
       "      <th>sibsp</th>\n",
       "      <th>parch</th>\n",
       "      <th>fare</th>\n",
       "      <th>sex_male</th>\n",
       "      <th>embarked_Q</th>\n",
       "      <th>embarked_S</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>29.0000</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>211.3375</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0.9167</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>151.5500</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>2.0000</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>151.5500</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>30.0000</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>151.5500</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>25.0000</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>151.5500</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   pclass  survived      age  sibsp  parch      fare  sex_male  embarked_Q  \\\n",
       "0       1         1  29.0000      0      0  211.3375     False       False   \n",
       "1       1         1   0.9167      1      2  151.5500      True       False   \n",
       "2       1         0   2.0000      1      2  151.5500     False       False   \n",
       "3       1         0  30.0000      1      2  151.5500      True       False   \n",
       "4       1         0  25.0000      1      2  151.5500     False       False   \n",
       "\n",
       "   embarked_S  \n",
       "0        True  \n",
       "1        True  \n",
       "2        True  \n",
       "3        True  \n",
       "4        True  "
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "dff2673a-50ae-4bfe-bd0c-7550e7cee470",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "모델 정확도(Accuracy): 0.7748\n",
      "\n",
      "[상세 평가지표 수치]\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.75      0.88      0.81       144\n",
      "           1       0.82      0.64      0.72       118\n",
      "\n",
      "    accuracy                           0.77       262\n",
      "   macro avg       0.78      0.76      0.77       262\n",
      "weighted avg       0.78      0.77      0.77       262\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# 전체 데이터를 학습용과 검증용으로 8:2 비율로 나눕니다.\n",
    "X_train, X_test, y_train, y_test = train_test_split(\n",
    "    X, y, test_size=0.2, random_state=42\n",
    ")\n",
    "\n",
    "# 4. 로지스틱 회귀(Logistic Regression) 모델 학습\n",
    "model = LogisticRegression(max_iter=1000)\n",
    "model.fit(X_train, y_train)\n",
    "\n",
    "# 5. 모델 평가\n",
    "y_pred = model.predict(X_test)\n",
    "\n",
    "# 결과 출력\n",
    "accuracy = accuracy_score(y_test, y_pred)\n",
    "print(f\"모델 정확도(Accuracy): {accuracy:.4f}\")\n",
    "print(\"\\n[상세 평가지표 수치]\")\n",
    "print(classification_report(y_test, y_pred))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fa4af44e-c385-42e3-9de8-d90a45e47b58",
   "metadata": {},
   "source": [
    "`cross_val_score()` 이용"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "131ad46c-5a1d-4302-8795-1eab70d1b9b0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[5분할 교차 검증별 정확도]\n",
      "1번째 폴드 정확도: 0.5420\n",
      "2번째 폴드 정확도: 0.8550\n",
      "3번째 폴드 정확도: 0.8168\n",
      "4번째 폴드 정확도: 0.7328\n",
      "5번째 폴드 정확도: 0.6705\n",
      "\n",
      "--- 최종 평가 결과 ---\n",
      "평균 정확도(Mean Accuracy): 0.7234\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "# 교차 검증을 위한 라이브러리 추가\n",
    "from sklearn.model_selection import cross_val_score\n",
    "\n",
    "# 1. 데이터 불러오기\n",
    "df = pd.read_excel(\"data/titanic.xls\")\n",
    "\n",
    "# 2. 데이터 전처리 (Preprocessing)\n",
    "drop_cols = [\"name\", \"ticket\", \"cabin\", \"boat\", \"body\", \"home.dest\"]\n",
    "df = df.drop(drop_cols, axis=1)\n",
    "\n",
    "# 결측치(Missing Value) 처리\n",
    "df[\"age\"] = df[\"age\"].fillna(df[\"age\"].mean())\n",
    "df[\"fare\"] = df[\"fare\"].fillna(df[\"fare\"].mean())\n",
    "df[\"embarked\"] = df[\"embarked\"].fillna(\"S\")\n",
    "\n",
    "# 범주형(Categorical) 데이터 변환\n",
    "df = pd.get_dummies(df, columns=[\"sex\", \"embarked\"], drop_first=True)\n",
    "\n",
    "# 3. 데이터 설정\n",
    "# 교차 검증 함수가 내부에서 데이터를 나누므로 train_test_split은 제외합니다.\n",
    "X = df.drop(\"survived\", axis=1)\n",
    "y = df[\"survived\"]\n",
    "\n",
    "# 4. 로지스틱 회귀(Logistic Regression) 모델 정의\n",
    "model = LogisticRegression(max_iter=1000)\n",
    "\n",
    "# 5. 교차 검증 수행\n",
    "# cv=5 설정을 통해 데이터를 5개로 나누어 모델 성능을 평가합니다.\n",
    "scores = cross_val_score(model, X, y, cv=5, scoring=\"accuracy\")\n",
    "\n",
    "# 6. 결과 출력\n",
    "print(\"[5분할 교차 검증별 정확도]\")\n",
    "for i, score in enumerate(scores, 1):\n",
    "    print(f\"{i}번째 폴드 정확도: {score:.4f}\")\n",
    "\n",
    "print(\"\\n--- 최종 평가 결과 ---\")\n",
    "print(f\"평균 정확도(Mean Accuracy): {np.mean(scores):.4f}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "7def3d9d-5fe2-40c7-9eab-e8751c76c579",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[5분할 교차 검증별 정확도]\n",
      "1번째 폴드 정확도: 0.5382\n",
      "2번째 폴드 정확도: 0.8550\n",
      "3번째 폴드 정확도: 0.8168\n",
      "4번째 폴드 정확도: 0.7290\n",
      "5번째 폴드 정확도: 0.6743\n",
      "\n",
      "--- 최종 평가 결과 ---\n",
      "평균 정확도(Mean Accuracy): 0.7227\n",
      "정확도 표준편차(Std Dev): 0.1121\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "# 교차 검증 및 파이프라인 라이브러리 추가\n",
    "from sklearn.model_selection import cross_val_score\n",
    "from sklearn.pipeline import make_pipeline\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "# 1. 데이터 불러오기\n",
    "# 지정해주신 경로의 구형 엑셀 파일(.xls)을 읽어옵니다.\n",
    "df = pd.read_excel(\"data/titanic.xls\")\n",
    "\n",
    "# 2. 데이터 전처리 (Preprocessing)\n",
    "# 분석에 부적절하거나 불필요한 컬럼 제거\n",
    "drop_cols = [\"name\", \"ticket\", \"cabin\", \"boat\", \"body\", \"home.dest\"]\n",
    "df = df.drop(drop_cols, axis=1)\n",
    "\n",
    "# 결측치(Missing Value) 처리\n",
    "df[\"age\"] = df[\"age\"].fillna(df[\"age\"].mean())\n",
    "df[\"fare\"] = df[\"fare\"].fillna(df[\"fare\"].mean())\n",
    "df[\"embarked\"] = df[\"embarked\"].fillna(\"S\")\n",
    "\n",
    "# 범주형(Categorical) 데이터 변환 (원-핫 인코딩)\n",
    "df = pd.get_dummies(df, columns=[\"sex\", \"embarked\"], drop_first=True)\n",
    "\n",
    "# 3. 데이터 분할\n",
    "# 예측 대상인 survived를 y로, 나머지를 X로 설정합니다.\n",
    "X = df.drop(\"survived\", axis=1)\n",
    "y = df[\"survived\"]\n",
    "\n",
    "# 4. 파이프라인 생성 (스케일러 + 모델)\n",
    "# 교차 검증 시 폴드(Fold)별로 스케일링이 독립적으로 적용되도록 파이프라인을 만듭니다.\n",
    "pipeline = make_pipeline(StandardScaler(), LogisticRegression(max_iter=1000))\n",
    "\n",
    "# 5. 교차 검증(Cross Validation) 수행\n",
    "# cv=5는 데이터를 5개의 구역으로 나누어 5번 교차 검증을 수행한다는 의미입니다.\n",
    "scores = cross_val_score(pipeline, X, y, cv=5, scoring=\"accuracy\")\n",
    "\n",
    "# 6. 결과 출력\n",
    "print(\"[5분할 교차 검증별 정확도]\")\n",
    "for i, score in enumerate(scores, 1):\n",
    "    print(f\"{i}번째 폴드 정확도: {score:.4f}\")\n",
    "\n",
    "print(\"\\n--- 최종 평가 결과 ---\")\n",
    "print(f\"평균 정확도(Mean Accuracy): {np.mean(scores):.4f}\")\n",
    "print(f\"정확도 표준편차(Std Dev): {np.std(scores):.4f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "53b28b79-8197-4726-a0d1-d3917ba3da29",
   "metadata": {},
   "source": [
    "`make_pipeline()`을 이용한 처리"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "7ea6c969-c339-4c7e-a8cb-d8f9a5c03bb5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 1 1 0 1 0 0 0 0 1 0 1 1 1 0 0 0 1 0 0 1\n",
      " 0 1 1 1 0 1 0 0 0 0 1 1 1 1 0 0 1 0 0 0 1 0 1 0 0 1 0 1 1 1 0 0 0 0 0 0 0\n",
      " 0 0 0 1 0 1 0 0 0 0 1 0 0 1 1 1 1 0 1 0 0 0 0 1 0 1 0 0 1 1 0 0 1 0 1 1 0\n",
      " 0 0 1 1 0 0 0 0 1 0 0 0 1 0 0 0 0 1 1 1 1 0 0 0 1 0 0 0 1 0 0 1 1 0 1 0 0\n",
      " 1 0 1 1 0 0 0 0 1 0 0 0 0 1 0 0 1 1 0 1 0 1 1 1 1 1 1 0 1 0 1 0 1 1 0 1 0\n",
      " 1 0 0 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 1 1 0 0 0 1 0\n",
      " 1 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 1 1\n",
      " 1 0 1]\n"
     ]
    }
   ],
   "source": [
    "from sklearn.linear_model import LogisticRegression\n",
    "from sklearn.pipeline import make_pipeline\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "# 파이프라인 정의: 스케일링 후 로지스틱 회귀 실행\n",
    "pipeline = make_pipeline(StandardScaler(), LogisticRegression(max_iter=1000))\n",
    "\n",
    "# 사용법은 단일 모델과 완전히 같습니다.\n",
    "# 1. 학습하기 (내부에서 스케일링 변환과 모델 학습이 연달아 일어남)\n",
    "pipeline.fit(X_train, y_train)\n",
    "\n",
    "# 2. 예측하기 (내부에서 학습 때 사용한 기준대로 테스트 데이터를 자동 변환 후 예측)\n",
    "y_pred = pipeline.predict(X_test)\n",
    "print(y_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1064413d-8fa6-465a-a5bd-6f45f8853276",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.15"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
