{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# AI Numerasi - XGBoost Classifier Training\n",
    "Notebook ini berisi langkah-langkah untuk melatih model Machine Learning menggunakan XGBoost berdasarkan dataset hasil jawaban siswa."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import xgboost as xgb\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.preprocessing import LabelEncoder\n",
    "from sklearn.metrics import classification_report, accuracy_score, confusion_matrix\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "from sklearn.utils.class_weight import compute_sample_weight\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Load Dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "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>student_id</th>\n",
       "      <th>Q1</th>\n",
       "      <th>Q2</th>\n",
       "      <th>Q3</th>\n",
       "      <th>Q4</th>\n",
       "      <th>Q5</th>\n",
       "      <th>Q6</th>\n",
       "      <th>Q7</th>\n",
       "      <th>Q8</th>\n",
       "      <th>Q9</th>\n",
       "      <th>Q10</th>\n",
       "      <th>Q11</th>\n",
       "      <th>Q12</th>\n",
       "      <th>Target_Level</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>STD_0001</td>\n",
       "      <td>1_A</td>\n",
       "      <td>2_C</td>\n",
       "      <td>3_C</td>\n",
       "      <td>4_B</td>\n",
       "      <td>5_A</td>\n",
       "      <td>6_A</td>\n",
       "      <td>7_B</td>\n",
       "      <td>8_B</td>\n",
       "      <td>9_C</td>\n",
       "      <td>10_B</td>\n",
       "      <td>11_B</td>\n",
       "      <td>12_B</td>\n",
       "      <td>NSI</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>STD_0002</td>\n",
       "      <td>1_B</td>\n",
       "      <td>2_C</td>\n",
       "      <td>3_B</td>\n",
       "      <td>4_C</td>\n",
       "      <td>5_C</td>\n",
       "      <td>6_A</td>\n",
       "      <td>7_A</td>\n",
       "      <td>8_C</td>\n",
       "      <td>9_C</td>\n",
       "      <td>10_B</td>\n",
       "      <td>11_A</td>\n",
       "      <td>12_A</td>\n",
       "      <td>Basic</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>STD_0003</td>\n",
       "      <td>1_C</td>\n",
       "      <td>2_A</td>\n",
       "      <td>3_B</td>\n",
       "      <td>4_A</td>\n",
       "      <td>5_B</td>\n",
       "      <td>6_B</td>\n",
       "      <td>7_A</td>\n",
       "      <td>8_B</td>\n",
       "      <td>9_B</td>\n",
       "      <td>10_A</td>\n",
       "      <td>11_B</td>\n",
       "      <td>12_B</td>\n",
       "      <td>Advanced</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>STD_0004</td>\n",
       "      <td>1_B</td>\n",
       "      <td>2_B</td>\n",
       "      <td>3_B</td>\n",
       "      <td>4_C</td>\n",
       "      <td>5_C</td>\n",
       "      <td>6_B</td>\n",
       "      <td>7_B</td>\n",
       "      <td>8_B</td>\n",
       "      <td>9_B</td>\n",
       "      <td>10_B</td>\n",
       "      <td>11_B</td>\n",
       "      <td>12_A</td>\n",
       "      <td>Basic</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>STD_0005</td>\n",
       "      <td>1_C</td>\n",
       "      <td>2_A</td>\n",
       "      <td>3_B</td>\n",
       "      <td>4_C</td>\n",
       "      <td>5_B</td>\n",
       "      <td>6_B</td>\n",
       "      <td>7_B</td>\n",
       "      <td>8_B</td>\n",
       "      <td>9_B</td>\n",
       "      <td>10_A</td>\n",
       "      <td>11_B</td>\n",
       "      <td>12_B</td>\n",
       "      <td>Proficient</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  student_id   Q1   Q2   Q3   Q4   Q5   Q6   Q7   Q8   Q9   Q10   Q11   Q12  \\\n",
       "0   STD_0001  1_A  2_C  3_C  4_B  5_A  6_A  7_B  8_B  9_C  10_B  11_B  12_B   \n",
       "1   STD_0002  1_B  2_C  3_B  4_C  5_C  6_A  7_A  8_C  9_C  10_B  11_A  12_A   \n",
       "2   STD_0003  1_C  2_A  3_B  4_A  5_B  6_B  7_A  8_B  9_B  10_A  11_B  12_B   \n",
       "3   STD_0004  1_B  2_B  3_B  4_C  5_C  6_B  7_B  8_B  9_B  10_B  11_B  12_A   \n",
       "4   STD_0005  1_C  2_A  3_B  4_C  5_B  6_B  7_B  8_B  9_B  10_A  11_B  12_B   \n",
       "\n",
       "  Target_Level  \n",
       "0          NSI  \n",
       "1        Basic  \n",
       "2     Advanced  \n",
       "3        Basic  \n",
       "4   Proficient  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Target_Level\n",
      "Basic         597\n",
      "NSI           519\n",
      "Proficient    234\n",
      "Advanced      150\n",
      "Name: count, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "# Membaca dataset\n",
    "df = pd.read_csv('numeracy_dataset.csv')\n",
    "display(df.head())\n",
    "\n",
    "# Melihat distribusi kelas target\n",
    "print(df['Target_Level'].value_counts())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. Preprocessing Data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Mapping Kelas: {'Advanced': 0, 'Basic': 1, 'NSI': 2, 'Proficient': 3}\n"
     ]
    }
   ],
   "source": [
    "# Buang kolom ID karena tidak relevan untuk prediksi\n",
    "X = df.drop(columns=['student_id', 'Target_Level'])\n",
    "y = df['Target_Level']\n",
    "\n",
    "# Karena fitur Q1-Q12 berisi ID opsi (misal: '1_A', '1_B'), \n",
    "# kita harus mengubahnya menjadi numerik (One-Hot Encoding)\n",
    "X_encoded = pd.get_dummies(X)\n",
    "\n",
    "# Label Encoding untuk Target Y (NSI, Basic, Proficient, Advanced) menjadi angka (0,1,2,3)\n",
    "le = LabelEncoder()\n",
    "y_encoded = le.fit_transform(y)\n",
    "print(\"Mapping Kelas:\", dict(zip(le.classes_, range(len(le.classes_)))))\n",
    "\n",
    "# Split Data 80% Training, 20% Testing\n",
    "X_train, X_test, y_train, y_test = train_test_split(X_encoded, y_encoded, test_size=0.2, random_state=42, stratify=y_encoded)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. XGBoost Model Training"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>#sk-container-id-3 {\n",
       "  /* Definition of color scheme common for light and dark mode */\n",
       "  --sklearn-color-text: #000;\n",
       "  --sklearn-color-text-muted: #666;\n",
       "  --sklearn-color-line: gray;\n",
       "  /* Definition of color scheme for unfitted estimators */\n",
       "  --sklearn-color-unfitted-level-0: #fff5e6;\n",
       "  --sklearn-color-unfitted-level-1: #f6e4d2;\n",
       "  --sklearn-color-unfitted-level-2: #ffe0b3;\n",
       "  --sklearn-color-unfitted-level-3: chocolate;\n",
       "  /* Definition of color scheme for fitted estimators */\n",
       "  --sklearn-color-fitted-level-0: #f0f8ff;\n",
       "  --sklearn-color-fitted-level-1: #d4ebff;\n",
       "  --sklearn-color-fitted-level-2: #b3dbfd;\n",
       "  --sklearn-color-fitted-level-3: cornflowerblue;\n",
       "\n",
       "  /* Specific color for light theme */\n",
       "  --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
       "  --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-icon: #696969;\n",
       "\n",
       "  @media (prefers-color-scheme: dark) {\n",
       "    /* Redefinition of color scheme for dark theme */\n",
       "    --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
       "    --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-icon: #878787;\n",
       "  }\n",
       "}\n",
       "\n",
       "#sk-container-id-3 {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 pre {\n",
       "  padding: 0;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 input.sk-hidden--visually {\n",
       "  border: 0;\n",
       "  clip: rect(1px 1px 1px 1px);\n",
       "  clip: rect(1px, 1px, 1px, 1px);\n",
       "  height: 1px;\n",
       "  margin: -1px;\n",
       "  overflow: hidden;\n",
       "  padding: 0;\n",
       "  position: absolute;\n",
       "  width: 1px;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-dashed-wrapped {\n",
       "  border: 1px dashed var(--sklearn-color-line);\n",
       "  margin: 0 0.4em 0.5em 0.4em;\n",
       "  box-sizing: border-box;\n",
       "  padding-bottom: 0.4em;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-container {\n",
       "  /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
       "     but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
       "     so we also need the `!important` here to be able to override the\n",
       "     default hidden behavior on the sphinx rendered scikit-learn.org.\n",
       "     See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
       "  display: inline-block !important;\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-text-repr-fallback {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       "div.sk-parallel-item,\n",
       "div.sk-serial,\n",
       "div.sk-item {\n",
       "  /* draw centered vertical line to link estimators */\n",
       "  background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
       "  background-size: 2px 100%;\n",
       "  background-repeat: no-repeat;\n",
       "  background-position: center center;\n",
       "}\n",
       "\n",
       "/* Parallel-specific style estimator block */\n",
       "\n",
       "#sk-container-id-3 div.sk-parallel-item::after {\n",
       "  content: \"\";\n",
       "  width: 100%;\n",
       "  border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
       "  flex-grow: 1;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-parallel {\n",
       "  display: flex;\n",
       "  align-items: stretch;\n",
       "  justify-content: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-parallel-item {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-parallel-item:first-child::after {\n",
       "  align-self: flex-end;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-parallel-item:last-child::after {\n",
       "  align-self: flex-start;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-parallel-item:only-child::after {\n",
       "  width: 0;\n",
       "}\n",
       "\n",
       "/* Serial-specific style estimator block */\n",
       "\n",
       "#sk-container-id-3 div.sk-serial {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "  align-items: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  padding-right: 1em;\n",
       "  padding-left: 1em;\n",
       "}\n",
       "\n",
       "\n",
       "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
       "clickable and can be expanded/collapsed.\n",
       "- Pipeline and ColumnTransformer use this feature and define the default style\n",
       "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
       "*/\n",
       "\n",
       "/* Pipeline and ColumnTransformer style (default) */\n",
       "\n",
       "#sk-container-id-3 div.sk-toggleable {\n",
       "  /* Default theme specific background. It is overwritten whether we have a\n",
       "  specific estimator or a Pipeline/ColumnTransformer */\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "/* Toggleable label */\n",
       "#sk-container-id-3 label.sk-toggleable__label {\n",
       "  cursor: pointer;\n",
       "  display: flex;\n",
       "  width: 100%;\n",
       "  margin-bottom: 0;\n",
       "  padding: 0.5em;\n",
       "  box-sizing: border-box;\n",
       "  text-align: center;\n",
       "  align-items: start;\n",
       "  justify-content: space-between;\n",
       "  gap: 0.5em;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 label.sk-toggleable__label .caption {\n",
       "  font-size: 0.6rem;\n",
       "  font-weight: lighter;\n",
       "  color: var(--sklearn-color-text-muted);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 label.sk-toggleable__label-arrow:before {\n",
       "  /* Arrow on the left of the label */\n",
       "  content: \"▸\";\n",
       "  float: left;\n",
       "  margin-right: 0.25em;\n",
       "  color: var(--sklearn-color-icon);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 label.sk-toggleable__label-arrow:hover:before {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "/* Toggleable content - dropdown */\n",
       "\n",
       "#sk-container-id-3 div.sk-toggleable__content {\n",
       "  display: none;\n",
       "  text-align: left;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-toggleable__content.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-toggleable__content pre {\n",
       "  margin: 0.2em;\n",
       "  border-radius: 0.25em;\n",
       "  color: var(--sklearn-color-text);\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-toggleable__content.fitted pre {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
       "  /* Expand drop-down */\n",
       "  display: block;\n",
       "  width: 100%;\n",
       "  overflow: visible;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
       "  content: \"▾\";\n",
       "}\n",
       "\n",
       "/* Pipeline/ColumnTransformer-specific style */\n",
       "\n",
       "#sk-container-id-3 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator-specific style */\n",
       "\n",
       "/* Colorize estimator box */\n",
       "#sk-container-id-3 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-label label.sk-toggleable__label,\n",
       "#sk-container-id-3 div.sk-label label {\n",
       "  /* The background is the default theme color */\n",
       "  color: var(--sklearn-color-text-on-default-background);\n",
       "}\n",
       "\n",
       "/* On hover, darken the color of the background */\n",
       "#sk-container-id-3 div.sk-label:hover label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "/* Label box, darken color on hover, fitted */\n",
       "#sk-container-id-3 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator label */\n",
       "\n",
       "#sk-container-id-3 div.sk-label label {\n",
       "  font-family: monospace;\n",
       "  font-weight: bold;\n",
       "  display: inline-block;\n",
       "  line-height: 1.2em;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-label-container {\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "/* Estimator-specific */\n",
       "#sk-container-id-3 div.sk-estimator {\n",
       "  font-family: monospace;\n",
       "  border: 1px dotted var(--sklearn-color-border-box);\n",
       "  border-radius: 0.25em;\n",
       "  box-sizing: border-box;\n",
       "  margin-bottom: 0.5em;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-estimator.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "/* on hover */\n",
       "#sk-container-id-3 div.sk-estimator:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-estimator.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
       "\n",
       "/* Common style for \"i\" and \"?\" */\n",
       "\n",
       ".sk-estimator-doc-link,\n",
       "a:link.sk-estimator-doc-link,\n",
       "a:visited.sk-estimator-doc-link {\n",
       "  float: right;\n",
       "  font-size: smaller;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1em;\n",
       "  height: 1em;\n",
       "  width: 1em;\n",
       "  text-decoration: none !important;\n",
       "  margin-left: 0.5em;\n",
       "  text-align: center;\n",
       "  /* unfitted */\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted,\n",
       "a:link.sk-estimator-doc-link.fitted,\n",
       "a:visited.sk-estimator-doc-link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "/* Span, style for the box shown on hovering the info icon */\n",
       ".sk-estimator-doc-link span {\n",
       "  display: none;\n",
       "  z-index: 9999;\n",
       "  position: relative;\n",
       "  font-weight: normal;\n",
       "  right: .2ex;\n",
       "  padding: .5ex;\n",
       "  margin: .5ex;\n",
       "  width: min-content;\n",
       "  min-width: 20ex;\n",
       "  max-width: 50ex;\n",
       "  color: var(--sklearn-color-text);\n",
       "  box-shadow: 2pt 2pt 4pt #999;\n",
       "  /* unfitted */\n",
       "  background: var(--sklearn-color-unfitted-level-0);\n",
       "  border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted span {\n",
       "  /* fitted */\n",
       "  background: var(--sklearn-color-fitted-level-0);\n",
       "  border: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link:hover span {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
       "\n",
       "#sk-container-id-3 a.estimator_doc_link {\n",
       "  float: right;\n",
       "  font-size: 1rem;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1rem;\n",
       "  height: 1rem;\n",
       "  width: 1rem;\n",
       "  text-decoration: none;\n",
       "  /* unfitted */\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 a.estimator_doc_link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "#sk-container-id-3 a.estimator_doc_link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 a.estimator_doc_link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".estimator-table summary {\n",
       "    padding: .5rem;\n",
       "    font-family: monospace;\n",
       "    cursor: pointer;\n",
       "}\n",
       "\n",
       ".estimator-table details[open] {\n",
       "    padding-left: 0.1rem;\n",
       "    padding-right: 0.1rem;\n",
       "    padding-bottom: 0.3rem;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table {\n",
       "    margin-left: auto !important;\n",
       "    margin-right: auto !important;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table tr:nth-child(odd) {\n",
       "    background-color: #fff;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table tr:nth-child(even) {\n",
       "    background-color: #f6f6f6;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table tr:hover {\n",
       "    background-color: #e0e0e0;\n",
       "}\n",
       "\n",
       ".estimator-table table td {\n",
       "    border: 1px solid rgba(106, 105, 104, 0.232);\n",
       "}\n",
       "\n",
       ".user-set td {\n",
       "    color:rgb(255, 94, 0);\n",
       "    text-align: left;\n",
       "}\n",
       "\n",
       ".user-set td.value pre {\n",
       "    color:rgb(255, 94, 0) !important;\n",
       "    background-color: transparent !important;\n",
       "}\n",
       "\n",
       ".default td {\n",
       "    color: black;\n",
       "    text-align: left;\n",
       "}\n",
       "\n",
       ".user-set td i,\n",
       ".default td i {\n",
       "    color: black;\n",
       "}\n",
       "\n",
       ".copy-paste-icon {\n",
       "    background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NDggNTEyIj48IS0tIUZvbnQgQXdlc29tZSBGcmVlIDYuNy4yIGJ5IEBmb250YXdlc29tZSAtIGh0dHBzOi8vZm9udGF3ZXNvbWUuY29tIExpY2Vuc2UgLSBodHRwczovL2ZvbnRhd2Vzb21lLmNvbS9saWNlbnNlL2ZyZWUgQ29weXJpZ2h0IDIwMjUgRm9udGljb25zLCBJbmMuLS0+PHBhdGggZD0iTTIwOCAwTDMzMi4xIDBjMTIuNyAwIDI0LjkgNS4xIDMzLjkgMTQuMWw2Ny45IDY3LjljOSA5IDE0LjEgMjEuMiAxNC4xIDMzLjlMNDQ4IDMzNmMwIDI2LjUtMjEuNSA0OC00OCA0OGwtMTkyIDBjLTI2LjUgMC00OC0yMS41LTQ4LTQ4bDAtMjg4YzAtMjYuNSAyMS41LTQ4IDQ4LTQ4ek00OCAxMjhsODAgMCAwIDY0LTY0IDAgMCAyNTYgMTkyIDAgMC0zMiA2NCAwIDAgNDhjMCAyNi41LTIxLjUgNDgtNDggNDhMNDggNTEyYy0yNi41IDAtNDgtMjEuNS00OC00OEwwIDE3NmMwLTI2LjUgMjEuNS00OCA0OC00OHoiLz48L3N2Zz4=);\n",
       "    background-repeat: no-repeat;\n",
       "    background-size: 14px 14px;\n",
       "    background-position: 0;\n",
       "    display: inline-block;\n",
       "    width: 14px;\n",
       "    height: 14px;\n",
       "    cursor: pointer;\n",
       "}\n",
       "</style><body><div id=\"sk-container-id-3\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>XGBClassifier(base_score=None, booster=None, callbacks=None,\n",
       "              colsample_bylevel=None, colsample_bynode=None,\n",
       "              colsample_bytree=None, device=None, early_stopping_rounds=None,\n",
       "              enable_categorical=False, eval_metric=None, feature_types=None,\n",
       "              feature_weights=None, gamma=None, grow_policy=None,\n",
       "              importance_type=None, interaction_constraints=None,\n",
       "              learning_rate=0.05, max_bin=None, max_cat_threshold=None,\n",
       "              max_cat_to_onehot=None, max_delta_step=None, max_depth=4,\n",
       "              max_leaves=None, min_child_weight=None, missing=nan,\n",
       "              monotone_constraints=None, multi_strategy=None, n_estimators=150,\n",
       "              n_jobs=None, num_class=4, ...)</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-3\" type=\"checkbox\" checked><label for=\"sk-estimator-id-3\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>XGBClassifier</div></div><div><a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://xgboost.readthedocs.io/en/release_3.2.0/python/python_api.html#xgboost.XGBClassifier\">?<span>Documentation for XGBClassifier</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></div></label><div class=\"sk-toggleable__content fitted\" data-param-prefix=\"\">\n",
       "        <div class=\"estimator-table\">\n",
       "            <details>\n",
       "                <summary>Parameters</summary>\n",
       "                <table class=\"parameters-table\">\n",
       "                  <tbody>\n",
       "                    \n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('objective',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">objective&nbsp;</td>\n",
       "            <td class=\"value\">&#x27;multi:softprob&#x27;</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('base_score',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">base_score&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('booster',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">booster&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('callbacks',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">callbacks&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('colsample_bylevel',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">colsample_bylevel&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('colsample_bynode',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">colsample_bynode&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('colsample_bytree',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">colsample_bytree&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('device',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">device&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('early_stopping_rounds',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">early_stopping_rounds&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('enable_categorical',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">enable_categorical&nbsp;</td>\n",
       "            <td class=\"value\">False</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('eval_metric',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">eval_metric&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('feature_types',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">feature_types&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('feature_weights',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">feature_weights&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('gamma',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">gamma&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('grow_policy',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">grow_policy&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('importance_type',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">importance_type&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('interaction_constraints',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">interaction_constraints&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('learning_rate',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">learning_rate&nbsp;</td>\n",
       "            <td class=\"value\">0.05</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('max_bin',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">max_bin&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('max_cat_threshold',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">max_cat_threshold&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('max_cat_to_onehot',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">max_cat_to_onehot&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('max_delta_step',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">max_delta_step&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('max_depth',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">max_depth&nbsp;</td>\n",
       "            <td class=\"value\">4</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('max_leaves',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">max_leaves&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('min_child_weight',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">min_child_weight&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('missing',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">missing&nbsp;</td>\n",
       "            <td class=\"value\">nan</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('monotone_constraints',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">monotone_constraints&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('multi_strategy',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">multi_strategy&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('n_estimators',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">n_estimators&nbsp;</td>\n",
       "            <td class=\"value\">150</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('n_jobs',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">n_jobs&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('num_parallel_tree',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">num_parallel_tree&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('random_state',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">random_state&nbsp;</td>\n",
       "            <td class=\"value\">42</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('reg_alpha',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">reg_alpha&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('reg_lambda',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">reg_lambda&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('sampling_method',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">sampling_method&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('scale_pos_weight',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">scale_pos_weight&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('subsample',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">subsample&nbsp;</td>\n",
       "            <td class=\"value\">0.8</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('tree_method',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">tree_method&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('validate_parameters',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">validate_parameters&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('verbosity',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">verbosity&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"user-set\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('num_class',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">num_class&nbsp;</td>\n",
       "            <td class=\"value\">4</td>\n",
       "        </tr>\n",
       "    \n",
       "                  </tbody>\n",
       "                </table>\n",
       "            </details>\n",
       "        </div>\n",
       "    </div></div></div></div></div><script>function copyToClipboard(text, element) {\n",
       "    // Get the parameter prefix from the closest toggleable content\n",
       "    const toggleableContent = element.closest('.sk-toggleable__content');\n",
       "    const paramPrefix = toggleableContent ? toggleableContent.dataset.paramPrefix : '';\n",
       "    const fullParamName = paramPrefix ? `${paramPrefix}${text}` : text;\n",
       "\n",
       "    const originalStyle = element.style;\n",
       "    const computedStyle = window.getComputedStyle(element);\n",
       "    const originalWidth = computedStyle.width;\n",
       "    const originalHTML = element.innerHTML.replace('Copied!', '');\n",
       "\n",
       "    navigator.clipboard.writeText(fullParamName)\n",
       "        .then(() => {\n",
       "            element.style.width = originalWidth;\n",
       "            element.style.color = 'green';\n",
       "            element.innerHTML = \"Copied!\";\n",
       "\n",
       "            setTimeout(() => {\n",
       "                element.innerHTML = originalHTML;\n",
       "                element.style = originalStyle;\n",
       "            }, 2000);\n",
       "        })\n",
       "        .catch(err => {\n",
       "            console.error('Failed to copy:', err);\n",
       "            element.style.color = 'red';\n",
       "            element.innerHTML = \"Failed!\";\n",
       "            setTimeout(() => {\n",
       "                element.innerHTML = originalHTML;\n",
       "                element.style = originalStyle;\n",
       "            }, 2000);\n",
       "        });\n",
       "    return false;\n",
       "}\n",
       "\n",
       "document.querySelectorAll('.fa-regular.fa-copy').forEach(function(element) {\n",
       "    const toggleableContent = element.closest('.sk-toggleable__content');\n",
       "    const paramPrefix = toggleableContent ? toggleableContent.dataset.paramPrefix : '';\n",
       "    const paramName = element.parentElement.nextElementSibling.textContent.trim();\n",
       "    const fullParamName = paramPrefix ? `${paramPrefix}${paramName}` : paramName;\n",
       "\n",
       "    element.setAttribute('title', fullParamName);\n",
       "});\n",
       "</script></body>"
      ],
      "text/plain": [
       "XGBClassifier(base_score=None, booster=None, callbacks=None,\n",
       "              colsample_bylevel=None, colsample_bynode=None,\n",
       "              colsample_bytree=None, device=None, early_stopping_rounds=None,\n",
       "              enable_categorical=False, eval_metric=None, feature_types=None,\n",
       "              feature_weights=None, gamma=None, grow_policy=None,\n",
       "              importance_type=None, interaction_constraints=None,\n",
       "              learning_rate=0.05, max_bin=None, max_cat_threshold=None,\n",
       "              max_cat_to_onehot=None, max_delta_step=None, max_depth=4,\n",
       "              max_leaves=None, min_child_weight=None, missing=nan,\n",
       "              monotone_constraints=None, multi_strategy=None, n_estimators=150,\n",
       "              n_jobs=None, num_class=4, ...)"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Menghitung bobot untuk mengatasi ketimpangan data (Class Imbalance)\n",
    "sample_weights = compute_sample_weight(\n",
    "    class_weight='balanced', \n",
    "    y=y_train\n",
    ")\n",
    "\n",
    "# Setup XGBoost Classifier dengan hyperparameter standar untuk klasifikasi Tabular ringan\n",
    "model = xgb.XGBClassifier(\n",
    "    objective='multi:softprob',\n",
    "    num_class=4,\n",
    "    learning_rate=0.05,\n",
    "    max_depth=4,\n",
    "    n_estimators=150,\n",
    "    subsample=0.8,\n",
    "    random_state=42\n",
    ")\n",
    "\n",
    "# Proses Training dengan memberikan perhatian ekstra (weight) pada kelas minoritas seperti Advanced\n",
    "model.fit(X_train, y_train, sample_weight=sample_weights)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. Evaluasi Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Akurasi: 0.8266666666666667\n",
      "\n",
      "Laporan Detail:\n",
      "               precision    recall  f1-score   support\n",
      "\n",
      "    Advanced       0.66      0.70      0.68        30\n",
      "       Basic       0.87      0.87      0.87       119\n",
      "         NSI       0.94      0.88      0.91       104\n",
      "  Proficient       0.63      0.68      0.65        47\n",
      "\n",
      "    accuracy                           0.83       300\n",
      "   macro avg       0.77      0.78      0.78       300\n",
      "weighted avg       0.83      0.83      0.83       300\n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 600x500 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Lakukan prediksi\n",
    "y_pred = model.predict(X_test)\n",
    "\n",
    "# Tampilkan Classification Report\n",
    "print(\"Akurasi:\", accuracy_score(y_test, y_pred))\n",
    "print(\"\\nLaporan Detail:\\n\", classification_report(y_test, y_pred, target_names=le.classes_))\n",
    "\n",
    "# Tampilkan Confusion Matrix\n",
    "cm = confusion_matrix(y_test, y_pred)\n",
    "plt.figure(figsize=(6,5))\n",
    "sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=le.classes_, yticklabels=le.classes_)\n",
    "plt.ylabel('Actual')\n",
    "plt.xlabel('Predicted')\n",
    "plt.title('Confusion Matrix')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5. Simpan Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model XGBoost berhasil disimpan sebagai 'xgboost_numerasi.json'\n"
     ]
    }
   ],
   "source": [
    "# Ekspor model ke file JSON agar bisa di-load oleh API / Microservice\n",
    "model.save_model('xgboost_numerasi.json')\n",
    "print(\"Model XGBoost berhasil disimpan sebagai 'xgboost_numerasi.json'\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "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.10.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
