{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "id": "HF38BRsWNIOk"
      },
      "outputs": [],
      "source": [
        "# Abdullah Al-Mardi ID#242000982\n",
        "# Import libraries\n",
        "import pandas as pd\n",
        "import numpy as np\n",
        "from sklearn.model_selection import train_test_split, GridSearchCV\n",
        "from sklearn.ensemble import RandomForestClassifier\n",
        "from sklearn.linear_model import LogisticRegression\n",
        "from sklearn.metrics import classification_report\n",
        "from sklearn.svm import SVC\n",
        "from sklearn.metrics import classification_report, accuracy_score, precision_score, recall_score, f1_score, confusion_matrix\n",
        "import seaborn as sns\n",
        "from sklearn.feature_selection import SelectKBest, chi2, RFE\n",
        "import matplotlib.pyplot as plt"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "id": "XO0XFsHqNPUq"
      },
      "outputs": [],
      "source": [
        "# Load your dataset (replace 'your_dataset.csv' with the correct path)\n",
        "diabetes_data = pd.read_csv('/content/diabetes_with_missing_values.csv')"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# New Section"
      ],
      "metadata": {
        "id": "4SRInj0agx2X"
      }
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 206
        },
        "id": "YxJFO6Ow69gX",
        "outputId": "9c8f7dbc-38b5-4a71-f9a9-2d2d906d84f8"
      },
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "   Pregnancies  Glucose  BloodPressure  SkinThickness  Insulin   BMI  \\\n",
              "0            6    148.0           72.0           35.0      0.0  33.6   \n",
              "1            1     85.0           66.0           29.0      0.0  26.6   \n",
              "2            8    183.0           64.0            0.0      0.0  23.3   \n",
              "3            1     89.0           66.0            NaN     94.0  28.1   \n",
              "4            0    137.0           40.0           35.0    168.0  43.1   \n",
              "\n",
              "   DiabetesPedigreeFunction  Age  Outcome  \n",
              "0                     0.627   50        1  \n",
              "1                     0.351   31        0  \n",
              "2                     0.672   32        1  \n",
              "3                     0.167   21        0  \n",
              "4                     2.288   33        1  "
            ],
            "text/html": [
              "\n",
              "  <div id=\"df-407a0e7b-4106-4147-914d-53b2f10b6628\" class=\"colab-df-container\">\n",
              "    <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>Pregnancies</th>\n",
              "      <th>Glucose</th>\n",
              "      <th>BloodPressure</th>\n",
              "      <th>SkinThickness</th>\n",
              "      <th>Insulin</th>\n",
              "      <th>BMI</th>\n",
              "      <th>DiabetesPedigreeFunction</th>\n",
              "      <th>Age</th>\n",
              "      <th>Outcome</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>6</td>\n",
              "      <td>148.0</td>\n",
              "      <td>72.0</td>\n",
              "      <td>35.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>33.6</td>\n",
              "      <td>0.627</td>\n",
              "      <td>50</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>1</td>\n",
              "      <td>85.0</td>\n",
              "      <td>66.0</td>\n",
              "      <td>29.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>26.6</td>\n",
              "      <td>0.351</td>\n",
              "      <td>31</td>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>8</td>\n",
              "      <td>183.0</td>\n",
              "      <td>64.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>23.3</td>\n",
              "      <td>0.672</td>\n",
              "      <td>32</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>1</td>\n",
              "      <td>89.0</td>\n",
              "      <td>66.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>94.0</td>\n",
              "      <td>28.1</td>\n",
              "      <td>0.167</td>\n",
              "      <td>21</td>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>0</td>\n",
              "      <td>137.0</td>\n",
              "      <td>40.0</td>\n",
              "      <td>35.0</td>\n",
              "      <td>168.0</td>\n",
              "      <td>43.1</td>\n",
              "      <td>2.288</td>\n",
              "      <td>33</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>\n",
              "    <div class=\"colab-df-buttons\">\n",
              "\n",
              "  <div class=\"colab-df-container\">\n",
              "    <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-407a0e7b-4106-4147-914d-53b2f10b6628')\"\n",
              "            title=\"Convert this dataframe to an interactive table.\"\n",
              "            style=\"display:none;\">\n",
              "\n",
              "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n",
              "    <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n",
              "  </svg>\n",
              "    </button>\n",
              "\n",
              "  <style>\n",
              "    .colab-df-container {\n",
              "      display:flex;\n",
              "      gap: 12px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert {\n",
              "      background-color: #E8F0FE;\n",
              "      border: none;\n",
              "      border-radius: 50%;\n",
              "      cursor: pointer;\n",
              "      display: none;\n",
              "      fill: #1967D2;\n",
              "      height: 32px;\n",
              "      padding: 0 0 0 0;\n",
              "      width: 32px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert:hover {\n",
              "      background-color: #E2EBFA;\n",
              "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "      fill: #174EA6;\n",
              "    }\n",
              "\n",
              "    .colab-df-buttons div {\n",
              "      margin-bottom: 4px;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert {\n",
              "      background-color: #3B4455;\n",
              "      fill: #D2E3FC;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert:hover {\n",
              "      background-color: #434B5C;\n",
              "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
              "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
              "      fill: #FFFFFF;\n",
              "    }\n",
              "  </style>\n",
              "\n",
              "    <script>\n",
              "      const buttonEl =\n",
              "        document.querySelector('#df-407a0e7b-4106-4147-914d-53b2f10b6628 button.colab-df-convert');\n",
              "      buttonEl.style.display =\n",
              "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "\n",
              "      async function convertToInteractive(key) {\n",
              "        const element = document.querySelector('#df-407a0e7b-4106-4147-914d-53b2f10b6628');\n",
              "        const dataTable =\n",
              "          await google.colab.kernel.invokeFunction('convertToInteractive',\n",
              "                                                    [key], {});\n",
              "        if (!dataTable) return;\n",
              "\n",
              "        const docLinkHtml = 'Like what you see? Visit the ' +\n",
              "          '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
              "          + ' to learn more about interactive tables.';\n",
              "        element.innerHTML = '';\n",
              "        dataTable['output_type'] = 'display_data';\n",
              "        await google.colab.output.renderOutput(dataTable, element);\n",
              "        const docLink = document.createElement('div');\n",
              "        docLink.innerHTML = docLinkHtml;\n",
              "        element.appendChild(docLink);\n",
              "      }\n",
              "    </script>\n",
              "  </div>\n",
              "\n",
              "\n",
              "<div id=\"df-b36a5264-5935-4c02-9bce-9c8e210bbac6\">\n",
              "  <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-b36a5264-5935-4c02-9bce-9c8e210bbac6')\"\n",
              "            title=\"Suggest charts\"\n",
              "            style=\"display:none;\">\n",
              "\n",
              "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
              "     width=\"24px\">\n",
              "    <g>\n",
              "        <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"/>\n",
              "    </g>\n",
              "</svg>\n",
              "  </button>\n",
              "\n",
              "<style>\n",
              "  .colab-df-quickchart {\n",
              "      --bg-color: #E8F0FE;\n",
              "      --fill-color: #1967D2;\n",
              "      --hover-bg-color: #E2EBFA;\n",
              "      --hover-fill-color: #174EA6;\n",
              "      --disabled-fill-color: #AAA;\n",
              "      --disabled-bg-color: #DDD;\n",
              "  }\n",
              "\n",
              "  [theme=dark] .colab-df-quickchart {\n",
              "      --bg-color: #3B4455;\n",
              "      --fill-color: #D2E3FC;\n",
              "      --hover-bg-color: #434B5C;\n",
              "      --hover-fill-color: #FFFFFF;\n",
              "      --disabled-bg-color: #3B4455;\n",
              "      --disabled-fill-color: #666;\n",
              "  }\n",
              "\n",
              "  .colab-df-quickchart {\n",
              "    background-color: var(--bg-color);\n",
              "    border: none;\n",
              "    border-radius: 50%;\n",
              "    cursor: pointer;\n",
              "    display: none;\n",
              "    fill: var(--fill-color);\n",
              "    height: 32px;\n",
              "    padding: 0;\n",
              "    width: 32px;\n",
              "  }\n",
              "\n",
              "  .colab-df-quickchart:hover {\n",
              "    background-color: var(--hover-bg-color);\n",
              "    box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "    fill: var(--button-hover-fill-color);\n",
              "  }\n",
              "\n",
              "  .colab-df-quickchart-complete:disabled,\n",
              "  .colab-df-quickchart-complete:disabled:hover {\n",
              "    background-color: var(--disabled-bg-color);\n",
              "    fill: var(--disabled-fill-color);\n",
              "    box-shadow: none;\n",
              "  }\n",
              "\n",
              "  .colab-df-spinner {\n",
              "    border: 2px solid var(--fill-color);\n",
              "    border-color: transparent;\n",
              "    border-bottom-color: var(--fill-color);\n",
              "    animation:\n",
              "      spin 1s steps(1) infinite;\n",
              "  }\n",
              "\n",
              "  @keyframes spin {\n",
              "    0% {\n",
              "      border-color: transparent;\n",
              "      border-bottom-color: var(--fill-color);\n",
              "      border-left-color: var(--fill-color);\n",
              "    }\n",
              "    20% {\n",
              "      border-color: transparent;\n",
              "      border-left-color: var(--fill-color);\n",
              "      border-top-color: var(--fill-color);\n",
              "    }\n",
              "    30% {\n",
              "      border-color: transparent;\n",
              "      border-left-color: var(--fill-color);\n",
              "      border-top-color: var(--fill-color);\n",
              "      border-right-color: var(--fill-color);\n",
              "    }\n",
              "    40% {\n",
              "      border-color: transparent;\n",
              "      border-right-color: var(--fill-color);\n",
              "      border-top-color: var(--fill-color);\n",
              "    }\n",
              "    60% {\n",
              "      border-color: transparent;\n",
              "      border-right-color: var(--fill-color);\n",
              "    }\n",
              "    80% {\n",
              "      border-color: transparent;\n",
              "      border-right-color: var(--fill-color);\n",
              "      border-bottom-color: var(--fill-color);\n",
              "    }\n",
              "    90% {\n",
              "      border-color: transparent;\n",
              "      border-bottom-color: var(--fill-color);\n",
              "    }\n",
              "  }\n",
              "</style>\n",
              "\n",
              "  <script>\n",
              "    async function quickchart(key) {\n",
              "      const quickchartButtonEl =\n",
              "        document.querySelector('#' + key + ' button');\n",
              "      quickchartButtonEl.disabled = true;  // To prevent multiple clicks.\n",
              "      quickchartButtonEl.classList.add('colab-df-spinner');\n",
              "      try {\n",
              "        const charts = await google.colab.kernel.invokeFunction(\n",
              "            'suggestCharts', [key], {});\n",
              "      } catch (error) {\n",
              "        console.error('Error during call to suggestCharts:', error);\n",
              "      }\n",
              "      quickchartButtonEl.classList.remove('colab-df-spinner');\n",
              "      quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n",
              "    }\n",
              "    (() => {\n",
              "      let quickchartButtonEl =\n",
              "        document.querySelector('#df-b36a5264-5935-4c02-9bce-9c8e210bbac6 button');\n",
              "      quickchartButtonEl.style.display =\n",
              "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "    })();\n",
              "  </script>\n",
              "</div>\n",
              "\n",
              "    </div>\n",
              "  </div>\n"
            ],
            "application/vnd.google.colaboratory.intrinsic+json": {
              "type": "dataframe",
              "variable_name": "diabetes_data",
              "summary": "{\n  \"name\": \"diabetes_data\",\n  \"rows\": 768,\n  \"fields\": [\n    {\n      \"column\": \"Pregnancies\",\n      \"properties\": {\n        \"dtype\": \"number\",\n        \"std\": 3,\n        \"min\": 0,\n        \"max\": 17,\n        \"num_unique_values\": 17,\n        \"samples\": [\n          6,\n          1,\n          3\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"Glucose\",\n      \"properties\": {\n        \"dtype\": \"number\",\n        \"std\": 32.09821458457135,\n        \"min\": 0.0,\n        \"max\": 199.0,\n        \"num_unique_values\": 135,\n        \"samples\": [\n          162.0,\n          163.0,\n          193.0\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"BloodPressure\",\n      \"properties\": {\n        \"dtype\": \"number\",\n        \"std\": 19.479981157348274,\n        \"min\": 0.0,\n        \"max\": 122.0,\n        \"num_unique_values\": 47,\n        \"samples\": [\n          75.0,\n          102.0,\n          86.0\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"SkinThickness\",\n      \"properties\": {\n        \"dtype\": \"number\",\n        \"std\": 16.011043374215106,\n        \"min\": 0.0,\n        \"max\": 99.0,\n        \"num_unique_values\": 50,\n        \"samples\": [\n          36.0,\n          44.0,\n          22.0\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"Insulin\",\n      \"properties\": {\n        \"dtype\": \"number\",\n        \"std\": 116.26498571474076,\n        \"min\": 0.0,\n        \"max\": 846.0,\n        \"num_unique_values\": 176,\n        \"samples\": [\n          70.0,\n          99.0,\n          193.0\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"BMI\",\n      \"properties\": {\n        \"dtype\": \"number\",\n        \"std\": 7.8841603203754405,\n        \"min\": 0.0,\n        \"max\": 67.1,\n        \"num_unique_values\": 248,\n        \"samples\": [\n          19.9,\n          31.0,\n          38.1\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"DiabetesPedigreeFunction\",\n      \"properties\": {\n        \"dtype\": \"number\",\n        \"std\": 0.33132859501277484,\n        \"min\": 0.078,\n        \"max\": 2.42,\n        \"num_unique_values\": 517,\n        \"samples\": [\n          1.731,\n          0.426,\n          0.138\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"Age\",\n      \"properties\": {\n        \"dtype\": \"number\",\n        \"std\": 11,\n        \"min\": 21,\n        \"max\": 81,\n        \"num_unique_values\": 52,\n        \"samples\": [\n          60,\n          47,\n          72\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    },\n    {\n      \"column\": \"Outcome\",\n      \"properties\": {\n        \"dtype\": \"number\",\n        \"std\": 0,\n        \"min\": 0,\n        \"max\": 1,\n        \"num_unique_values\": 2,\n        \"samples\": [\n          0,\n          1\n        ],\n        \"semantic_type\": \"\",\n        \"description\": \"\"\n      }\n    }\n  ]\n}"
            }
          },
          "metadata": {},
          "execution_count": 3
        }
      ],
      "source": [
        "diabetes_data.head()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "mi_6Mqz-NcYj",
        "outputId": "d80fcb05-c704-4fa8-b718-42fd3213c959"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Missing Values Per Column:\n",
            "Pregnancies                  0\n",
            "Glucose                     77\n",
            "BloodPressure               77\n",
            "SkinThickness               77\n",
            "Insulin                     77\n",
            "BMI                          0\n",
            "DiabetesPedigreeFunction     0\n",
            "Age                          0\n",
            "Outcome                      0\n",
            "dtype: int64\n"
          ]
        }
      ],
      "source": [
        "# Step 1: Detect Missing Values\n",
        "print(\"Missing Values Per Column:\")\n",
        "print(diabetes_data.isnull().sum())"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "metadata": {
        "id": "HBJQDeohOHH7"
      },
      "outputs": [],
      "source": [
        "# Step 2: Handle Missing Values (Impute with Median)\n",
        "columns_to_modify = ['Glucose', 'BloodPressure', 'SkinThickness', 'Insulin']\n",
        "\n",
        "for col in columns_to_modify:\n",
        "    diabetes_data[col] = diabetes_data[col].fillna(diabetes_data[col].median())\n",
        "\n",
        "# Why use median imputation?\n",
        "# - We didn't drop columns because features like 'Glucose' and 'Insulin' are crucial for predicting diabetes.\n",
        "# - Dropping rows would shrink the dataset, which isn't ideal for machine learning.\n",
        "# - Median is robust to outliers and works well for numeric data with skewed distributions.\n",
        "# - It's a simple and effective choice for handling missing values without overcomplicating the process.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "kyyheVLJON8n",
        "outputId": "97e86df0-5a9f-4dd8-b240-b4d6c3417b36"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\n",
            "Missing Values After Imputation:\n",
            "Pregnancies                 0\n",
            "Glucose                     0\n",
            "BloodPressure               0\n",
            "SkinThickness               0\n",
            "Insulin                     0\n",
            "BMI                         0\n",
            "DiabetesPedigreeFunction    0\n",
            "Age                         0\n",
            "Outcome                     0\n",
            "dtype: int64\n"
          ]
        }
      ],
      "source": [
        "# Verify that missing values are handled\n",
        "print(\"\\nMissing Values After Imputation:\")\n",
        "print(diabetes_data.isnull().sum())"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Save the cleaned dataset\n",
        "cleaned_file_path = '/content/diabetes_cleaned.csv'\n",
        "diabetes_data.to_csv(cleaned_file_path, index=False)\n",
        "\n",
        "print(f\"The cleaned dataset has been saved to: {cleaned_file_path}\")\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "GExQAiIjSXDr",
        "outputId": "a3cd1a8d-8e35-4770-b3d1-33de06b5c996"
      },
      "execution_count": 7,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "The cleaned dataset has been saved to: /content/diabetes_cleaned.csv\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "metadata": {
        "id": "3loJuTjmOScA"
      },
      "outputs": [],
      "source": [
        "# Step 3: Split Dataset into Features and Target\n",
        "X = diabetes_data.drop(columns=['Outcome'])\n",
        "y = diabetes_data['Outcome']"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "metadata": {
        "id": "2TJwJL7QOZXL"
      },
      "outputs": [],
      "source": [
        "# Split into training and testing sets\n",
        "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "m_Dd6JDkOc7m",
        "outputId": "d97a6a7c-5663-4048-eda8-f0996b5485f6"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\n",
            "Training Random Forest...\n",
            "Fitting 5 folds for each of 36 candidates, totalling 180 fits\n",
            "\n",
            "Best Hyperparameters for Random Forest: {'max_depth': 20, 'min_samples_leaf': 2, 'min_samples_split': 2, 'n_estimators': 100}\n",
            "Classification Report for Random Forest:\n",
            "\n",
            "              precision    recall  f1-score\n",
            "0              0.729730  0.818182  0.771429\n",
            "1              0.581395  0.454545  0.510204\n",
            "accuracy       0.688312  0.688312  0.688312\n",
            "macro avg      0.655563  0.636364  0.640816\n",
            "weighted avg   0.676753  0.688312  0.678134\n",
            "\n",
            "Training Logistic Regression...\n",
            "Fitting 5 folds for each of 8 candidates, totalling 40 fits\n",
            "\n",
            "Best Hyperparameters for Logistic Regression: {'C': 10, 'solver': 'liblinear'}\n",
            "Classification Report for Logistic Regression:\n",
            "\n",
            "              precision    recall  f1-score\n",
            "0              0.745614  0.858586  0.798122\n",
            "1              0.650000  0.472727  0.547368\n",
            "accuracy       0.720779  0.720779  0.720779\n",
            "macro avg      0.697807  0.665657  0.672745\n",
            "weighted avg   0.711466  0.720779  0.708567\n",
            "\n",
            "Training SVM...\n",
            "Fitting 5 folds for each of 8 candidates, totalling 40 fits\n",
            "\n",
            "Best Hyperparameters for SVM: {'C': 10, 'kernel': 'rbf'}\n",
            "Classification Report for SVM:\n",
            "\n",
            "              precision    recall  f1-score\n",
            "0              0.728814  0.868687  0.792627\n",
            "1              0.638889  0.418182  0.505495\n",
            "accuracy       0.707792  0.707792  0.707792\n",
            "macro avg      0.683851  0.643434  0.649061\n",
            "weighted avg   0.696698  0.707792  0.690080\n"
          ]
        }
      ],
      "source": [
        "# Step 4: Train and Evaluate Machine Learning Models\n",
        "\n",
        "# Define models and hyperparameter grids\n",
        "models = {\n",
        "    'Random Forest': RandomForestClassifier(),\n",
        "    'Logistic Regression': LogisticRegression(max_iter=1000),\n",
        "    'SVM': SVC()\n",
        "}\n",
        "\n",
        "param_grids = {\n",
        "    'Random Forest': {\n",
        "        'n_estimators': [100, 200],\n",
        "        'max_depth': [10, 20, None],\n",
        "        'min_samples_split': [2, 5],\n",
        "        'min_samples_leaf': [1, 2, 4],\n",
        "    },\n",
        "    'Logistic Regression': {\n",
        "        'C': [0.01, 0.1, 1, 10],\n",
        "        'solver': ['liblinear', 'saga'],\n",
        "    },\n",
        "    'SVM': {\n",
        "        'C': [0.01, 0.1, 1, 10],\n",
        "        'kernel': ['linear', 'rbf'],\n",
        "    }\n",
        "}\n",
        "\n",
        "# Perform Grid Search and Evaluation for each model\n",
        "for model_name, model in models.items():\n",
        "    print(f\"\\nTraining {model_name}...\")\n",
        "    grid_search = GridSearchCV(estimator=model, param_grid=param_grids[model_name], cv=5, n_jobs=-1, verbose=1)\n",
        "    grid_search.fit(X_train, y_train)\n",
        "    best_model = grid_search.best_estimator_\n",
        "    y_pred = best_model.predict(X_test)\n",
        "    print(f\"\\nBest Hyperparameters for {model_name}: {grid_search.best_params_}\")\n",
        "\n",
        "    # Generate classification report without support\n",
        "    report = classification_report(y_test, y_pred, output_dict=True)\n",
        "    df_report = pd.DataFrame(report).T.drop(columns=[\"support\"])\n",
        "    print(f\"Classification Report for {model_name}:\\n\")\n",
        "    print(df_report)\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "metadata": {
        "id": "uPNSzXCUOk3B",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "5424f05f-9b37-4739-bf8c-255692d44735"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\n",
            "Performing Feature Selection with RFE...\n",
            "Top features selected by RFE: ['Glucose', 'BloodPressure', 'BMI', 'DiabetesPedigreeFunction', 'Age']\n",
            "\n",
            "Training Random Forest with RFE selected features...\n",
            "\n",
            "Classification Report for Random Forest with RFE Selected Features:\n",
            "              precision    recall  f1-score   support\n",
            "\n",
            "           0       0.76      0.82      0.79        99\n",
            "           1       0.62      0.55      0.58        55\n",
            "\n",
            "    accuracy                           0.72       154\n",
            "   macro avg       0.69      0.68      0.69       154\n",
            "weighted avg       0.71      0.72      0.72       154\n",
            "\n"
          ]
        }
      ],
      "source": [
        "# Step 5: Feature Selection Using RFE\n",
        "print(\"\\nPerforming Feature Selection with RFE...\")\n",
        "base_model = RandomForestClassifier()\n",
        "rfe = RFE(estimator=base_model, n_features_to_select=5)  # Select top 5 features\n",
        "rfe.fit(X_train, y_train)\n",
        "\n",
        "# Identify selected features\n",
        "selected_features_rfe = X.columns[rfe.support_]\n",
        "print(f\"Top features selected by RFE: {list(selected_features_rfe)}\")\n",
        "\n",
        "# Filter datasets for selected features\n",
        "X_train_rfe_selected = X_train[selected_features_rfe]\n",
        "X_test_rfe_selected = X_test[selected_features_rfe]\n",
        "\n",
        "# Retrain Random Forest with RFE selected features\n",
        "print(\"\\nTraining Random Forest with RFE selected features...\")\n",
        "rf_rfe = RandomForestClassifier()\n",
        "rf_rfe.fit(X_train_rfe_selected, y_train)\n",
        "y_pred_rfe_selected = rf_rfe.predict(X_test_rfe_selected)\n",
        "\n",
        "# Classification Report\n",
        "print(\"\\nClassification Report for Random Forest with RFE Selected Features:\")\n",
        "print(classification_report(y_test, y_pred_rfe_selected))\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "4Df8xhF8G6jk"
      },
      "source": [
        "## Visualization"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 18,
      "metadata": {
        "id": "eP978CbtOn_H",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 561
        },
        "outputId": "c4c4db9e-bb1a-48dd-847b-290c94168a43"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Fitting 5 folds for each of 36 candidates, totalling 180 fits\n",
            "Fitting 5 folds for each of 8 candidates, totalling 40 fits\n",
            "Fitting 5 folds for each of 8 candidates, totalling 40 fits\n"
          ]
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<Figure size 800x500 with 1 Axes>"
            ],
            "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxYAAAHqCAYAAACZcdjsAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAABN70lEQVR4nO3deVwVZf//8fcB2RE3FMQbxS2XJHfNfYnEJVNzz8QUrUxS477NLBOX0rLbJcuyTMW7XMhcS3Mj0VxSk9xKKTXDFTUTEBUM5vdHP87XE6DioAf09Xw8ziPPNdfMfGY4h86bmes6FsMwDAEAAACACQ72LgAAAABAwUewAAAAAGAawQIAAACAaQQLAAAAAKYRLAAAAACYRrAAAAAAYBrBAgAAAIBpBAsAAAAAphEsAAAAAJhGsACAO2CxWDR27Nhcr3f8+HFZLBZFRkbmeU1Adlq2bKmWLVvauwwADwCCBYACKzIyUhaLRRaLRVu3bs2y3DAM+fv7y2Kx6IknnrBDhXljzZo1slgs8vPzU0ZGhr3LKXCSkpI0btw41axZU56ennJzc1ONGjU0cuRInT592t7lAcB9o5C9CwAAs1xdXbVw4UI1bdrUpn3z5s06efKkXFxc7FRZ3liwYIECAgJ0/PhxffvttwoKCrJ3SQXGsWPHFBQUpPj4eHXv3l3PPfecnJ2dtX//fs2ZM0fLly/XL7/8Yu8y76r169fbuwQADwiuWAAo8Nq3b68lS5bor7/+smlfuHCh6tatK19fXztVZl5KSopWrlyp8PBw1a5dWwsWLLB3STlKSUmxdwk2/vrrLz311FNKSEhQTEyMFi1apCFDhmjQoEF6//33dezYMXXv3t3eZd41V65ckSQ5OzvL2dnZztUAeBAQLAAUeL1799Yff/yhDRs2WNvS0tL05Zdf6umnn852nZSUFP373/+Wv7+/XFxcVKVKFf33v/+VYRg2/VJTU/Xyyy+rZMmSKly4sJ588kmdPHky222eOnVKAwYMkI+Pj1xcXPTwww9r7ty5po5t+fLlunr1qrp3765evXpp2bJlunbtWpZ+165d09ixY/XQQw/J1dVVpUuX1lNPPaWjR49a+2RkZOi9995TYGCgXF1dVbJkSbVt21Y//PCDpJuP//jnmJKxY8fKYrHo559/1tNPP61ixYpZrxjt379fzz77rCpUqCBXV1f5+vpqwIAB+uOPP7I9Z6GhofLz85OLi4vKly+vwYMHKy0tTceOHZPFYtG0adOyrLd9+3ZZLBYtWrQox3O3dOlS7du3T6+//nqWq1mS5OXlpbfeesumbcmSJapbt67c3Nzk7e2tZ555RqdOnbLp8+yzz8rT01Px8fF64okn5OnpqTJlymjmzJmSpAMHDqh169by8PBQuXLltHDhQpv1M2/h27Jli55//nmVKFFCXl5eCgkJ0Z9//mnTd+XKlerQoYP1/FSsWFETJkxQenq6Tb+WLVuqRo0a2rNnj5o3by53d3e99tpr1mX/HGPx/vvv6+GHH5a7u7uKFSumevXqZanzxx9/VLt27eTl5SVPT0899thj+v7777M9lm3btik8PFwlS5aUh4eHunTpovPnz2f3YwFwHyNYACjwAgIC1KhRI5sPmd98840SExPVq1evLP0Nw9CTTz6padOmqW3btpo6daqqVKmiESNGKDw83KbvwIEDNX36dLVp00Zvv/22nJyc1KFDhyzbTEhI0KOPPqqNGzcqLCxM7733nipVqqTQ0FBNnz79jo9twYIFatWqlXx9fdWrVy8lJyfrq6++sumTnp6uJ554QuPGjVPdunU1ZcoUDRs2TImJiTp48KC1X2hoqIYPHy5/f3+98847evXVV+Xq6prlw2JudO/eXVeuXNHEiRM1aNAgSdKGDRt07Ngx9e/fX++//7569eqlxYsXq3379jbB7fTp02rQoIEWL16snj17asaMGerbt682b96sK1euqEKFCmrSpEm2V2kWLFigwoULq1OnTjnWtmrVKklS3759b+tYIiMj1aNHDzk6OmrSpEkaNGiQli1bpqZNm+rSpUs2fdPT09WuXTv5+/tr8uTJCggIUFhYmCIjI9W2bVvVq1dP77zzjgoXLqyQkBD99ttvWfYXFhamQ4cOaezYsQoJCdGCBQvUuXNnm3MUGRkpT09PhYeH67333lPdunU1ZswYvfrqq1m298cff6hdu3aqVauWpk+frlatWmV7nLNnz9bQoUNVvXp1TZ8+XePGjVOtWrW0c+dOa5+ffvpJzZo10759+/TKK6/ojTfe0G+//aaWLVva9Mv00ksvad++fYqIiNDgwYP11VdfKSws7LbOO4D7iAEABdS8efMMScbu3buNDz74wChcuLBx5coVwzAMo3v37karVq0MwzCMcuXKGR06dLCut2LFCkOS8eabb9psr1u3bobFYjGOHDliGIZh7N2715BkvPjiizb9nn76aUOSERERYW0LDQ01SpcubVy4cMGmb69evYwiRYpY6/rtt98MSca8efNueXwJCQlGoUKFjNmzZ1vbGjdubHTq1Mmm39y5cw1JxtSpU7NsIyMjwzAMw/j2228NScbQoUNz7HOz2v55vBEREYYko3fv3ln6Zh7rjRYtWmRIMrZs2WJtCwkJMRwcHIzdu3fnWNPHH39sSDIOHTpkXZaWlmZ4e3sb/fr1y7LejWrXrm0UKVLkpn1u3GapUqWMGjVqGFevXrW2f/3114YkY8yYMda2fv36GZKMiRMnWtv+/PNPw83NzbBYLMbixYut7YcPH85y7jJft3Xr1jXS0tKs7ZMnTzYkGStXrrS2ZXcun3/+ecPd3d24du2ata1FixaGJGPWrFlZ+rdo0cJo0aKF9XmnTp2Mhx9++Kbno3Pnzoazs7Nx9OhRa9vp06eNwoULG82bN89yLEFBQdafmWEYxssvv2w4Ojoaly5duul+ANxfuGIB4L7Qo0cPXb16VV9//bWSk5P19ddf53gb1Jo1a+To6KihQ4fatP/73/+WYRj65ptvrP0kZek3fPhwm+eGYWjp0qXq2LGjDMPQhQsXrI/g4GAlJiYqNjY218e0ePFiOTg4qGvXrta23r1765tvvrG5ZWbp0qXy9vbWSy+9lGUbFovF2sdisSgiIiLHPnfihRdeyNLm5uZm/fe1a9d04cIFPfroo5JkPQ8ZGRlasWKFOnbsqHr16uVYU48ePeTq6mpz1WLdunW6cOGCnnnmmZvWlpSUpMKFC9/Wcfzwww86d+6cXnzxRbm6ulrbO3TooKpVq2r16tVZ1hk4cKD130WLFlWVKlXk4eGhHj16WNurVKmiokWL6tixY1nWf+655+Tk5GR9PnjwYBUqVMj6upNsz2VycrIuXLigZs2a6cqVKzp8+LDN9lxcXNS/f/9bHmvRokV18uRJ7d69O9vl6enpWr9+vTp37qwKFSpY20uXLq2nn35aW7duVVJSUpZjufF11KxZM6Wnp+v333+/ZT0A7h8ECwD3hZIlSyooKEgLFy7UsmXLlJ6erm7dumXb9/fff5efn1+WD53VqlWzLs/8r4ODgypWrGjTr0qVKjbPz58/r0uXLumTTz5RyZIlbR6ZH/TOnTuX62P6/PPP1aBBA/3xxx86cuSIjhw5otq1aystLU1Lliyx9jt69KiqVKmiQoVynujv6NGj8vPzU/HixXNdx82UL18+S9vFixc1bNgw+fj4yM3NTSVLlrT2S0xMlPT3OUtKSlKNGjVuuv2iRYuqY8eONvf/L1iwQGXKlFHr1q1vuq6Xl5eSk5Nv6zgyf+b//NlKUtWqVbN8QM4co3KjIkWK6F//+leWoFakSJEsYyckqXLlyjbPPT09Vbp0aR0/ftza9tNPP6lLly4qUqSIvLy8VLJkSWugyjyXmcqUKXNbg7RHjhwpT09PNWjQQJUrV9aQIUO0bds26/Lz58/rypUr2Z6LatWqKSMjQydOnLBpL1u2rM3zYsWKSVK2xw3g/sV0swDuG08//bQGDRqks2fPql27dipatOg92W/md0s888wz6tevX7Z9HnnkkVxt89dff7X+RfmfH0Clvz9cP/fcc7ms9OZyunLxz4HCN7rxL+qZevTooe3bt2vEiBGqVauWPD09lZGRobZt297R93CEhIRoyZIl2r59uwIDA7Vq1Sq9+OKLcnC4+d/Gqlatqh9//FEnTpyQv79/rvd7M46OjrlqN/4xKcDtuHTpklq0aCEvLy+NHz9eFStWlKurq2JjYzVy5Mgs5zK7n0V2qlWrpri4OH399ddau3atli5dqg8//FBjxozRuHHjcl2nlLfHDaDgIlgAuG906dJFzz//vL7//ntFRUXl2K9cuXLauHGjkpOTba5aZN5aUq5cOet/MzIyrFcEMsXFxdlsL3PGqPT09Dz7jokFCxbIyclJn332WZYPbVu3btWMGTMUHx+vsmXLqmLFitq5c6euX79uc2vNjSpWrKh169bp4sWLOV61yPwr8z8HKufmdpY///xT0dHRGjdunMaMGWNt//XXX236lSxZUl5eXjaDy3PStm1blSxZUgsWLFDDhg115cqV2xqQ3bFjRy1atEiff/65Ro0addO+mT/zuLi4LFdC4uLirMvz0q+//mozwPry5cs6c+aM2rdvL0mKiYnRH3/8oWXLlql58+bWftkNBM8tDw8P9ezZUz179lRaWpqeeuopvfXWWxo1apRKliwpd3f3LK9z6e/3iIODQ54HNQD3B26FAnDf8PT01EcffaSxY8eqY8eOOfZr37690tPT9cEHH9i0T5s2TRaLRe3atZMk639nzJhh0++fszw5Ojqqa9euWrp0abYflO9k2s0FCxaoWbNm6tmzp7p162bzGDFihCRZZ8Hq2rWrLly4kOV4pP/7i3HXrl1lGEa2f5HO7OPl5SVvb29t2bLFZvmHH35423VnhqB//qX6n+fMwcFBnTt31ldffWWd7ja7miSpUKFC6t27t7744gtFRkYqMDDwtq4AdevWTYGBgXrrrbe0Y8eOLMuTk5P1+uuvS5Lq1aunUqVKadasWUpNTbX2+eabb3To0KFsZwIz65NPPtH169etzz/66CP99ddf1tddducyLS0tVz+P7Pxz2l9nZ2dVr15dhmHo+vXrcnR0VJs2bbRy5Uqb27ISEhKsX0Tp5eVlqgYA9yeuWAC4r+R0K9KNOnbsqFatWun111/X8ePHVbNmTa1fv14rV67U8OHDrWMqatWqpd69e+vDDz9UYmKiGjdurOjoaB05ciTLNt9++21t2rRJDRs21KBBg1S9enVdvHhRsbGx2rhxoy5evHjbx7Bz504dOXIkx+k6y5Qpozp16mjBggUaOXKkQkJC9L///U/h4eHatWuXmjVrppSUFG3cuFEvvviiOnXqpFatWqlv376aMWOGfv31V+ttSd99951atWpl3dfAgQP19ttva+DAgapXr562bNmSq2+m9vLyUvPmzTV58mRdv35dZcqU0fr167P9K/vEiRO1fv16tWjRQs8995yqVaumM2fOaMmSJdq6davNrWwhISGaMWOGNm3apHfeeee2anFyctKyZcsUFBSk5s2bq0ePHmrSpImcnJz0008/aeHChSpWrJjeeustOTk56Z133lH//v3VokUL9e7dWwkJCXrvvfcUEBCgl19++bbPwe1KS0vTY489ph49eiguLk4ffvihmjZtqieffFKS1LhxYxUrVkz9+vXT0KFDZbFY9Nlnn5m+vahNmzby9fVVkyZN5OPjo0OHDumDDz5Qhw4drFfw3nzzTW3YsEFNmzbViy++qEKFCunjjz9WamqqJk+ebPrYAdyn7DIXFQDkgRunm72Zf043axiGkZycbLz88suGn5+f4eTkZFSuXNl49913babMNAzDuHr1qjF06FCjRIkShoeHh9GxY0fjxIkTWaYQNYy/p4cdMmSI4e/vbzg5ORm+vr7GY489ZnzyySfWPrcz3exLL71kSLKZ6vOfxo4da0gy9u3bZxjG39OS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2bOnfvnllzvef2RkpPW95ODgoNKlS6tnz56Kj4+/423mF7k5t0B+cf78eQ0ePFhly5aVi4uLfH19FRwcrM2bN8vb21tvv/12tutNmDBBPj4+un79uvV9Xa1atSz9lixZIovFooCAgLt8JMgvCBa4pbZt2+rMmTM6duyYpk2bpo8//lgRERH2LuuuyzzuGx/ly5e/o22lpaXlcXVA7pUsWVLu7u53vL6bm5tKlSplqgYvLy+dOXNGp06d0tKlSxUXF6fu3bub2ubtuH79+l3dvtlzC9hD165d9eOPP2r+/Pn65ZdftGrVKrVs2VKJiYl65plnNG/evCzrGIahyMhIhYSEyMnJSZLk4eGhc+fOaceOHTZ958yZo7Jly96TY0H+QLDALWX+FcPf31+dO3dWUFCQNmzYYF3+xx9/qHfv3ipTpozc3d0VGBioRYsW2WyjZcuWGjp0qF555RUVL15cvr6+Gjt2rE2fX3/9Vc2bN5erq6uqV69us49MBw4cUOvWreXm5qYSJUroueee0+XLl63LM//qO3HiRPn4+Kho0aIaP368/vrrL40YMULFixfXv/71r2x/WeZ03Dc+HB0dJUmbN29WgwYN5OLiotKlS+vVV1/VX3/9ZXO8YWFhGj58uLy9vRUcHCxJOnjwoNq1aydPT0/5+Piob9++unDhgnW9L7/8UoGBgdbjCwoKUkpKisaOHav58+dr5cqV1r/4xsTE3PIYcP+41WsuOTlZffr0kYeHh0qXLq1p06apZcuWGj58uLXPjVchDMPQ2LFjrX+p9PPz09ChQyX9/fr9/fff9fLLL1tfb1L2t0J99dVXql+/vlxdXeXt7a0uXbrc9DgsFot8fX1VunRpNW7cWKGhodq1a5eSkpKsfVauXKk6derI1dVVFSpU0Lhx42yO9fDhw2ratKn1d8XGjRttbps8fvy4LBaLoqKi1KJFC7m6umrBggWSpE8//VTVqlWTq6urqlatqg8//NC63bS0NIWFhal06dJydXVVuXLlrF/OerPz9c9zK/39HUydOnWSp6envLy81KNHDyUkJFiXjx07VrVq1dJnn32mgIAAFSlSRL169VJycvJNzx+QVy5duqTvvvtO77zzjlq1aqVy5cqpQYMGGjVqlJ588kmFhobql19+0datW23W27x5s44dO6bQ0FBrW6FChfT0009r7ty51raT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X1WqVNFvv/2Wq/0Ct8Pf319xcXH68MMP5ebmphdffFHNmzfP1SBnNze3XO/XwcFBlSpVUrVq1RQeHq5HH31UgwcPti6/fPmyxo0bZ/MeOXDggH799Ve5urrmal83vgczx2LNnj3bZtsHDx7U999/L0mqU6eOfvvtN02YMEFXr15Vjx491K1bN0l5c77+6V79TgRuxtXVVY8//rjeeOMNbd++Xc8++6x1ghYvLy9169bNOi5x3rx56tGjhzw9PbPdVp8+ffT9999r7Nix6tu3rwoVKnTPjgP5A8ECueLg4KDXXntNo0eP1tWrVyVJ27ZtU6dOnfTMM8+oZs2aqlChQq6npKxWrZpOnDhhcy935v/sb+yzb98+paSkWNu2bdsmBweHm/5lNq9Vq1ZNO3bskGEYNnUULlxY//rXv3Jcr06dOvrpp58UEBBgE1gqVapk/QBksVjUpEkTjRs3Tj/++KOcnZ21fPlySZKzs7PS09Pv7sEhX7rVa65ChQpycnLS7t27rcsTExNv+T50c3NTx44dNWPGDMXExGjHjh06cOCApNt7vT3yyCOKjo42cWR/j4OIioqyjgepU6eO4uLisrxHKlWqZH2vnzhxwmYg9I3HnRMfHx/5+fnp2LFjWbZ742xvXl5e6tmzp2bPnq2oqCgtXbpUFy9elHTz83WjzN9nJ06csLb9/PPPunTpkqpXr37H5wq4F6pXr27z/9nQ0FBt3bpVX3/9tbZv324zaPufihcvrieffFKbN2/WgAED7kW5yGcIFsi17t27y9HRUTNnzpQkVa5cWRs2bND27dt16NAhPf/88zb/078dQUFBeuihh9SvXz/t27dP3333XZYBmX369JGrq6v69eungwcPatOmTXrppZfUt2/fezo47MUXX9SJEyf00ksv6fDhw1q5cqUiIiIUHh5ucwvWPw0ZMkQXL15U7969tXv3bh09elTr1q1T//79lZ6erp07d2rixIn64YcfFB8fr2XLlun8+fPWucEDAgK0f/9+xcXF6cKFC3d9+kzce4mJiVmuaJ04ceKWr7nChQurX79+GjFihDZt2qSffvpJoaGhcnBwsLl96kaRkZGaM2eODh48qGPHjunzzz+Xm5ubypUrJ+nv19uWLVt06tQpm5nLbhQREaFFixYpIiJChw4d0oEDB/TOO+/k6pj9/f3VpUsXjRkzRpI0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\n"
          },
          "metadata": {}
        }
      ],
      "source": [
        "# Step 6: Visualize Model Accuracy\n",
        "# Prepare data for visualization\n",
        "model_names = []\n",
        "accuracy_scores = []\n",
        "\n",
        "# Evaluate each model and collect accuracy\n",
        "for model_name, model in models.items():\n",
        "    grid_search = GridSearchCV(estimator=model, param_grid=param_grids[model_name], cv=5, n_jobs=-1, verbose=1)\n",
        "    grid_search.fit(X_train, y_train)\n",
        "    best_model = grid_search.best_estimator_\n",
        "    y_pred = best_model.predict(X_test)\n",
        "\n",
        "    # Calculate accuracy\n",
        "    accuracy = np.mean(y_pred == y_test)\n",
        "    model_names.append(model_name)\n",
        "    accuracy_scores.append(accuracy)\n",
        "\n",
        "# Visualization\n",
        "fig, ax = plt.subplots(figsize=(8, 5))\n",
        "bars = ax.bar(model_names, accuracy_scores, color='skyblue')\n",
        "\n",
        "# Annotate bars with accuracy values\n",
        "for bar in bars:\n",
        "    height = bar.get_height()\n",
        "    ax.annotate(f'{height:.2f}', xy=(bar.get_x() + bar.get_width() / 2, height),\n",
        "                xytext=(0, 5), textcoords='offset points', ha='center', va='bottom')\n",
        "\n",
        "# Add labels and titles\n",
        "ax.set_title('Model Accuracy Comparison')\n",
        "ax.set_ylabel('Accuracy')\n",
        "ax.set_xlabel('Models')\n",
        "ax.set_ylim(0, 1)\n",
        "\n",
        "# Show the chart\n",
        "plt.tight_layout()\n",
        "plt.show()"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "provenance": [],
      "gpuType": "T4"
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    },
    "language_info": {
      "name": "python"
    },
    "accelerator": "GPU"
  },
  "nbformat": 4,
  "nbformat_minor": 0
}