{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "647e0e30-83f0-4aef-a3ce-9d9ba53dd87b",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.preprocessing import StandardScaler, LabelEncoder\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "from sklearn.tree import DecisionTreeClassifier\n",
    "from sklearn.ensemble import RandomForestClassifier\n",
    "from sklearn.svm import SVC\n",
    "from sklearn.naive_bayes import GaussianNB\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "from sklearn.metrics import confusion_matrix, accuracy_score, precision_score, recall_score\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "6cd20231-ee74-4329-97d5-6fe4cbd41817",
   "metadata": {},
   "outputs": [],
   "source": [
    "data = pd.read_csv('Diabetes.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "83db2eb4-8652-4e2b-9a11-0f8c9695f11a",
   "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>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</td>\n",
       "      <td>72</td>\n",
       "      <td>35</td>\n",
       "      <td>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</td>\n",
       "      <td>66</td>\n",
       "      <td>29</td>\n",
       "      <td>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</td>\n",
       "      <td>64</td>\n",
       "      <td>0</td>\n",
       "      <td>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</td>\n",
       "      <td>66</td>\n",
       "      <td>23</td>\n",
       "      <td>94</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</td>\n",
       "      <td>40</td>\n",
       "      <td>35</td>\n",
       "      <td>168</td>\n",
       "      <td>43.1</td>\n",
       "      <td>2.288</td>\n",
       "      <td>33</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>758</th>\n",
       "      <td>1</td>\n",
       "      <td>106</td>\n",
       "      <td>76</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>37.5</td>\n",
       "      <td>0.197</td>\n",
       "      <td>26</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>759</th>\n",
       "      <td>6</td>\n",
       "      <td>190</td>\n",
       "      <td>92</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>35.5</td>\n",
       "      <td>0.278</td>\n",
       "      <td>66</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>760</th>\n",
       "      <td>2</td>\n",
       "      <td>88</td>\n",
       "      <td>58</td>\n",
       "      <td>26</td>\n",
       "      <td>16</td>\n",
       "      <td>28.4</td>\n",
       "      <td>0.766</td>\n",
       "      <td>22</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>761</th>\n",
       "      <td>9</td>\n",
       "      <td>170</td>\n",
       "      <td>74</td>\n",
       "      <td>31</td>\n",
       "      <td>0</td>\n",
       "      <td>44.0</td>\n",
       "      <td>0.403</td>\n",
       "      <td>43</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>762</th>\n",
       "      <td>9</td>\n",
       "      <td>89</td>\n",
       "      <td>62</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>22.5</td>\n",
       "      <td>0.142</td>\n",
       "      <td>33</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>763 rows × 9 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "     Pregnancies  Glucose  BloodPressure  SkinThickness  Insulin   BMI  \\\n",
       "0              6      148             72             35        0  33.6   \n",
       "1              1       85             66             29        0  26.6   \n",
       "2              8      183             64              0        0  23.3   \n",
       "3              1       89             66             23       94  28.1   \n",
       "4              0      137             40             35      168  43.1   \n",
       "..           ...      ...            ...            ...      ...   ...   \n",
       "758            1      106             76              0        0  37.5   \n",
       "759            6      190             92              0        0  35.5   \n",
       "760            2       88             58             26       16  28.4   \n",
       "761            9      170             74             31        0  44.0   \n",
       "762            9       89             62              0        0  22.5   \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  \n",
       "..                        ...  ...      ...  \n",
       "758                     0.197   26        0  \n",
       "759                     0.278   66        1  \n",
       "760                     0.766   22        0  \n",
       "761                     0.403   43        1  \n",
       "762                     0.142   33        0  \n",
       "\n",
       "[763 rows x 9 columns]"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.head(-5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "fcaaf713-2f34-451a-b8ef-4dffdea965bf",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "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": [
    "import pandas as pd\n",
    "\n",
    "# Load dataset\n",
    "data = pd.read_csv('Diabetes.csv')\n",
    "\n",
    "# Check for missing values\n",
    "print(data.isnull().sum())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "20c9945f-fe65-4de2-8d3a-cb1c640332f9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Outcome\n",
       "0    500\n",
       "1    268\n",
       "Name: count, dtype: int64"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Count the number of occurrences of each unique value in the 'Outcome' column\n",
    "data['Outcome'].value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "9448d7ec-3b4e-4097-9956-0c6270c9b31a",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import LabelEncoder\n",
    "\n",
    "# Example for converting 'Outcome' into numerical data\n",
    "label_encoder = LabelEncoder()\n",
    "data['Outcome'] = label_encoder.fit_transform(data['Outcome'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "41288d91-f9ef-490f-8b59-8733ba24bad0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Shape of Features (X): (768, 8)\n",
      "Shape of Target (y): (768,)\n"
     ]
    }
   ],
   "source": [
    "# Import the dataset\n",
    "data = pd.read_csv('Diabetes.csv')\n",
    "\n",
    "# Features: All columns except the target\n",
    "X = data.drop(columns=['Outcome'])\n",
    "\n",
    "# Target: The 'Outcome' column\n",
    "y = data['Outcome']\n",
    "\n",
    "# Display the dimensions of features and target\n",
    "print(\"Shape of Features (X):\", X.shape)\n",
    "print(\"Shape of Target (y):\", y.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "031bbdcc-5a16-4451-8ed6-ce26ba47046a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training Features Shape: (614, 8)\n",
      "Testing Features Shape: (154, 8)\n",
      "Training Target Shape: (614,)\n",
      "Testing Target Shape: (154,)\n"
     ]
    }
   ],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "# Load the dataset\n",
    "data = pd.read_csv('Diabetes.csv')\n",
    "\n",
    "# Define features and target variable\n",
    "X = data.drop(columns=['Outcome'])  # Features\n",
    "y = data['Outcome']  # Target variable\n",
    "\n",
    "# Split the data 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",
    "\n",
    "# Display the dimensions of the splits\n",
    "print(\"Training Features Shape:\", X_train.shape)\n",
    "print(\"Testing Features Shape:\", X_test.shape)\n",
    "print(\"Training Target Shape:\", y_train.shape)\n",
    "print(\"Testing Target Shape:\", y_test.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "dc9d3f98-ec74-4662-941e-2e03e8386d8f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy: 0.7207792207792207\n",
      "Confusion Matrix:\n",
      " [[77 22]\n",
      " [21 34]]\n",
      "Classification Report:\n",
      "               precision    recall  f1-score   support\n",
      "\n",
      "           0       0.79      0.78      0.78        99\n",
      "           1       0.61      0.62      0.61        55\n",
      "\n",
      "    accuracy                           0.72       154\n",
      "   macro avg       0.70      0.70      0.70       154\n",
      "weighted avg       0.72      0.72      0.72       154\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Importing necessary libraries\n",
    "from sklearn.ensemble import RandomForestClassifier\n",
    "from sklearn.metrics import accuracy_score, confusion_matrix, classification_report\n",
    "\n",
    "# Initialize the Random Forest Classifier\n",
    "rf_classifier = RandomForestClassifier(n_estimators=100, random_state=42)\n",
    "\n",
    "# Train the model\n",
    "rf_classifier.fit(X_train, y_train)\n",
    "\n",
    "# Predict on the test data\n",
    "y_pred = rf_classifier.predict(X_test)\n",
    "\n",
    "# Evaluate the model\n",
    "accuracy = accuracy_score(y_test, y_pred)\n",
    "conf_matrix = confusion_matrix(y_test, y_pred)\n",
    "class_report = classification_report(y_test, y_pred)\n",
    "\n",
    "# Display results\n",
    "print(\"Accuracy:\", accuracy)\n",
    "print(\"Confusion Matrix:\\n\", conf_matrix)\n",
    "print(\"Classification Report:\\n\", class_report)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "138920a6-5ff1-4655-b058-df7d24aa54a4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy: 0.7467532467532467\n",
      "Confusion Matrix:\n",
      " [[78 21]\n",
      " [18 37]]\n",
      "Classification Report:\n",
      "               precision    recall  f1-score   support\n",
      "\n",
      "           0       0.81      0.79      0.80        99\n",
      "           1       0.64      0.67      0.65        55\n",
      "\n",
      "    accuracy                           0.75       154\n",
      "   macro avg       0.73      0.73      0.73       154\n",
      "weighted avg       0.75      0.75      0.75       154\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Importing required libraries\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "from sklearn.metrics import accuracy_score, confusion_matrix, classification_report\n",
    "\n",
    "# Initialize the Logistic Regression model\n",
    "logistic_model = LogisticRegression(max_iter=1000, random_state=42)\n",
    "\n",
    "# Train the model\n",
    "logistic_model.fit(X_train, y_train)\n",
    "\n",
    "# Predict on the test data\n",
    "y_pred = logistic_model.predict(X_test)\n",
    "\n",
    "# Evaluate the model\n",
    "accuracy = accuracy_score(y_test, y_pred)\n",
    "conf_matrix = confusion_matrix(y_test, y_pred)\n",
    "class_report = classification_report(y_test, y_pred)\n",
    "\n",
    "# Display evaluation results\n",
    "print(\"Accuracy:\", accuracy)\n",
    "print(\"Confusion Matrix:\\n\", conf_matrix)\n",
    "print(\"Classification Report:\\n\", class_report)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "d5266a61-8277-4836-9a2e-cd98ba645ec1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy: 0.7532467532467533\n",
      "Confusion Matrix:\n",
      " [[80 19]\n",
      " [19 36]]\n",
      "Classification Report:\n",
      "               precision    recall  f1-score   support\n",
      "\n",
      "           0       0.81      0.81      0.81        99\n",
      "           1       0.65      0.65      0.65        55\n",
      "\n",
      "    accuracy                           0.75       154\n",
      "   macro avg       0.73      0.73      0.73       154\n",
      "weighted avg       0.75      0.75      0.75       154\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Importing necessary libraries\n",
    "from sklearn.svm import SVC\n",
    "from sklearn.metrics import accuracy_score, confusion_matrix, classification_report\n",
    "\n",
    "# Initialize the SVM classifier\n",
    "svm_model = SVC(kernel='linear', random_state=42)\n",
    "\n",
    "# Train the SVM model\n",
    "svm_model.fit(X_train, y_train)\n",
    "\n",
    "# Predict on the test data\n",
    "y_pred = svm_model.predict(X_test)\n",
    "\n",
    "# Evaluate the model\n",
    "accuracy = accuracy_score(y_test, y_pred)\n",
    "conf_matrix = confusion_matrix(y_test, y_pred)\n",
    "class_report = classification_report(y_test, y_pred)\n",
    "\n",
    "# Display evaluation metrics\n",
    "print(\"Accuracy:\", accuracy)\n",
    "print(\"Confusion Matrix:\\n\", conf_matrix)\n",
    "print(\"Classification Report:\\n\", class_report)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "87729d30-f453-4f3b-bf2f-2da77f3c49dd",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy: 0.6623376623376623\n",
      "Confusion Matrix:\n",
      " [[70 29]\n",
      " [23 32]]\n",
      "Classification Report:\n",
      "               precision    recall  f1-score   support\n",
      "\n",
      "           0       0.75      0.71      0.73        99\n",
      "           1       0.52      0.58      0.55        55\n",
      "\n",
      "    accuracy                           0.66       154\n",
      "   macro avg       0.64      0.64      0.64       154\n",
      "weighted avg       0.67      0.66      0.67       154\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Importing required libraries\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "from sklearn.metrics import accuracy_score, confusion_matrix, classification_report\n",
    "\n",
    "# Initialize the KNN classifier\n",
    "knn_model = KNeighborsClassifier(n_neighbors=5)\n",
    "\n",
    "# Train the model\n",
    "knn_model.fit(X_train, y_train)\n",
    "\n",
    "# Predict on the test data\n",
    "y_pred = knn_model.predict(X_test)\n",
    "\n",
    "# Evaluate the model\n",
    "accuracy = accuracy_score(y_test, y_pred)\n",
    "conf_matrix = confusion_matrix(y_test, y_pred)\n",
    "class_report = classification_report(y_test, y_pred)\n",
    "\n",
    "# Display evaluation metrics\n",
    "print(\"Accuracy:\", accuracy)\n",
    "print(\"Confusion Matrix:\\n\", conf_matrix)\n",
    "print(\"Classification Report:\\n\", class_report)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "e7826f53-fff1-4662-b7bf-68873d6bee67",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAIjCAYAAACTRapjAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvc2/+5QAAAAlwSFlzAAAPYQAAD2EBqD+naQAATFVJREFUeJzt3Xt8z/X///H7e2PvzWYnzKyYY3PImRiVQxOiiD4U5RAdhaxUOjmVoXIsFD5ITuUUyVlIJnJKSHJo9bE5ZWPYsL1+f/Tz/va20aa993p7v27XLq/LxZ6v5+v5erzen+zz6PF8vp5vm2EYhgAAAGAZXmYHAAAAgPxFAggAAGAxJIAAAAAWQwIIAABgMSSAAAAAFkMCCAAAYDEkgAAAABZDAggAAGAxJIAAAAAWQwII4IYOHjyo+++/X0FBQbLZbFq8eHGejn/06FHZbDZNnz49T8e9lTVu3FiNGzc2OwwAHowEELgFHDp0SM8884zKli0rX19fBQYGqmHDhho7dqwuXrzo0nt37dpVe/bs0bvvvquZM2eqTp06Lr1ffurWrZtsNpsCAwOz/RwPHjwom80mm82m999/P9fjHzt2TIMGDdKuXbvyIFoAyDsFzA4AwI0tW7ZM//nPf2S329WlSxfdeeedunTpkjZt2qT+/ftr7969+uSTT1xy74sXLyo+Pl5vvPGGXnjhBZfcIzIyUhcvXlTBggVdMv4/KVCggC5cuKClS5eqQ4cOTudmzZolX19fpaWl3dTYx44d0+DBg1W6dGnVqFEjx9etWrXqpu4HADlFAgi4sSNHjujRRx9VZGSk1q1bpxIlSjjO9erVS7/++quWLVvmsvufPHlSkhQcHOyye9hsNvn6+rps/H9it9vVsGFDzZkzJ0sCOHv2bLVq1UoLFizIl1guXLigQoUKycfHJ1/uB8C6mAIG3NjIkSOVmpqqqVOnOiV/V5UvX159+/Z1/HzlyhUNHTpU5cqVk91uV+nSpfX6668rPT3d6brSpUurdevW2rRpk+666y75+vqqbNmy+vTTTx19Bg0apMjISElS//79ZbPZVLp0aUl/TZ1e/fPfDRo0SDabzalt9erVuvvuuxUcHKyAgABFRUXp9ddfd5y/3hrAdevW6Z577pG/v7+Cg4PVpk0b7d+/P9v7/frrr+rWrZuCg4MVFBSk7t2768KFC9f/YK/RqVMnLV++XMnJyY62bdu26eDBg+rUqVOW/n/++adefvllVa1aVQEBAQoMDFTLli21e/duR5/169erbt26kqTu3bs7ppKvPmfjxo115513avv27br33ntVqFAhx+dy7RrArl27ytfXN8vzN2/eXCEhITp27FiOnxUAJBJAwK0tXbpUZcuWVYMGDXLUv2fPnnr77bdVq1YtjR49Wo0aNVJcXJweffTRLH1//fVXPfLII2rWrJk++OADhYSEqFu3btq7d68kqV27dho9erQk6bHHHtPMmTM1ZsyYXMW/d+9etW7dWunp6RoyZIg++OADPfTQQ/ruu+9ueN2aNWvUvHlznThxQoMGDVJsbKw2b96shg0b6ujRo1n6d+jQQefOnVNcXJw6dOig6dOna/DgwTmOs127drLZbFq4cKGjbfbs2apYsaJq1aqVpf/hw4e1ePFitW7dWqNGjVL//v21Z88eNWrUyJGMVapUSUOGDJEkPf3005o5c6Zmzpype++91zHO6dOn1bJlS9WoUUNjxoxRkyZNso1v7NixKlasmLp27aqMjAxJ0scff6xVq1Zp/PjxioiIyPGzAoAkyQDgllJSUgxJRps2bXLUf9euXYYko2fPnk7tL7/8siHJWLdunaMtMjLSkGRs3LjR0XbixAnDbrcbL730kqPtyJEjhiTjvffecxqza9euRmRkZJYYBg4caPz918ro0aMNScbJkyevG/fVe0ybNs3RVqNGDSMsLMw4ffq0o2337t2Gl5eX0aVLlyz3e/LJJ53GfPjhh40iRYpc955/fw5/f3/DMAzjkUceMe677z7DMAwjIyPDCA8PNwYPHpztZ5CWlmZkZGRkeQ673W4MGTLE0bZt27Ysz3ZVo0aNDEnGpEmTsj3XqFEjp7aVK1cakox33nnHOHz4sBEQEGC0bdv2H58RALJDBRBwU2fPnpUkFS5cOEf9v/76a0lSbGysU/tLL70kSVnWClauXFn33HOP4+dixYopKipKhw8fvumYr3V17eCXX36pzMzMHF2TmJioXbt2qVu3bgoNDXW0V6tWTc2aNXM85989++yzTj/fc889On36tOMzzIlOnTpp/fr1SkpK0rp165SUlJTt9K/017pBL6+/fn1mZGTo9OnTjuntHTt25Piedrtd3bt3z1Hf+++/X88884yGDBmidu3aydfXVx9//HGO7wUA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Vq2qefPmZWmfO3euKleunCdBAQAA5CebzXWHO8r1SyBvvfWW2rVrp0OHDqlp06aSpLVr12r27NmaP39+ngcIAADgal7umqm5SK4TwAcffFCLFy/WsGHDNH/+fPn5+al69epat26dQkNDXREjAAAA8lCuE0BJatWqlVq1aiVJOnv2rObMmaOXX35Z27dvV0ZGRp4GCAAA4Gq5XhN3i7vp5924caO6du2qiIgIffDBB2ratKm2bNmSl7EBAADABXJVAUxKStL06dM1depUnT17Vh06dFB6eroWL17MCyAAAOCWZbElgDmvAD744IOKiorSjz/+qDFjxujYsWMaP368K2MDAACAC+S4Arh8+XL16dNHzz33nCpUqODKmAAAAPKV1d4CznEFcNOmTTp37pxq166tevXq6cMPP9SpU6dcGRsAAABcIMcJYP369TV58mQlJibqmWee0dy5cxUREaHMzEytXr1a586dc2WcAAAALmO1jaBz/Rawv7+/nnzySW3atEl79uzRSy+9pOHDhyssLEwPPfSQK2IEAABwKb4LOBeioqI0cuRI/fHHH5ozZ05exQQAAAAXuqmNoK/l7e2ttm3bqm3btnkxHAAAQL7iJRAAAAB4tDypAAIAANzKLFYApAIIAABgNVQAAQCA5bnr27quQgUQAADAYqgAAgAAy7PJWiVAEkAAAGB5TAEDAADAo1EBBAAAlkcFEAAAAB6NCiAAALA8m8V2gqYCCAAAYDFUAAEAgOWxBhAAAAAejQogAACwPIstASQBBAAA8LJYBsgUMAAAgMVQAQQAAJbHSyAAAADwaFQAAQCA5VlsCSAVQAAAAKuhAggAACzPS9YqAVIBBAAAsBgqgAAAwPKstgaQBBAAAFge28AAAADAo1EBBAAAlsdXwQEAAMCjUQEEAACWZ7ECIBVAAAAAq6ECCAAALI81gAAAAPBoVAABAIDlWawASAIIAABgtSlRqz0vAACA5VEBBAAAlmez2BwwFUAAAACLoQIIAAAsz1r1PyqAAAAAlkMFEAAAWB4bQQMAAMCjUQEEAACWZ636HwkgAACA5b4JhClgAAAAi6ECCAAALI+NoAEAAODRSAABAIDlebnw+DeGDx8um82mF1980dGWlpamXr16qUiRIgoICFD79u11/PjxXI1LAggAAOCGtm3bpo8//ljVqlVzau/Xr5+WLl2q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",
      "text/plain": [
       "<Figure size 800x600 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.ensemble import RandomForestClassifier\n",
    "from sklearn.metrics import confusion_matrix\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "\n",
    "# Load the dataset\n",
    "data = pd.read_csv('Diabetes.csv')\n",
    "\n",
    "# Define features and target variable\n",
    "X = data.drop(columns=['Outcome'])  # Features\n",
    "y = data['Outcome']  # Target\n",
    "\n",
    "# Split the dataset\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\n",
    "\n",
    "# Train a classifier\n",
    "model = RandomForestClassifier(random_state=42)\n",
    "model.fit(X_train, y_train)\n",
    "\n",
    "# Make predictions\n",
    "y_pred = model.predict(X_test)\n",
    "\n",
    "# Generate Confusion Matrix\n",
    "cm = confusion_matrix(y_test, y_pred)\n",
    "\n",
    "# Plot Confusion Matrix\n",
    "plt.figure(figsize=(8, 6))\n",
    "sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=['No Diabetes', 'Diabetes'], yticklabels=['No Diabetes', 'Diabetes'])\n",
    "plt.xlabel('Predicted')\n",
    "plt.ylabel('Actual')\n",
    "plt.title('Confusion Matrix')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "b589c558-77cd-4f43-aa13-deb993c7b79c",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.feature_selection import SelectKBest, chi2\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "1814bd6f-472b-46b0-a94a-b6b9851d50eb",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\USER\\AppData\\Local\\Temp\\ipykernel_11884\\2409946590.py:7: FutureWarning: A value is trying to be set on a copy of a DataFrame or Series through chained assignment using an inplace method.\n",
      "The behavior will change in pandas 3.0. This inplace method will never work because the intermediate object on which we are setting values always behaves as a copy.\n",
      "\n",
      "For example, when doing 'df[col].method(value, inplace=True)', try using 'df.method({col: value}, inplace=True)' or df[col] = df[col].method(value) instead, to perform the operation inplace on the original object.\n",
      "\n",
      "\n",
      "  data[col].replace(0, data[col].mean(), inplace=True)\n"
     ]
    }
   ],
   "source": [
    "# Load the dataset\n",
    "data = pd.read_csv('Diabetes.csv')\n",
    "\n",
    "# Replace zeros in specific columns (except Pregnancies, as 0 may be valid)\n",
    "columns_to_replace = ['Glucose', 'BloodPressure', 'SkinThickness', 'Insulin', 'BMI']\n",
    "for col in columns_to_replace:\n",
    "    data[col].replace(0, data[col].mean(), inplace=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "a6b27a01-c23f-47e0-babb-2215370c5bd3",
   "metadata": {},
   "outputs": [],
   "source": [
    "X = data.drop(columns=['Outcome'])  # Features\n",
    "y = data['Outcome']                 # Target"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "22065a10-c79d-436f-9dea-82faa085a647",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                    Feature  Chi-Square Score\n",
      "4                   Insulin       1798.088682\n",
      "1                   Glucose       1418.660636\n",
      "7                       Age        181.303689\n",
      "0               Pregnancies        111.519691\n",
      "5                       BMI        108.937867\n",
      "3             SkinThickness         81.917622\n",
      "2             BloodPressure         41.394665\n",
      "6  DiabetesPedigreeFunction          5.392682\n"
     ]
    }
   ],
   "source": [
    "# Select top K features\n",
    "chi_selector = SelectKBest(score_func=chi2, k='all')  # Choose 'k' features (or 'all' to score all features)\n",
    "chi_selector.fit(X, y)\n",
    "\n",
    "# Get feature scores\n",
    "chi_scores = chi_selector.scores_\n",
    "\n",
    "# Display feature scores\n",
    "feature_scores = pd.DataFrame({'Feature': X.columns, 'Chi-Square Score': chi_scores})\n",
    "print(feature_scores.sort_values(by='Chi-Square Score', ascending=False))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "f18fed39-22b3-4ba0-a999-11f4c57edb17",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Selected Features: Index(['Pregnancies', 'Glucose', 'Insulin', 'BMI', 'Age'], dtype='object')\n"
     ]
    }
   ],
   "source": [
    "from sklearn.feature_selection import SelectKBest, chi2\n",
    "\n",
    "# Select top 5 features for simplicity (adjust 'k' as needed)\n",
    "chi_selector = SelectKBest(score_func=chi2, k=5)\n",
    "X_selected = chi_selector.fit_transform(X, y)\n",
    "selected_features = X.columns[chi_selector.get_support()]\n",
    "print(\"Selected Features:\", selected_features)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "7e784b54-8850-4c15-88ad-d8b8dbf3a07d",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\USER\\AppData\\Local\\Temp\\ipykernel_11884\\3564244265.py:15: FutureWarning: A value is trying to be set on a copy of a DataFrame or Series through chained assignment using an inplace method.\n",
      "The behavior will change in pandas 3.0. This inplace method will never work because the intermediate object on which we are setting values always behaves as a copy.\n",
      "\n",
      "For example, when doing 'df[col].method(value, inplace=True)', try using 'df.method({col: value}, inplace=True)' or df[col] = df[col].method(value) instead, to perform the operation inplace on the original object.\n",
      "\n",
      "\n",
      "  data[col].replace(0, data[col].mean(), inplace=True)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy: 0.7662337662337663\n",
      "Classification Report:\n",
      "               precision    recall  f1-score   support\n",
      "\n",
      "           0       0.83      0.80      0.81        99\n",
      "           1       0.66      0.71      0.68        55\n",
      "\n",
      "    accuracy                           0.77       154\n",
      "   macro avg       0.75      0.75      0.75       154\n",
      "weighted avg       0.77      0.77      0.77       154\n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAIjCAYAAACTRapjAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvc2/+5QAAAAlwSFlzAAAPYQAAD2EBqD+naQAAXJtJREFUeJzt3Xt8z/X///H7e2Nvs9lm7GAOcz7mrFiUiJBECKVM6Og8qXRyqAyVYx+HKCQkx5KciWRKTilSObTEnDJzyNj2/P3h5/31tmGT995ve92uXV6Xy/Z8nR6vl/fWY4/n8/V82YwxRgAAALAML3cHAAAAgOxFAggAAGAxJIAAAAAWQwIIAABgMSSAAAAAFkMCCAAAYDEkgAAAABZDAggAAGAxJIAAAAAWQwKIbPH777/rgQceUGBgoGw2mxYtWnRLj3/gwAHZbDZNmzbtlh73dnbffffpvvvuc3cYHoPPiGfzhH+f4sWLq3Pnzk5tGf3umjZtmmw2mw4cOOCWOIFbgQTQQvbu3atnn31WJUuWVJ48eRQQEKC6detqzJgx+vfff1167ujoaO3cuVPvvPOOZsyYoVq1arn0fNmpc+fOstlsCggIyPA+/v7777LZbLLZbHrvvfeyfPxDhw5p0KBB2r59+y2INnsUL17ccc02m01+fn6666679Mknn7g7NI9y9X26cjl//ry7w0tn48aNGjRokBITE7O03zfffKPWrVsrPDxcPj4+Cg0NVYsWLbRgwQLXBHoL5eTfXbC2XO4OANljyZIlevTRR2W329WpUyfdcccdunDhgjZs2KD+/fvrl19+0YcffuiSc//777+Ki4vTa6+9ph49erjkHJGRkfr333+VO3dulxz/RnLlyqVz585p8eLFateundO6mTNnKk+ePDf9P/RDhw5p8ODBKl68uKpVq5bp/VasWHFT57tVqlWrpn79+kmSDh8+rClTpig6OlrJycl6+umn3RqbJ7nyPl3Jx8fHDdFc38aNGzV48GB17txZQUFBmdpn4MCBGjJkiMqUKaNnn31WkZGROnHihL7++mu1adNGM2fO1OOPP+7awDNpz5498vL6v7rItX53Pfnkk+rQoYPsdrs7wgRuCRJAC9i/f786dOigyMhIrVmzRoUKFXKs6969u/744w8tWbLEZec/duyYJGX6fxg3w2azKU+ePC47/o3Y7XbVrVtXs2fPTpcAzpo1S82bN9f8+fOzJZZz584pb968bk8gChcurCeeeMLxfefOnVWyZEmNGjWKBPAKV9+nWyUtLU0XLlxw68/FvHnzNGTIELVt21azZs1y+gOtf//+Wr58uS5evOi2+K52dUJ3rd9d3t7e8vb2vmXnPXv2rPz8/G7Z8YBMMcjxnnvuOSPJfPfdd5na/uLFi2bIkCGmZMmSxsfHx0RGRpoBAwaY8+fPO20XGRlpmjdvbr799ltz5513GrvdbkqUKGGmT5/u2GbgwIFGktMSGRlpjDEmOjra8fWVLu9zpRUrVpi6deuawMBA4+fnZ8qWLWsGDBjgWL9//34jyUydOtVpv9WrV5t69eqZvHnzmsDAQPPwww+bXbt2ZXi+33//3URHR5vAwEATEBBgOnfubM6ePXvD+xUdHW38/PzMtGnTjN1uNydPnnSs++GHH4wkM3/+fCPJvPvuu451J06cMP369TN33HGH8fPzM/ny5TNNmzY127dvd2yzdu3adPfvyuusX7++qVSpkvnxxx/NPffcY3x9fU3v3r0d6+rXr+84VqdOnYzdbk93/Q888IAJCgoyf//99w2vNbMufzauVqtWLePj4+PUtn79etO2bVtTtGhR4+PjY4oUKWL69Oljzp0757Td5ft88OBB07JlS+Pn52cKFixo+vXrZ1JSUpy2PXnypImOjjYBAQEmMDDQdOrUyWzbtu0/f0b27NljOnbsaAICAkzBggXN66+/btLS0kx8fLx5+OGHTb58+UxYWJh57733/tN9utKZM2dMTEyMKVKkiPHx8TFly5Y17777rklLS3PaTpLp3r27+fTTT03FihVNrly5zMKFC40xxhw8eNA89dRTJjQ01Pj4+JiKFSuajz76KN25xo4daypWrGh8fX1NUFCQqVmzppk5c6bTPbh62b9//zVjL1++vAkODjZJSUk3vBcZ/Qzv2LHDREdHmxIlShi73W7CwsLMU089ZY4fP+60b1JSkundu7eJjIw0Pj4+JiQkxDRq1Mhs2bLFsc1vv/1mWrdubcLCwozdbjeFCxc27du3N4mJiY5tIiMjTXR09DWv9/Lvq6lTp2Z47V9//bXjs+Tv728efPBB8/PPPzttc/lz/Mcff5hmzZoZf39/07JlyxveH+BWowJoAYsXL1bJkiV19913Z2r7bt26afr06Wrbtq369eun77//XrGxsdq9e7cWLlzotO0ff/yhtm3bqmvXroqOjtbHH3+szp07q2bNmqpUqZJat26toKAg9e3bV4899pgefPBB+fv7Zyn+X375RQ899JCqVKmiIUOGyG63648//tB333133f1WrVqlZs2aqWTJkho0aJD+/fdfjRs3TnXr1tXWrVtVvHhxp+3btWunEiVKKDY2Vlu3btWUKVMUGhqq4cOHZyrO1q1b67nnntOCBQvUpUsXSZeqf+XLl1eNGjXSbb9v3z4tWrRIjz76qEqUKKEjR45o0qRJql+/vnbt2qWIiAhVqFBBQ4YM0ZtvvqlnnnlG99xzjyQ5/VueOHFCzZo1U4cOHfTEE08oLCwsw/jGjBmjNWvWKDo6WnFxcfL29takSZO0YsUKzZgxQxEREZm6zpuVkpKigwcPKn/+/E7tc+fO1blz5/T888+rQIEC+uGHHzRu3DgdPHhQc+fOddo2NTVVTZo0Ue3atfXee+9p1apVev/991WqVCk9//zzkiRjjFq2bKkNGzboueeeU4UKFbRw4UJFR0eniymrn5H27durQoUKGjZsmJYsWaK3335bwcHBmjRpkho2bKjhw4dr5syZevHFF3XnnXfq3nvvveF9uXjxoo4fP+7UljdvXuXNm1fGGD388MNau3atunbtqmrVqmn58uXq37+//v77b40aNcppvzVr1ujzzz9Xjx49VLBgQRUvXlxHjhxRnTp1ZLPZ1KNHD4WEhGjp0qXq2rWrkpKS1KdPH0nS5MmT1atXL7Vt21a9e/fW+fPn9dNPP+n777/X448/rtatW+u3337T7NmzNWrUKBUsWFCSFBISkuF1/f777/r111/VpUsX5cuX74b3ISMrV67Uvn379NRTTyk8PNwxVOWXX37Rpk2bZLPZJEnPPfec5s2bpx49eqhixYo6ceKENmzYoN27d6tGjRq6cOGCmjRpouTkZPXs2VPh4eH6+++/9dVXXykxMVGBgYHpzp3V310zZsxQdHS0mjRpouHDh+vcuXOaMGGC6tWrp23btjl9llJSUtSkSRPVq1dP7733nvLmzXtT9wf4T9ydgcK1Tp06ZSRl+i/M7du3G0mmW7duTu0vvviikWTWrFnjaIuMjDSSzPr16x1tR48eNXa73fTr18/Rdvkv+yurX8ZkvgI4atQoI8kcO3bsmnFnVD2oVq2aCQ0NNSdOnHC07dixw3h5eZlOnTqlO1+XLl2cjvnII4+YAgUKXPOcV16Hn5+fMcaYtm3bmvvvv98YY0xqaqoJDw83gwcPzvAenD9/3qSmpqa7DrvdboYMGeJo27x5c4aVK2MuVfkkmYkTJ2a47soKoDHGLF++3Egyb7/9ttm3b5/x9/c3rVq1uuE1ZlVkZKR54IEHzLFjx8yxY8fMzp07zZNPPumoUl3p6kqfMcbExsYam81m/vzzT0dbdHS0keR0b4wxpnr16qZmzZqO7xctWmQkmREjRjjaUlJSzD333POfPyPPPPOM0zGLFClibDabGTZsmKP95MmTxtfX11FJutF9UgZVtYEDBzpdy9tvv+20X9u2bY3NZjN//PGHo02S8fLyMr/88ovTtl27djWFChVKVzXr0KGDCQwMdNz/li1bmkqVKl033nffffeGVb/LvvjiCyPJjBo16obbGpPxz3BGn43Zs2en+70TGBiY7nN1pcvV37lz5143hisrgFfGdPXvrqsrgKdPnzZBQUHm6aefdtouISHBBAYGOrVf/hy/8sor140FcDWeAs7hkpKSJCnTf4F//fXXkqSYmBin9suD1K8eK1ixYkVHVUq6VA0oV66c9u3bd9MxX+3y+JsvvvhCaWlpmdrn8OHD2r59uzp37qzg4GBHe5UqVdS4cWPHdV7pueeec/r+nnvu0YkTJxz3MDMef/xxffPNN0pISNCaNWuUkJBwzQHudrvdMeA8NTVVJ06ckL+/v8qVK6etW7dm+px2u11PPfVUprZ94IEH9Oyzz2rIkCFq3bq18uTJo0mTJmX6XFmxYsUKhYSEKCQkRJUrV9aMGTP01FNP6d1333XaztfX1/H12bNndfz4cd19990yxmjbtm3pjpvRv9OVn7evv/5auXLlclQEpUtjtnr27Om03818Rrp16+Z0zFq1askYo65duzrag4KCsvQzULt2ba1cudJp6dSpk+NavL291atXL6d9+vXrJ2OMli5d6tRev359VaxY0fG9MUbz589XixYtZIzR8ePHHUuTJk106tQpx2ctKChIBw8e1ObNmzMV941k9XdPRq78bJw/f17Hjx9XnTp1JMnpZyQoKEjff/+9Dh06lOFxLlf4li9frnPnzt10PNeycuVKJSYm6rHHHnO6x97e3qpdu7bWrl2bbp8rP5+AO5AA5nABAQGSpNOnT2dq+z///FNeXl4qXbq0U3t4eLiCgoL0559/OrUXK1Ys3THy58+vkydP3mTE6bVv315169ZVt27dFBYWpg4dOujzzz+/bjJ4Oc5y5cqlW1ehQgUdP35cZ8+edWq/+loud1Vm5VoefPBB5cuXT3PmzNHMmTN15513pruXl6WlpWnUqFEqU6aM7Ha7ChYsqJCQEP300086depUps9ZuHDhLD3w8d577yk4OFjbt2/X2LFjFRoaesN9jh07poSEBMdy5syZG+5zObFZtmyZ3nvvPQUFBenkyZPpYo2Pj3ckYf7+/goJCVH9+vUlKd19yJMnT7oux6s/b3/++acKFSqUrrvu6s/CrfiMBAYGKk+ePI7u0CvbM/u5KViwoBo1auS0lCxZ0hFjREREuiSqQoUKTtdwWYkSJZy+P3bsmBITE/Xhhx86kvHLy+U/Go4ePSpJevnll+Xv76+77rpLZcqUUffu3W84zOJ6svq7JyP//POPevfurbCwMPn6+iokJMRxjVd+NkaMGKGff/5ZRYsW1V133aVBgwY5JeAlSpRQTEyMpkyZooIFC6pJkyb63//+l6Wfs+v5/fffJUkNGzZMd59XrFjhuMeX5cqVS0WKFLkl5wZuFmMAc7iAgABFRETo559/ztJ+l8fW3Mi1noQzxtz0OVJTU52+9/X11fr167V27VotWbJEy5Yt05w5c9SwYUOtWLHilj2N91+u5TK73a7WrVtr+vTp2rdvnwYNGnTNbYcOHao33nhDXbp00VtvvaXg4GB5eXmpT58+ma50Ss5VkszYtm2b439IO3fu1GOPPXbDfe68806nZGPgwIHXvTbp/xIbSWrSpInKly+vhx56SGPGjHFUmFNTU9W4cWP9888/evnll1W+fHn5+fnp77//VufOndPdh1v55OXNyOj8t+Jzc6tc/Vm4fP+eeOKJDMdASpcqntKlpHLPnj366quvtGzZMs2fP1/jx4/Xm2++qcGDB2c5lvLly0u69Bm7We3atdPGjRvVv39/VatWTf7+/kpLS1PTpk2dPhvt2rXTPffco4ULF2rFihV69913NXz4cC1YsEDNmjWTJL3//vvq3LmzvvjiC61YsUK9evVSbGysNm3a9J+TscuxzJgxQ+Hh4enW58rl/L/aK6v/gLuQAFrAQw89pA8//FBxcXGKioq67raRkZFKS0vT77//7qgySNKRI0eUmJioyMjIWxZX/vz5M5xQ9uqqhiR5eXnp/vvv1/3336+RI0dq6NCheu2117R27VpHknH1dUiX5vW62q+//qqCBQu6bNqFxx9/XB9//LG8vLzUoUOHa243b948NWjQQB999JFTe2JiolNFKbPJeGacPXtWTz31lCpWrKi7775bI0aM0COPPKI777zzuvvNnDnTaZLryxWqrGjevLnq16+voUOH6tlnn5Wfn5927typ3377TdOnT3d0e0qXutRuVmRkpFavXq0zZ844VQGv/iy48zOSWZGRkVq1apVOnz7tVAX89ddfHeuvJyQkRPny5VNqamqGPydX8/PzU/v27dW+fXtduHBBrVu31jvvvKMBAwYoT548Wfosli1bVuXKldMXX3yhMWPGZPnhr5MnT2r16tUaPHiw3nzzTUf75Wrb1QoVKqQXXnhBL7zwgo4ePaoaNWronXfecSSAklS5cmVVrlxZr7/+ujZu3Ki6detq4sSJevvtt7MU29VKlSolSQoNDc3UfQY8AX+CWMBLL70kPz8/devWTUeOHEm3fu/evRozZoykS12YkjR69GinbUaOHCnp0v/Eb5VSpUrp1KlT+umnnxxthw8fTvek8T///JNu38sTIicnJ2d47EKFCqlatWqaPn26U5L5888/a8WKFY7rdIUGDRrorbfe0gcffJBhNeAyb2/vdFWiuXPn6u+//3Zqu5yEZPXtCxl5+eWXFR8fr+nTp2vkyJEqXry4Y3Lm66lbt26GXZQ3c/4TJ05o8uTJkv6venblfTDGOD6PN+PBBx9USkqKJkyY4GhLTU3VuHHjnLZz52cksx588EGlpqbqgw8+cGofNWqUbDabU3KTEW9vb7Vp00bz58/PsBfg8jx30qWnya/k4+OjihUryhjjmKsvq5/FwYMH68SJE+rWrZtSUlLSrV+xYoW++uqra8Yupa+kXv27KTU1NV1XbmhoqCIiIhyf66SkpHTnr1y5sry8vG742c+MJk2aKCAgQEOHDs1wXsMr7zPgKagAWkCpUqU0a9YsxxQWV74JZOPGjZo7d67j/ZdVq1ZVdHS0PvzwQyUmJqp+/fr64YcfNH36dLVq1UoNGjS4ZXF16NBBL7/8sh555BH16tXLMW1C2bJlnQZ4DxkyROvXr1fz5s0VGRmpo0ePavz48SpSpIjq1at3zeO/++67atasmaKiotS1a1fHFB+BgYE37L78L7y8vPT666/fcLuHHnpIQ4YM0VNPPaW7775bO3fu1MyZM9MlV6VKlVJQUJAmTpyofPnyyc/PT7Vr10433utG1qxZo/Hjx2vgwIGOaWmmTp2q++67T2+88YZGjBiRpePdjGbNmumOO+7QyJEj1b17d5UvX16lSpXSiy++qL///lsBAQGaP3/+fxpD2qJFC9WtW1evvPKKDhw4oIoVK2rBggUZjvdy12cks1q0aKEGDRrotdde04EDB1S1alWtWLFCX3zxhfr06eOoPF3PsGHDtHbtWtWuXVtPP/20KlasqH/++Udbt27VqlWrHH9gPfDAAwoPD1fdunUVFham3bt364MPPlDz5s0d1ceaNWtKkl577TV16NBBuXPnVosWLa5ZKW3fvr3jNWrbtm3TY4895ngTyLJly7R69WrNmjUrw30DAgJ07733asSIEbp48aIKFy6sFStWaP/+/U7bnT59WkWKFFHbtm1VtWpV+fv7a9WqVdq8ebPef/99SZc++z169NCjjz6qsmXLKiUlRTNmzHAkyP9VQECAJkyYoCeffFI1atRQhw4dFBISovj4eC1ZskR169ZNl8QDbueWZ4/hFr/99pt5+umnTfHixY2Pj4/Jly+fqVu3rhk3bpzTJM8XL140gwcPNiVKlDC5c+c2RYsWve5E0Fe7evqRa02lYMylCZ7vuOMO4+PjY8qVK2c+/fTTdNPArF692rRs2dJEREQYHx8fExERYR577DHz22+/pTvH1VOlrFq1ytStW9f4+vqagIAA06JFi2tO8nv1NDPXmuz1aldOA3Mt15oGpl+/fqZQoULG19fX1K1b18TFxWU4fcsXX3zhmNz3yuu8PBF0Rq48TlJSkomMjDQ1atQwFy9edNqub9++xsvLy8TFxV33GrLiehMcT5s2zekadu3aZRo1amT8/f1NwYIFzdNPP2127NiR7t/zWvc5o4nDT5w4YZ588knHRNBPPvnkNSeC/i+fkWvFdL1/lytlZiLo06dPm759+5qIiAiTO3duU6ZMmetOBJ2RI0eOmO7du5uiRYua3Llzm/DwcHP//febDz/80LHNpEmTzL333msKFChg7Ha7KVWqlOnfv785deqU07HeeustU7hwYePl5ZXpKWEu/wyHhoaaXLlymZCQENOiRQvzxRdfOLbJ6Gf44MGD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wwIAAGtwZe4x4JUBiomJcWqz2+0ZbpuWlqZatWpp6NChkqTq1avr559/1sSJE2/pA7QeUQH85JNPVLlyZfn6+srX11dVqlTRjBkz3B0WAADAf2a32xUQEOC0XCsBLFSokCpWrOjUVqFCBcXHx0uSwsPDJUlHjhxx2ubIkSOOdZnh9gRw5MiRev755/Xggw/q888/1+eff66mTZvqueee06hRo9wdHgAAsABPeRdw3bp1tWfPHqe23377TZGRkZIuPRASHh6u1atXO9YnJSXp+++/V1RUVKbP4/Yu4HHjxmnChAnq1KmTo+3hhx9WpUqVNGjQIPXt29eN0QEAAGSfvn376u6779bQoUPVrl07/fDDD/rwww/14YcfSrrUVd2nTx+9/fbbKlOmjEqUKKE33nhDERERatWqVabP4/YE8PDhw7r77rvTtd999906fPiwGyICAABW4ynPH9x5551auHChBgwYoCFDhqhEiRIaPXq0Onbs6NjmpZde0tmzZ/XMM88oMTFR9erV07Jly5QnT55Mn8ftCWDp0qX1+eef69VXX3VqnzNnTpZmtAYAAMgJHnroIT300EPXXG+z2TRkyBANGTLkps/h9gRw8ODBat++vdavX6+6detKkr777jutXr1an3/+uZujAwAAVuAhBcBs4/aHQNq0aaPvv/9eBQsW1KJFi7Ro0SIVLFhQP/zwgx555BF3hwcAAJDjuL0CKEk1a9bUp59+6u4wAACARXnKGMDs4vYKIAAAALKX2yqAXl5eN8y2bTabUlJSsikiAABgVRYrALovAVy4cOE118XFxWns2LFKS0vLxogAAIBVWa0L2G0JYMuWLdO17dmzR6+88ooWL16sjh07/qfHmwEAAJAxjxgDeOjQIT399NOqXLmyUlJStH37dk2fPt3x2hMAAABX8pRXwWUXtyaAp06d0ssvv6zSpUvrl19+0erVq7V48WLdcccd7gwLAAAgR3NbF/CIESM0fPhwhYeHa/bs2Rl2CQMAAGQHxgBmk1deeUW+vr4qXbq0pk+frunTp2e43YIFC7I5MgAAgJzNbQlgp06dLJdtAwAAz2S1lMRtCeC0adPcdWoAAABL84hXwQEAALiT1XolSQABAIDlWSz/84x5AAEAAJB9qAACAADLs1oXMBVAAAAAi6ECCAAALI8KIAAAAHI0KoAAAMDyLFYApAII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i4+P16FDhxQRESHp0s+ul5eXypUrp7CwMEVERGjfvn3q2LFjhjH4+PhIktPPa2b2ky7NRtC+fXu1b99ebdu2VdOmTfXPP/8oODg4czcAuA2RACJLKleurI4dO2rs2LFO7f369dOdd96pt956S+3bt1dcXJw++OADp6ftMmKMUUJCgowxSkxMVFxcnIYOHarAwMB0cw9edrnKNm7cOD333HP6+eefrzlH4JAhQ1SgQAGFhYXptddeU8GCBdWqVStJl55MrFOnjnr06KFu3brJz89Pu3bt0sqVK/XBBx9IujQP4Pr169WhQwfZ7XYVLFjwhvt99dVX2rdvn+69917lz59fX3/9tdLS0tIlzcDtKDk5WQkJCUpNTdWRI0e0bNkyxcbG6qGHHlKnTp3SbV+mTBnFx8frs88+05133qklS5Zo4cKF6bbLkyePoqOj9d577ykpKUm9evVSu3btFB4eLkkaPHiwevXqpcDAQDVt2lTJycn68ccfdfLkScXExCg0NFS+vr5atmyZihQpojx58igwMPCG+40cOVKFChVS9erV5eXlpblz5yo8PJxqPXI+dw5AhOfLaND3/v37jY+Pj7n64zNv3jxTsWJFkzt3blOsWDHz7rvvXvfYU6dONZKMJGOz2UxgYKC56667zJAhQ8ypU6ectr36IZBZs2aZ4sWLG7vdbqKiosyXX37pNAD88kMgixcvNpUqVTI+Pj7mrrvuMjt27HA67g8//GAaN25s/P39jZ+fn6lSpYp55513HOvj4uJMlSpVjN1ud7re6+337bffmvr165v8+fMbX19fU6VKFceDJ8DtLDo62vEzmytXLhMSEmIaNWpkPv74Y5OamurYTlc9BNK/f39ToEAB4+/vb9q3b29GjRrl9ADYwIEDTdWqVc348eNNRESEyZMnj2nbtq35559/nM4/c+ZMU61aNePj42Py589v7r33XrNgwQLH+smTJ5uiRYsaLy8vU79+/Uzt9+GHH5pq1aoZPz8/ExAQYO6//36zdevWW3vjAA9kM+b/j7YHAACAJTARNAAAgMWQAAIAAFgMCSAAAIDFkAACAABYDAkgAACAxZAAAgAAWAwJIAAAgMWQAAIAAFgMCSAAj9W5c2fHq/sk6b777lOfPn2yPY5vvvlGNptNiYmJ2X5uAHAFEkAAWda5c2fZbDbZbDb5+PiodOnSGjJkiFJSUlx63gULFlzzvc9XI2kDgGvL5e4AANyemjZtqqlTpyo5OVlff/21unfvrty5c2vAgAFO2124cEE+Pj635JzBwcG35DgAYHVUAAHcFLvdrvDwcEVGRur5559Xo0aN9OWXXzq6bd955x1FRESoXLlykqS//vpL7dq1U1BQkIKDg9WyZUsdOHDAcbzU1FTFxMQoKChIBQoU0EsvvaSrX1V+dRdwcnKyXn75ZRUtWlR2u12lS5fWRx99pAMHDqhBgwaSpPz588tms6lz586SpLS0NMXGxqpEiRLy9fVV1apVNW/ePKfzfP311ypbtqx8fX3VoEEDpzgBICcgAQRwS/j6+urChQuSpNWrV2vPnj1auXKlvvrqK128eFFNmjRRvnz59O233+q7776Tv7+/mjZt6tjn/fff17Rp0/Txxx9rw4YN+ueff7Rw4cLrnrNTp06aPXu2xo4dq927d2vSpEny9/dX0aJFNX/+fEnSnj17dPjwYY0ZM0aSFBsbq08++UQTJ07UL7/8or59++qJJ57QunXrJF1KVFu3bq0WLVpo+/bt6tatm1555RVX3TYAcAu6gAH8J8YYrV69WsuXL1fPnj117Ngx+fn5acqUKY6u308//VRpaWmaMmWKbDabJGnq1KkKCgrSN998owceeECjR4/WgAED1Lp1a0nSxIkTtXz58mue97ffftPnn3+ulStXqlGjRpKkkiVLOtZf7i4ODQ1VUFCQpEsVw6FDh2rVqlWKiopy7LNhwwZNmjRJ9evX14QJE1SqVCm9//77kqRy5cpp586dGj58+C28awDgXiSAAG7KV199JX9/f128eFFpaWl6/PHHNWjQIHXv3l2VK1d2Gve3Y8cO/fHHH8qXL5/TMc6fP6+9e/fq1KlTOnz4sGrXru1YlytXLtWqVStdN/Bl27dvl7e3t+rXr5/pmP/44w+dO3dOjRs3dmq/cOGCqlevLknavXu3UxySHMkiAOQUJIAAbkqDBg00YcIE+fj4KCIiQrly/d+vEz8/P6dtz5w5o5o1a2rmzJnpjhMSEnJT5/f19c3yPmfOnJEkLVmyRIULF3ZaZ7fbbyoOALgdkQACuCl+fn4qXbp0pratUaOG5syZo9DQUAUEBGS4TaFChfT999/r3nvvlSSlpKRoy5YtqlGjRobbV65cWWlpaVq3bp2jC/hKlyuQqampjraKFSvKbrcrPj7+mpXDChUq6Msvv3Rq27Rp040vEgBuIzwEAsDlOnbsqIIFC6ply5b69ttvtX//fn3zzTfq1auXDh48KEnq3bu3hg0bpkWLFunXX3/VCy+8cN05/IoXL67o6Gh16dJFixYtchzz888/lyRFRkbKZrPpq6++0rFjx3TmzBnly5dPL774ovr27avp06dr79692rp1q8aNG6fp06dLkp577jn9/vvv6t+/v/bs2aNZs2Zp2rRprr5FAJCtSAABuFzevHm1fv16FStWTK1bt1aFChXUtWtXnT9/3lER7Nevn5588klFR0crKipK+fLl0yOPPHLd406YMEFt27bVCy+8oPLly+vpp5/W2bNnJUmFCxfW4MGD9corrygsLEw9evSQJL311lt64403FBsbqwoVKqhp06ZasmSJSpQoIUkqVqyY5s+fr0WLFqlq1aqaOHGihg4d6sK7AwDZz2auNcIaAAAAORIVQAAAAIshAQQAALAYEkAAAACLIQEEAACwGBJAAAAAiyEBBAAAsBgSQAAAAIshAQQAALAYEkAAAACLIQEEAACwGBJAAAAAi/l/c5NM+v6j58IAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 800x600 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Import necessary libraries\n",
    "from sklearn.ensemble import RandomForestClassifier\n",
    "from sklearn.metrics import accuracy_score, classification_report, confusion_matrix\n",
    "import pandas as pd\n",
    "from sklearn.model_selection import train_test_split\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "\n",
    "# Load the dataset\n",
    "data = pd.read_csv('Diabetes.csv')\n",
    "\n",
    "# Replace zeros in specific columns (except 'Pregnancies')\n",
    "columns_to_replace = ['Glucose', 'BloodPressure', 'SkinThickness', 'Insulin', 'BMI']\n",
    "for col in columns_to_replace:\n",
    "    data[col].replace(0, data[col].mean(), inplace=True)\n",
    "\n",
    "# Define features (X) and target (y)\n",
    "X = data.drop(columns=['Outcome'])\n",
    "y = data['Outcome']\n",
    "\n",
    "# Split data 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",
    "\n",
    "# Initialize Random Forest model\n",
    "rf_model = RandomForestClassifier(n_estimators=100, random_state=42)\n",
    "\n",
    "# Train the model\n",
    "rf_model.fit(X_train, y_train)\n",
    "\n",
    "# Predict on the test set\n",
    "y_pred = rf_model.predict(X_test)\n",
    "\n",
    "# Evaluate the model\n",
    "accuracy = accuracy_score(y_test, y_pred)\n",
    "print(\"Accuracy:\", accuracy)\n",
    "print(\"Classification Report:\\n\", classification_report(y_test, y_pred))\n",
    "\n",
    "# Confusion Matrix\n",
    "cm = confusion_matrix(y_test, y_pred)\n",
    "\n",
    "# Visualize Confusion Matrix\n",
    "plt.figure(figsize=(8, 6))\n",
    "sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=['No Diabetes', 'Diabetes'], yticklabels=['No Diabetes', 'Diabetes'])\n",
    "plt.xlabel('Predicted')\n",
    "plt.ylabel('Actual')\n",
    "plt.title('Confusion Matrix - Random Forest Classifier')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "0d29db19-c4a4-46b8-a0cd-7826ed3d6758",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.feature_selection import RFE\n",
    "from sklearn.ensemble import RandomForestClassifier\n",
    "import pandas as pd\n",
    "from sklearn.model_selection import train_test_split"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "8be68613-37ba-4046-817c-0a9bf4d0cba6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Selected Features: Index(['Glucose', 'BloodPressure', 'BMI', 'DiabetesPedigreeFunction', 'Age'], dtype='object')\n"
     ]
    }
   ],
   "source": [
    "# Initialize Random Forest model\n",
    "rf_model = RandomForestClassifier(random_state=42)\n",
    "\n",
    "# Apply RFE\n",
    "rfe = RFE(estimator=rf_model, n_features_to_select=5)  # Select top 5 features\n",
    "rfe.fit(X_train, y_train)\n",
    "\n",
    "# Get the selected features\n",
    "selected_features = X_train.columns[rfe.support_]\n",
    "print(\"Selected Features:\", selected_features)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "ac2a2082-c22d-47e7-b359-35870e67af49",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy: 0.7662337662337663\n",
      "Classification Report:\n",
      "               precision    recall  f1-score   support\n",
      "\n",
      "           0       0.83      0.80      0.81        99\n",
      "           1       0.66      0.71      0.68        55\n",
      "\n",
      "    accuracy                           0.77       154\n",
      "   macro avg       0.75      0.75      0.75       154\n",
      "weighted avg       0.77      0.77      0.77       154\n",
      "\n",
      "Confusion Matrix:\n",
      " [[79 20]\n",
      " [16 39]]\n"
     ]
    }
   ],
   "source": [
    "# Transform the dataset to only include selected features\n",
    "X_train_selected = rfe.transform(X_train)\n",
    "X_test_selected = rfe.transform(X_test)\n",
    "\n",
    "# Train the Random Forest model with selected features\n",
    "rf_model.fit(X_train_selected, y_train)\n",
    "\n",
    "# Make predictions and evaluate performance\n",
    "from sklearn.metrics import accuracy_score, classification_report, confusion_matrix\n",
    "\n",
    "y_pred = rf_model.predict(X_test_selected)\n",
    "print(\"Accuracy:\", accuracy_score(y_test, y_pred))\n",
    "print(\"Classification Report:\\n\", classification_report(y_test, y_pred))\n",
    "print(\"Confusion Matrix:\\n\", confusion_matrix(y_test, y_pred))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "f13711ed-152a-4834-b461-6fa5fc323232",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy: 0.7662337662337663\n",
      "Classification Report:\n",
      "               precision    recall  f1-score   support\n",
      "\n",
      " No Diabetes       0.83      0.80      0.81        99\n",
      "    Diabetes       0.66      0.71      0.68        55\n",
      "\n",
      "    accuracy                           0.77       154\n",
      "   macro avg       0.75      0.75      0.75       154\n",
      "weighted avg       0.77      0.77      0.77       154\n",
      "\n",
      "Confusion Matrix:\n",
      " [[79 20]\n",
      " [16 39]]\n"
     ]
    }
   ],
   "source": [
    "from sklearn.metrics import accuracy_score, classification_report, confusion_matrix\n",
    "\n",
    "# Accuracy\n",
    "accuracy = accuracy_score(y_test, y_pred)\n",
    "print(\"Accuracy:\", accuracy)\n",
    "\n",
    "# Classification Report\n",
    "report = classification_report(y_test, y_pred, target_names=['No Diabetes', 'Diabetes'])\n",
    "print(\"Classification Report:\\n\", report)\n",
    "\n",
    "# Confusion Matrix\n",
    "cm = confusion_matrix(y_test, y_pred)\n",
    "print(\"Confusion Matrix:\\n\", cm)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "03448f98-06be-487a-99f4-76f04534073d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Fitting 5 folds for each of 27 candidates, totalling 135 fits\n",
      "[CV] END max_depth=None, min_samples_split=2, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=None, min_samples_split=2, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=None, min_samples_split=2, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=None, min_samples_split=2, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=None, min_samples_split=2, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=None, min_samples_split=2, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=None, min_samples_split=2, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=None, min_samples_split=2, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=None, min_samples_split=2, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=None, min_samples_split=2, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=None, min_samples_split=2, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=None, min_samples_split=2, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=None, min_samples_split=2, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=None, min_samples_split=2, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=None, min_samples_split=2, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=None, min_samples_split=5, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=None, min_samples_split=5, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=None, min_samples_split=5, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=None, min_samples_split=5, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=None, min_samples_split=5, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=None, min_samples_split=5, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=None, min_samples_split=5, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=None, min_samples_split=5, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=None, min_samples_split=5, n_estimators=100; total time=   0.0s\n",
      "[CV] END max_depth=None, min_samples_split=5, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=None, min_samples_split=5, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=None, min_samples_split=5, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=None, min_samples_split=5, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=None, min_samples_split=5, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=None, min_samples_split=5, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=None, min_samples_split=10, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=None, min_samples_split=10, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=None, min_samples_split=10, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=None, min_samples_split=10, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=None, min_samples_split=10, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=None, min_samples_split=10, n_estimators=100; total time=   0.0s\n",
      "[CV] END max_depth=None, min_samples_split=10, n_estimators=100; total time=   0.0s\n",
      "[CV] END max_depth=None, min_samples_split=10, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=None, min_samples_split=10, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=None, min_samples_split=10, n_estimators=100; total time=   0.0s\n",
      "[CV] END max_depth=None, min_samples_split=10, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=None, min_samples_split=10, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=None, min_samples_split=10, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=None, min_samples_split=10, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=None, min_samples_split=10, n_estimators=200; total time=   0.2s\n",
      "[CV] END .max_depth=10, min_samples_split=2, n_estimators=50; total time=   0.0s\n",
      "[CV] END .max_depth=10, min_samples_split=2, n_estimators=50; total time=   0.0s\n",
      "[CV] END .max_depth=10, min_samples_split=2, n_estimators=50; total time=   0.0s\n",
      "[CV] END .max_depth=10, min_samples_split=2, n_estimators=50; total time=   0.0s\n",
      "[CV] END .max_depth=10, min_samples_split=2, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=10, min_samples_split=2, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=10, min_samples_split=2, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=10, min_samples_split=2, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=10, min_samples_split=2, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=10, min_samples_split=2, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=10, min_samples_split=2, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=10, min_samples_split=2, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=10, min_samples_split=2, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=10, min_samples_split=2, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=10, min_samples_split=2, n_estimators=200; total time=   0.2s\n",
      "[CV] END .max_depth=10, min_samples_split=5, n_estimators=50; total time=   0.0s\n",
      "[CV] END .max_depth=10, min_samples_split=5, n_estimators=50; total time=   0.0s\n",
      "[CV] END .max_depth=10, min_samples_split=5, n_estimators=50; total time=   0.0s\n",
      "[CV] END .max_depth=10, min_samples_split=5, n_estimators=50; total time=   0.0s\n",
      "[CV] END .max_depth=10, min_samples_split=5, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=10, min_samples_split=5, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=10, min_samples_split=5, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=10, min_samples_split=5, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=10, min_samples_split=5, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=10, min_samples_split=5, n_estimators=100; total time=   0.0s\n",
      "[CV] END max_depth=10, min_samples_split=5, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=10, min_samples_split=5, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=10, min_samples_split=5, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=10, min_samples_split=5, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=10, min_samples_split=5, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=10, min_samples_split=10, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=10, min_samples_split=10, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=10, min_samples_split=10, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=10, min_samples_split=10, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=10, min_samples_split=10, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=10, min_samples_split=10, n_estimators=100; total time=   0.0s\n",
      "[CV] END max_depth=10, min_samples_split=10, n_estimators=100; total time=   0.0s\n",
      "[CV] END max_depth=10, min_samples_split=10, n_estimators=100; total time=   0.0s\n",
      "[CV] END max_depth=10, min_samples_split=10, n_estimators=100; total time=   0.0s\n",
      "[CV] END max_depth=10, min_samples_split=10, n_estimators=100; total time=   0.0s\n",
      "[CV] END max_depth=10, min_samples_split=10, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=10, min_samples_split=10, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=10, min_samples_split=10, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=10, min_samples_split=10, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=10, min_samples_split=10, n_estimators=200; total time=   0.2s\n",
      "[CV] END .max_depth=20, min_samples_split=2, n_estimators=50; total time=   0.0s\n",
      "[CV] END .max_depth=20, min_samples_split=2, n_estimators=50; total time=   0.0s\n",
      "[CV] END .max_depth=20, min_samples_split=2, n_estimators=50; total time=   0.0s\n",
      "[CV] END .max_depth=20, min_samples_split=2, n_estimators=50; total time=   0.0s\n",
      "[CV] END .max_depth=20, min_samples_split=2, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=20, min_samples_split=2, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=20, min_samples_split=2, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=20, min_samples_split=2, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=20, min_samples_split=2, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=20, min_samples_split=2, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=20, min_samples_split=2, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=20, min_samples_split=2, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=20, min_samples_split=2, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=20, min_samples_split=2, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=20, min_samples_split=2, n_estimators=200; total time=   0.2s\n",
      "[CV] END .max_depth=20, min_samples_split=5, n_estimators=50; total time=   0.0s\n",
      "[CV] END .max_depth=20, min_samples_split=5, n_estimators=50; total time=   0.0s\n",
      "[CV] END .max_depth=20, min_samples_split=5, n_estimators=50; total time=   0.0s\n",
      "[CV] END .max_depth=20, min_samples_split=5, n_estimators=50; total time=   0.0s\n",
      "[CV] END .max_depth=20, min_samples_split=5, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=20, min_samples_split=5, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=20, min_samples_split=5, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=20, min_samples_split=5, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=20, min_samples_split=5, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=20, min_samples_split=5, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=20, min_samples_split=5, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=20, min_samples_split=5, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=20, min_samples_split=5, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=20, min_samples_split=5, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=20, min_samples_split=5, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=20, min_samples_split=10, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=20, min_samples_split=10, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=20, min_samples_split=10, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=20, min_samples_split=10, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=20, min_samples_split=10, n_estimators=50; total time=   0.0s\n",
      "[CV] END max_depth=20, min_samples_split=10, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=20, min_samples_split=10, n_estimators=100; total time=   0.0s\n",
      "[CV] END max_depth=20, min_samples_split=10, n_estimators=100; total time=   0.0s\n",
      "[CV] END max_depth=20, min_samples_split=10, n_estimators=100; total time=   0.0s\n",
      "[CV] END max_depth=20, min_samples_split=10, n_estimators=100; total time=   0.1s\n",
      "[CV] END max_depth=20, min_samples_split=10, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=20, min_samples_split=10, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=20, min_samples_split=10, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=20, min_samples_split=10, n_estimators=200; total time=   0.2s\n",
      "[CV] END max_depth=20, min_samples_split=10, n_estimators=200; total time=   0.2s\n",
      "Best Parameters: {'max_depth': None, 'min_samples_split': 2, 'n_estimators': 100}\n"
     ]
    }
   ],
   "source": [
    "from sklearn.model_selection import GridSearchCV\n",
    "from sklearn.ensemble import RandomForestClassifier\n",
    "\n",
    "# Define hyperparameter grid for Random Forest\n",
    "param_grid = {\n",
    "    \"n_estimators\": [50, 100, 200],       # Number of trees in the forest\n",
    "    \"max_depth\": [None, 10, 20],         # Maximum depth of each tree\n",
    "    \"min_samples_split\": [2, 5, 10]      # Minimum samples required to split an internal node\n",
    "}\n",
    "\n",
    "# Initialize Random Forest model\n",
    "rf = RandomForestClassifier(random_state=42)  # Always set a random state for reproducibility\n",
    "\n",
    "# Apply Grid Search with 5-fold Cross-Validation\n",
    "grid_search = GridSearchCV(estimator=rf, param_grid=param_grid, cv=5, scoring=\"accuracy\", verbose=2)\n",
    "grid_search.fit(X_train, y_train)\n",
    "\n",
    "# Output the best parameters\n",
    "print(\"Best Parameters:\", grid_search.best_params_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "6e0f712f-b846-4a4c-842c-7959ca544505",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy: 0.7662337662337663\n",
      "Classification Report:\n",
      "               precision    recall  f1-score   support\n",
      "\n",
      "           0       0.83      0.80      0.81        99\n",
      "           1       0.66      0.71      0.68        55\n",
      "\n",
      "    accuracy                           0.77       154\n",
      "   macro avg       0.75      0.75      0.75       154\n",
      "weighted avg       0.77      0.77      0.77       154\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Retrieve the best estimator\n",
    "best_rf = grid_search.best_estimator_\n",
    "\n",
    "# Fit the optimized model on the training data\n",
    "best_rf.fit(X_train, y_train)\n",
    "\n",
    "# Make predictions\n",
    "y_pred = best_rf.predict(X_test)\n",
    "\n",
    "# Evaluate performance\n",
    "from sklearn.metrics import accuracy_score, classification_report, confusion_matrix\n",
    "print(\"Accuracy:\", accuracy_score(y_test, y_pred))\n",
    "print(\"Classification Report:\\n\", classification_report(y_test, y_pred))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "5ccd2db9-1aeb-4d18-a60e-c99b3a917aa5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Selected Features: Index(['Glucose', 'BloodPressure', 'BMI', 'DiabetesPedigreeFunction', 'Age'], dtype='object')\n"
     ]
    }
   ],
   "source": [
    "from sklearn.feature_selection import RFE\n",
    "from sklearn.ensemble import RandomForestClassifier\n",
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "# Split the original data 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",
    "\n",
    "# Initialize the model\n",
    "rf_model = RandomForestClassifier(random_state=42)\n",
    "\n",
    "# Apply RFE\n",
    "rfe = RFE(estimator=rf_model, n_features_to_select=5)  # Select top 5 features\n",
    "rfe.fit(X_train, y_train)\n",
    "\n",
    "# Transform training and testing sets based on selected features\n",
    "X_train_rfe = rfe.transform(X_train)\n",
    "X_test_rfe = rfe.transform(X_test)\n",
    "\n",
    "# View selected features\n",
    "selected_features = X.columns[rfe.support_]\n",
    "print(\"Selected Features:\", selected_features)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "5edb4f54-da85-4773-9e57-97715cbde49e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model Accuracy after RFE: 0.77\n"
     ]
    }
   ],
   "source": [
    "from sklearn.metrics import accuracy_score\n",
    "\n",
    "# Train the model on selected features\n",
    "model = RandomForestClassifier(random_state=42)\n",
    "model.fit(X_train_rfe, y_train)\n",
    "\n",
    "# Make predictions on the test set\n",
    "y_pred = model.predict(X_test_rfe)\n",
    "\n",
    "# Evaluate model performance\n",
    "accuracy = accuracy_score(y_test, y_pred)\n",
    "print(f\"Model Accuracy after RFE: {accuracy:.2f}\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
