{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "50b46a36-4330-4868-a1d9-ba8db4209eea",
   "metadata": {},
   "source": [
    "# Preprocessing \n",
    "\n",
    "In this notebook, we prepare the UCI Student Performance dataset for Machine Learning.\n",
    "We will:\n",
    "- Identify numerical and categorical features\n",
    "- Encode categorical variables\n",
    "- Normalize numeric data \n",
    "- Create target variables for regression & classification\n",
    "- Split the data into train/test sets\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "a324a8c7-2ff3-4189-b6e8-d1b7ad7d6705",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.preprocessing import StandardScaler\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "985258ee-a301-482d-ba56-0e4f75876261",
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.read_csv(\"../data/raw/student_performance_full.csv\",sep=\";\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "500db2ef-ea72-4cbc-9d83-da0af17064e2",
   "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>school</th>\n",
       "      <th>sex</th>\n",
       "      <th>age</th>\n",
       "      <th>address</th>\n",
       "      <th>famsize</th>\n",
       "      <th>Pstatus</th>\n",
       "      <th>Medu</th>\n",
       "      <th>Fedu</th>\n",
       "      <th>Mjob</th>\n",
       "      <th>Fjob</th>\n",
       "      <th>...</th>\n",
       "      <th>famrel</th>\n",
       "      <th>freetime</th>\n",
       "      <th>goout</th>\n",
       "      <th>Dalc</th>\n",
       "      <th>Walc</th>\n",
       "      <th>health</th>\n",
       "      <th>absences</th>\n",
       "      <th>G1</th>\n",
       "      <th>G2</th>\n",
       "      <th>G3</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>GP</td>\n",
       "      <td>F</td>\n",
       "      <td>18</td>\n",
       "      <td>U</td>\n",
       "      <td>GT3</td>\n",
       "      <td>A</td>\n",
       "      <td>4</td>\n",
       "      <td>4</td>\n",
       "      <td>at_home</td>\n",
       "      <td>teacher</td>\n",
       "      <td>...</td>\n",
       "      <td>4</td>\n",
       "      <td>3</td>\n",
       "      <td>4</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>4</td>\n",
       "      <td>0</td>\n",
       "      <td>11</td>\n",
       "      <td>11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>GP</td>\n",
       "      <td>F</td>\n",
       "      <td>17</td>\n",
       "      <td>U</td>\n",
       "      <td>GT3</td>\n",
       "      <td>T</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>at_home</td>\n",
       "      <td>other</td>\n",
       "      <td>...</td>\n",
       "      <td>5</td>\n",
       "      <td>3</td>\n",
       "      <td>3</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>2</td>\n",
       "      <td>9</td>\n",
       "      <td>11</td>\n",
       "      <td>11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>GP</td>\n",
       "      <td>F</td>\n",
       "      <td>15</td>\n",
       "      <td>U</td>\n",
       "      <td>LE3</td>\n",
       "      <td>T</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>at_home</td>\n",
       "      <td>other</td>\n",
       "      <td>...</td>\n",
       "      <td>4</td>\n",
       "      <td>3</td>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "      <td>3</td>\n",
       "      <td>3</td>\n",
       "      <td>6</td>\n",
       "      <td>12</td>\n",
       "      <td>13</td>\n",
       "      <td>12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>GP</td>\n",
       "      <td>F</td>\n",
       "      <td>15</td>\n",
       "      <td>U</td>\n",
       "      <td>GT3</td>\n",
       "      <td>T</td>\n",
       "      <td>4</td>\n",
       "      <td>2</td>\n",
       "      <td>health</td>\n",
       "      <td>services</td>\n",
       "      <td>...</td>\n",
       "      <td>3</td>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>5</td>\n",
       "      <td>0</td>\n",
       "      <td>14</td>\n",
       "      <td>14</td>\n",
       "      <td>14</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>GP</td>\n",
       "      <td>F</td>\n",
       "      <td>16</td>\n",
       "      <td>U</td>\n",
       "      <td>GT3</td>\n",
       "      <td>T</td>\n",
       "      <td>3</td>\n",
       "      <td>3</td>\n",
       "      <td>other</td>\n",
       "      <td>other</td>\n",
       "      <td>...</td>\n",
       "      <td>4</td>\n",
       "      <td>3</td>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>5</td>\n",
       "      <td>0</td>\n",
       "      <td>11</td>\n",
       "      <td>13</td>\n",
       "      <td>13</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 33 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "  school sex  age address famsize Pstatus  Medu  Fedu     Mjob      Fjob  ...  \\\n",
       "0     GP   F   18       U     GT3       A     4     4  at_home   teacher  ...   \n",
       "1     GP   F   17       U     GT3       T     1     1  at_home     other  ...   \n",
       "2     GP   F   15       U     LE3       T     1     1  at_home     other  ...   \n",
       "3     GP   F   15       U     GT3       T     4     2   health  services  ...   \n",
       "4     GP   F   16       U     GT3       T     3     3    other     other  ...   \n",
       "\n",
       "  famrel freetime  goout  Dalc  Walc health absences  G1  G2  G3  \n",
       "0      4        3      4     1     1      3        4   0  11  11  \n",
       "1      5        3      3     1     1      3        2   9  11  11  \n",
       "2      4        3      2     2     3      3        6  12  13  12  \n",
       "3      3        2      2     1     1      5        0  14  14  14  \n",
       "4      4        3      2     1     2      5        0  11  13  13  \n",
       "\n",
       "[5 rows x 33 columns]"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8038a066-c814-43fe-a6ef-f33654c1d284",
   "metadata": {},
   "source": [
    "Identify numerical and categorical features"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "789e4891-9bdb-4b35-afeb-dcef4a600457",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(Index(['age', 'Medu', 'Fedu', 'traveltime', 'studytime', 'failures', 'famrel',\n",
       "        'freetime', 'goout', 'Dalc', 'Walc', 'health', 'absences', 'G1', 'G2',\n",
       "        'G3'],\n",
       "       dtype='object'),\n",
       " Index(['school', 'sex', 'address', 'famsize', 'Pstatus', 'Mjob', 'Fjob',\n",
       "        'reason', 'guardian', 'schoolsup', 'famsup', 'paid', 'activities',\n",
       "        'nursery', 'higher', 'internet', 'romantic'],\n",
       "       dtype='object'))"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "numeric_cols = df.select_dtypes(include=['int64', 'float64']).columns\n",
    "categorical_cols = df.select_dtypes(include=['object']).columns\n",
    "numeric_cols, categorical_cols"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9ddb34a2-26da-4b60-96b2-bafc14e966a2",
   "metadata": {},
   "source": [
    "Explore Unique Values of Categorical Columns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "0feda451-928d-4e67-a68d-5f5f171f2587",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "school : ['GP' 'MS']\n",
      "sex : ['F' 'M']\n",
      "address : ['U' 'R']\n",
      "famsize : ['GT3' 'LE3']\n",
      "Pstatus : ['A' 'T']\n",
      "Mjob : ['at_home' 'health' 'other' 'services' 'teacher']\n",
      "Fjob : ['teacher' 'other' 'services' 'health' 'at_home']\n",
      "reason : ['course' 'other' 'home' 'reputation']\n",
      "guardian : ['mother' 'father' 'other']\n",
      "schoolsup : ['yes' 'no']\n",
      "famsup : ['no' 'yes']\n",
      "paid : ['no' 'yes']\n",
      "activities : ['no' 'yes']\n",
      "nursery : ['yes' 'no']\n",
      "higher : ['yes' 'no']\n",
      "internet : ['no' 'yes']\n",
      "romantic : ['no' 'yes']\n"
     ]
    }
   ],
   "source": [
    "for col in categorical_cols:\n",
    "    print(col, \":\", df[col].unique())\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2fdfe90f-fb25-42a7-9443-672099faf3d2",
   "metadata": {},
   "source": [
    "One-Hot Encoding"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "1c1a2a4f-a8f9-489a-ad7c-e56d695c632e",
   "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>age</th>\n",
       "      <th>Medu</th>\n",
       "      <th>Fedu</th>\n",
       "      <th>traveltime</th>\n",
       "      <th>studytime</th>\n",
       "      <th>failures</th>\n",
       "      <th>famrel</th>\n",
       "      <th>freetime</th>\n",
       "      <th>goout</th>\n",
       "      <th>Dalc</th>\n",
       "      <th>...</th>\n",
       "      <th>guardian_mother</th>\n",
       "      <th>guardian_other</th>\n",
       "      <th>schoolsup_yes</th>\n",
       "      <th>famsup_yes</th>\n",
       "      <th>paid_yes</th>\n",
       "      <th>activities_yes</th>\n",
       "      <th>nursery_yes</th>\n",
       "      <th>higher_yes</th>\n",
       "      <th>internet_yes</th>\n",
       "      <th>romantic_yes</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>18</td>\n",
       "      <td>4</td>\n",
       "      <td>4</td>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>4</td>\n",
       "      <td>3</td>\n",
       "      <td>4</td>\n",
       "      <td>1</td>\n",
       "      <td>...</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>17</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>5</td>\n",
       "      <td>3</td>\n",
       "      <td>3</td>\n",
       "      <td>1</td>\n",
       "      <td>...</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>15</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>4</td>\n",
       "      <td>3</td>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "      <td>...</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>15</td>\n",
       "      <td>4</td>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>0</td>\n",
       "      <td>3</td>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "      <td>...</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>16</td>\n",
       "      <td>3</td>\n",
       "      <td>3</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>4</td>\n",
       "      <td>3</td>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "      <td>...</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 42 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "   age  Medu  Fedu  traveltime  studytime  failures  famrel  freetime  goout  \\\n",
       "0   18     4     4           2          2         0       4         3      4   \n",
       "1   17     1     1           1          2         0       5         3      3   \n",
       "2   15     1     1           1          2         0       4         3      2   \n",
       "3   15     4     2           1          3         0       3         2      2   \n",
       "4   16     3     3           1          2         0       4         3      2   \n",
       "\n",
       "   Dalc  ...  guardian_mother  guardian_other  schoolsup_yes  famsup_yes  \\\n",
       "0     1  ...             True           False           True       False   \n",
       "1     1  ...            False           False          False        True   \n",
       "2     2  ...             True           False           True       False   \n",
       "3     1  ...             True           False          False        True   \n",
       "4     1  ...            False           False          False        True   \n",
       "\n",
       "   paid_yes  activities_yes  nursery_yes  higher_yes  internet_yes  \\\n",
       "0     False           False         True        True         False   \n",
       "1     False           False        False        True          True   \n",
       "2     False           False         True        True          True   \n",
       "3     False            True         True        True          True   \n",
       "4     False           False         True        True         False   \n",
       "\n",
       "   romantic_yes  \n",
       "0         False  \n",
       "1         False  \n",
       "2         False  \n",
       "3          True  \n",
       "4         False  \n",
       "\n",
       "[5 rows x 42 columns]"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_encoded = pd.get_dummies(df, columns=categorical_cols, drop_first=True)\n",
    "df_encoded.head()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eaadae83-76fe-4e49-9b42-170b1d6fe255",
   "metadata": {},
   "source": [
    "Normalize Numeric Features"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "5e2c0b1e-bdca-459b-b2a7-de9d36e14f52",
   "metadata": {},
   "outputs": [],
   "source": [
    "scaler = StandardScaler()\n",
    "df_scaled = df_encoded.copy()\n",
    "\n",
    "num_features = df_scaled.select_dtypes(include=['int64', 'float64']).columns\n",
    "df_scaled[num_features] = scaler.fit_transform(df_scaled[num_features])\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d76079b2-7ee1-497f-9a55-8a9eb5699374",
   "metadata": {},
   "source": [
    "Create the Regression Target"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "20d7b91d-dd80-4138-8707-da21a91cd4ca",
   "metadata": {},
   "outputs": [],
   "source": [
    "target_reg = \"G3\"\n",
    "X_reg = df_scaled.drop(columns=[\"G3\"])\n",
    "y_reg = df_scaled[\"G3\"]\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2a161f4c-f000-469a-9709-ba69aebbfab4",
   "metadata": {},
   "source": [
    "Create Classification Target (risk / medium / good)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a459e55b-dd5d-464b-9450-69cbedab1c52",
   "metadata": {},
   "source": [
    "We convert the final grade (G3) into 3 categories:\n",
    "\n",
    "- 0–9   → risk\n",
    "- 10–14 → medium\n",
    "- 15–20 → good\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "9e823344-4084-46f0-b730-8d480c302e29",
   "metadata": {},
   "outputs": [],
   "source": [
    "def categorize_grade(g):\n",
    "    if g < 10:\n",
    "        return \"risk\"\n",
    "    elif g < 15:\n",
    "        return \"medium\"\n",
    "    else:\n",
    "        return \"good\"\n",
    "\n",
    "df_encoded[\"G3_category\"] = df[\"G3\"].apply(categorize_grade)\n",
    "\n",
    "X_clf = df_encoded.drop(columns=[\"G3\", \"G3_category\"])\n",
    "y_clf = df_encoded[\"G3_category\"]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "9a63651e-12fe-44f1-baf3-2dd9c990953e",
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train_reg, X_test_reg, y_train_reg, y_test_reg = train_test_split(\n",
    "    X_reg, y_reg, test_size=0.2, random_state=42\n",
    ")\n",
    "\n",
    "X_train_clf, X_test_clf, y_train_clf, y_test_clf = train_test_split(\n",
    "    X_clf, y_clf, test_size=0.2, random_state=42\n",
    ")\n"
   ]
  }
 ],
 "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.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
