{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "a4eee0a0",
   "metadata": {},
   "source": [
    "# Étape 1 — Chargement et exploration initiale"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "49ac00e2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(116, 10)\n",
      "   Age        BMI  Glucose  Insulin      HOMA   Leptin  Adiponectin  Resistin  \\\n",
      "0   48  23.500000       70    2.707  0.467409   8.8071     9.702400   7.99585   \n",
      "1   83  20.690495       92    3.115  0.706897   8.8438     5.429285   4.06405   \n",
      "2   82  23.124670       91    4.498  1.009651  17.9393    22.432040   9.27715   \n",
      "3   68  21.367521       77    3.226  0.612725   9.8827     7.169560  12.76600   \n",
      "4   86  21.111111       92    3.549  0.805386   6.6994     4.819240  10.57635   \n",
      "\n",
      "     MCP.1  Classification  \n",
      "0  417.114               1  \n",
      "1  468.786               1  \n",
      "2  554.697               1  \n",
      "3  928.220               1  \n",
      "4  773.920               1  \n",
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 116 entries, 0 to 115\n",
      "Data columns (total 10 columns):\n",
      " #   Column          Non-Null Count  Dtype  \n",
      "---  ------          --------------  -----  \n",
      " 0   Age             116 non-null    int64  \n",
      " 1   BMI             116 non-null    float64\n",
      " 2   Glucose         116 non-null    int64  \n",
      " 3   Insulin         116 non-null    float64\n",
      " 4   HOMA            116 non-null    float64\n",
      " 5   Leptin          116 non-null    float64\n",
      " 6   Adiponectin     116 non-null    float64\n",
      " 7   Resistin        116 non-null    float64\n",
      " 8   MCP.1           116 non-null    float64\n",
      " 9   Classification  116 non-null    int64  \n",
      "dtypes: float64(7), int64(3)\n",
      "memory usage: 9.2 KB\n",
      "Les variables explicative sont : ['Age', 'BMI', 'Glucose', 'Insulin', 'HOMA', 'Leptin', 'Adiponectin', 'Resistin', 'MCP.1']\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 79116 characters]",
      "text/plain": [
       "<Figure size 1200x800 with 12 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Import des bibliothèques\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "\n",
    "# Chargement des données\n",
    "data = pd.read_csv('breast+cancer+coimbra/dataR2.csv')\n",
    "\n",
    "# Aperçu des données\n",
    "print(data.shape)\n",
    "print(data.head())\n",
    "data.info()\n",
    "\n",
    "# Liste des variables explicatives\n",
    "features = data.columns[:-1]\n",
    "print(\"Les variables explicative sont :\", list(features))\n",
    "target = 'Classification'\n",
    "\n",
    "# Histogrammes des variables\n",
    "data.hist(bins=50, figsize=(12, 8))\n",
    "plt.suptitle(\"Histogrammes des variables\", fontsize=16)\n",
    "plt.tight_layout()\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4c223d85",
   "metadata": {},
   "source": [
    "# Étape 2 — Split du dataset en train et test\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "d6e94a0e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train : (92, 9) (92,)\n",
      "Test  : (24, 9) (24,)\n"
     ]
    }
   ],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "# Séparation des features et de la cible\n",
    "X = data.drop(columns='Classification')\n",
    "y = data['Classification'].map({2: 0, 1: 1})\n",
    "# Mapping : 1 = patient malade (positif), 2 = patient sain (négatif)\n",
    "# On recode pour avoir : 1 → malade (classe positive), 0 → sain\n",
    "\n",
    "\n",
    "# Split stratifié pour préserver la distribution des classes\n",
    "X_train, X_test, y_train, y_test = train_test_split(\n",
    "    X, y,\n",
    "    test_size=0.2,\n",
    "    random_state=42,\n",
    "    stratify=y)\n",
    "\n",
    "# Vérification de la forme\n",
    "print(\"Train :\", X_train.shape, y_train.shape)\n",
    "print(\"Test  :\", X_test.shape, y_test.shape)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a37cbc41",
   "metadata": {},
   "source": [
    "# Étape 3 — Visualisation des distributions par classe du dataset d'entrainement"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "7183e1ac",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 115384 characters]",
      "text/plain": [
       "<Figure size 1500x1200 with 9 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 130528 characters]",
      "text/plain": [
       "<Figure size 1500x1200 with 9 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 219856 characters]",
      "text/plain": [
       "<Figure size 1500x1200 with 9 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "import numpy as np\n",
    "\n",
    "# Fusion temporaire\n",
    "train_data = X_train.copy()\n",
    "train_data['Classification'] = y_train\n",
    "\n",
    "variables = X_train.columns.tolist()\n",
    "n_cols = 3\n",
    "n_rows = int(np.ceil(len(variables) / n_cols))\n",
    "\n",
    "# =======================\n",
    "# 🔹 1. Tous les histogrammes\n",
    "# =======================\n",
    "fig, axes = plt.subplots(n_rows, n_cols, figsize=(5 * n_cols, 4 * n_rows))\n",
    "axes = axes.flatten()\n",
    "\n",
    "for i, col in enumerate(variables):\n",
    "    for classe in y_train.unique():\n",
    "        axes[i].hist(X_train[y_train == classe][col], bins=30, alpha=0.5, label=f\"Classe {classe}\")\n",
    "    axes[i].set_title(f\"{col} selon la classe\")\n",
    "    axes[i].legend()\n",
    "    \n",
    "for j in range(i + 1, len(axes)):\n",
    "    fig.delaxes(axes[j])\n",
    "\n",
    "fig.suptitle(\"Histogrammes par classe\", fontsize=16)\n",
    "plt.tight_layout(rect=[0, 0, 1, 0.97])\n",
    "plt.show()\n",
    "\n",
    "\n",
    "# =======================\n",
    "# 🔹 2. Tous les boxplots\n",
    "# =======================\n",
    "fig, axes = plt.subplots(n_rows, n_cols, figsize=(5 * n_cols, 4 * n_rows))\n",
    "axes = axes.flatten()\n",
    "\n",
    "for i, col in enumerate(variables):\n",
    "    sns.boxplot(x=y_train, y=X_train[col], ax=axes[i])\n",
    "    axes[i].set_title(f\"Boxplot de {col}\")\n",
    "    axes[i].set_xlabel(\"Classe\")\n",
    "    axes[i].set_ylabel(col)\n",
    "\n",
    "for j in range(i + 1, len(axes)):\n",
    "    fig.delaxes(axes[j])\n",
    "\n",
    "fig.suptitle(\"Boxplots par classe\", fontsize=16)\n",
    "plt.tight_layout(rect=[0, 0, 1, 0.97])\n",
    "plt.show()\n",
    "\n",
    "\n",
    "# =======================\n",
    "# 🔹 3. Tous les scatter (jittered)\n",
    "# =======================\n",
    "fig, axes = plt.subplots(n_rows, n_cols, figsize=(5 * n_cols, 4 * n_rows))\n",
    "axes = axes.flatten()\n",
    "\n",
    "for i, col in enumerate(variables):\n",
    "    for classe in y_train.unique():\n",
    "        axes[i].scatter(\n",
    "            X_train[y_train == classe][col],\n",
    "            np.random.normal(loc=classe, scale=0.02, size=X_train[y_train == classe][col].shape),\n",
    "            alpha=0.5,\n",
    "            label=f\"Classe {classe}\"\n",
    "        )\n",
    "    axes[i].set_title(f\"{col} (scatter jittered)\")\n",
    "    axes[i].legend()\n",
    "\n",
    "for j in range(i + 1, len(axes)):\n",
    "    fig.delaxes(axes[j])\n",
    "\n",
    "fig.suptitle(\"Scatter plots (jittered) par classe\", fontsize=16)\n",
    "plt.tight_layout(rect=[0, 0, 1, 0.97])\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "87ecefeb",
   "metadata": {},
   "source": [
    "# Étape 4 — Matrice de corrélation et scatter matrix (train uniquement)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "34fd9b1c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 110644 characters]",
      "text/plain": [
       "<Figure size 1000x800 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 463160 characters]",
      "text/plain": [
       "<Figure size 1200x800 with 81 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from pandas.plotting import scatter_matrix\n",
    "# Matrice de corrélation (sur les données d'entraînement)\n",
    "corr_matrix = X_train.corr()\n",
    "\n",
    "plt.figure(figsize=(10, 8))\n",
    "sns.heatmap(corr_matrix, annot=True, fmt=\".2f\", cmap='coolwarm', square=True)\n",
    "plt.title(\"Matrice de corrélation (X_train)\")\n",
    "plt.tight_layout()\n",
    "plt.show()\n",
    "\n",
    "# DataFrame combiné pour visualisation colorée\n",
    "X_train_visu = X_train.copy()\n",
    "X_train_visu['Classification'] = y_train.values\n",
    "\n",
    "# Scatter matrix colorée\n",
    "scatter_matrix(X_train_visu.drop(columns='Classification'),\n",
    "               figsize=(12, 8),\n",
    "               diagonal='kde',\n",
    "               c=X_train_visu['Classification'],\n",
    "               cmap='coolwarm',\n",
    "               alpha=0.7)\n",
    "plt.suptitle(\"Matrice de dispersion colorée (X_train)\", y=1.02)\n",
    "plt.tight_layout()\n",
    "plt.show()\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "68c850ac",
   "metadata": {},
   "source": [
    "# Étape 5 — Transformation logarithmique "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "7c80e86d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 119928 characters]",
      "text/plain": [
       "<Figure size 1500x1200 with 9 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 134940 characters]",
      "text/plain": [
       "<Figure size 1500x1200 with 9 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 218312 characters]",
      "text/plain": [
       "<Figure size 1500x1200 with 9 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Variables à transformer (forte asymétrie identifiée précédemment) \n",
    "variables_log = ['Insulin', 'HOMA', 'MCP.1', 'Resistin']\n",
    "\n",
    "# Copie de X_train pour transformation\n",
    "X_train_transformed = X_train.copy()\n",
    "\n",
    "# Transformation log(x + 1)\n",
    "for col in variables_log:\n",
    "    X_train_transformed[col + '_log'] = np.log1p(X_train_transformed[col])\n",
    "    \n",
    "# Suppression des colonnes d'origine (optionnelle mais recommandée)\n",
    "X_train_transformed = X_train_transformed.drop(columns=variables_log)\n",
    "\n",
    "# Mise à jour de la liste des variables\n",
    "features = X_train_transformed.columns.tolist()\n",
    "\n",
    "# Fusion temporaire pour les visualisations\n",
    "train_data2 = X_train_transformed.copy()\n",
    "train_data2['Classification'] = y_train\n",
    "\n",
    "n_cols = 3\n",
    "n_rows = int(np.ceil(len(features) / n_cols))\n",
    "\n",
    "# Histogrammes\n",
    "fig, axes = plt.subplots(n_rows, n_cols, figsize=(5 * n_cols, 4 * n_rows))\n",
    "axes = axes.flatten()\n",
    "\n",
    "for i, col in enumerate(features):\n",
    "    for classe in y_train.unique():\n",
    "        axes[i].hist(X_train_transformed[y_train == classe][col], bins=30, alpha=0.5, label=f\"Classe {classe}\")\n",
    "    axes[i].set_title(f\"{col} selon la classe\")\n",
    "    axes[i].legend()\n",
    "    \n",
    "for j in range(i + 1, len(axes)):\n",
    "    fig.delaxes(axes[j])\n",
    "\n",
    "fig.suptitle(\"Histogrammes par classe (après tranformation)\", fontsize=16)\n",
    "plt.tight_layout(rect=[0, 0, 1, 0.97])\n",
    "plt.show()\n",
    "\n",
    "# Boxplots\n",
    "fig, axes = plt.subplots(n_rows, n_cols, figsize=(5 * n_cols, 4 * n_rows))\n",
    "axes = axes.flatten()\n",
    "\n",
    "for i, col in enumerate(features):\n",
    "    sns.boxplot(x=y_train, y=X_train_transformed[col], ax=axes[i])\n",
    "    axes[i].set_title(f\"Boxplot de {col}\")\n",
    "    axes[i].set_xlabel(\"Classe\")\n",
    "    axes[i].set_ylabel(col)\n",
    "\n",
    "for j in range(i + 1, len(axes)):\n",
    "    fig.delaxes(axes[j])\n",
    "\n",
    "fig.suptitle(\"Boxplots par classe (après tranformation)\", fontsize=16)\n",
    "plt.tight_layout(rect=[0, 0, 1, 0.97])\n",
    "plt.show()\n",
    "\n",
    "# Scatter plots\n",
    "fig, axes = plt.subplots(n_rows, n_cols, figsize=(5 * n_cols, 4 * n_rows))\n",
    "axes = axes.flatten()\n",
    "\n",
    "for i, col in enumerate(features):\n",
    "    for classe in y_train.unique():\n",
    "        axes[i].scatter(\n",
    "            X_train_transformed[y_train == classe][col],\n",
    "            np.random.normal(loc=classe, scale=0.02, size=X_train_transformed[y_train == classe][col].shape),\n",
    "            alpha=0.5,\n",
    "            label=f\"Classe {classe}\"\n",
    "        )\n",
    "    axes[i].set_title(f\"{col} (scatter jittered)\")\n",
    "    axes[i].legend()\n",
    "\n",
    "for j in range(i + 1, len(axes)):\n",
    "    fig.delaxes(axes[j])\n",
    "\n",
    "fig.suptitle(\"Scatter plots (jittered) par classe (après tranformation)\", fontsize=16)\n",
    "plt.tight_layout(rect=[0, 0, 1, 0.97])\n",
    "plt.show()\n",
    "\n",
    "\n",
    "    \n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "102a1a80",
   "metadata": {},
   "source": [
    "# Étape 6 — Standardisation (StandardScaler)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "3874217a",
   "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>mean</th>\n",
       "      <th>std</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>Age</th>\n",
       "      <td>1.037817e-16</td>\n",
       "      <td>1.005479</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>BMI</th>\n",
       "      <td>-8.447349e-17</td>\n",
       "      <td>1.005479</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Glucose</th>\n",
       "      <td>1.995309e-16</td>\n",
       "      <td>1.005479</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Leptin</th>\n",
       "      <td>6.033821e-17</td>\n",
       "      <td>1.005479</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Adiponectin</th>\n",
       "      <td>1.436049e-16</td>\n",
       "      <td>1.005479</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Insulin_log</th>\n",
       "      <td>2.292852e-16</td>\n",
       "      <td>1.005479</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>HOMA_log</th>\n",
       "      <td>-3.891814e-16</td>\n",
       "      <td>1.005479</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>MCP.1_log</th>\n",
       "      <td>-7.406515e-16</td>\n",
       "      <td>1.005479</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Resistin_log</th>\n",
       "      <td>-1.680419e-16</td>\n",
       "      <td>1.005479</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                      mean       std\n",
       "Age           1.037817e-16  1.005479\n",
       "BMI          -8.447349e-17  1.005479\n",
       "Glucose       1.995309e-16  1.005479\n",
       "Leptin        6.033821e-17  1.005479\n",
       "Adiponectin   1.436049e-16  1.005479\n",
       "Insulin_log   2.292852e-16  1.005479\n",
       "HOMA_log     -3.891814e-16  1.005479\n",
       "MCP.1_log    -7.406515e-16  1.005479\n",
       "Resistin_log -1.680419e-16  1.005479"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "# Initialisation du scaler\n",
    "scaler = StandardScaler()\n",
    "\n",
    "# Entraînement du scaler sur le jeu transformé\n",
    "X_train_scaled = pd.DataFrame(\n",
    "    scaler.fit_transform(X_train_transformed),\n",
    "    columns=X_train_transformed.columns,\n",
    "    index=X_train_transformed.index\n",
    ")\n",
    "\n",
    "X_train_scaled.describe().T[['mean', 'std']]\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9587225f",
   "metadata": {},
   "source": [
    "# Étape 7 — Préparation de X_test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "69e275ee",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Copie de X_test\n",
    "X_test_transformed = X_test.copy()\n",
    "\n",
    "# Appliquer les mêmes log-transforms\n",
    "for col in variables_log:\n",
    "    X_test_transformed[col + '_log'] = np.log1p(X_test_transformed[col])\n",
    "\n",
    "# Supprimer les colonnes originales\n",
    "X_test_transformed = X_test_transformed.drop(columns=variables_log)\n",
    "\n",
    "# Standardiser avec le scaler déjà entraîné sur X_train\n",
    "X_test_scaled = pd.DataFrame(\n",
    "    scaler.transform(X_test_transformed),\n",
    "    columns=X_test_transformed.columns,\n",
    "    index=X_test_transformed.index\n",
    ")\n",
    "\n",
    "# Vérifie que les colonnes de X_test sont identiques (et dans le même ordre) à celles de X_train, pour éviter des erreurs de prédiction\n",
    "if list(X_train_scaled.columns) != list(X_test_scaled.columns):\n",
    "    print( \"Mismatch between train and test columns\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3c346b2e",
   "metadata": {},
   "source": [
    "# Étape 8 — Modélisation avec SVM (rbf)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "0f47855f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy : 0.75\n",
      "F1-score : 0.727\n",
      "\n",
      "Classification report :\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.77      0.77      0.77        13\n",
      "           1       0.73      0.73      0.73        11\n",
      "\n",
      "    accuracy                           0.75        24\n",
      "   macro avg       0.75      0.75      0.75        24\n",
      "weighted avg       0.75      0.75      0.75        24\n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 20688 characters]",
      "text/plain": [
       "<Figure size 600x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 44868 characters]",
      "text/plain": [
       "<Figure size 800x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\n",
    "from sklearn.svm import SVC\n",
    "from sklearn.metrics import accuracy_score, f1_score, classification_report, confusion_matrix, roc_curve, auc\n",
    "\n",
    "# Initialisation du modèle\n",
    "svm_rbf = SVC(kernel='rbf', C=1.0, gamma='scale', probability=True, random_state=42)\n",
    "\n",
    "# Entraînement\n",
    "svm_rbf.fit(X_train_scaled, y_train)\n",
    "\n",
    "# Prédiction\n",
    "y_pred_svm = svm_rbf.predict(X_test_scaled)\n",
    "y_proba_svm = svm_rbf.predict_proba(X_test_scaled)[:, 1]\n",
    "\n",
    "# Évaluation\n",
    "# Accuracy & F1\n",
    "print(\"Accuracy :\", round(accuracy_score(y_test, y_pred_svm), 3))\n",
    "print(\"F1-score :\", round(f1_score(y_test, y_pred_svm), 3))\n",
    "\n",
    "# Rapport de classification\n",
    "print(\"\\nClassification report :\")\n",
    "print(classification_report(y_test, y_pred_svm))\n",
    "\n",
    "# Matrice de confusion\n",
    "cm = confusion_matrix(y_test, y_pred_svm)\n",
    "plt.figure(figsize=(6, 5))\n",
    "sns.heatmap(cm, annot=True, fmt='d', cmap='Purples', cbar=False,\n",
    "            xticklabels=['Négatif', 'Positif'], yticklabels=['Négatif', 'Positif'])\n",
    "plt.title(\"Matrice de confusion (SVM RBF)\")\n",
    "plt.xlabel(\"Prédictions\")\n",
    "plt.ylabel(\"Réel\")\n",
    "plt.tight_layout()\n",
    "plt.show()\n",
    "\n",
    "# Courbe ROC\n",
    "fpr, tpr, _ = roc_curve(y_test, y_proba_svm)\n",
    "roc_auc = auc(fpr, tpr)\n",
    "\n",
    "plt.figure(figsize=(8, 6))\n",
    "plt.plot(fpr, tpr, label=f\"AUC = {roc_auc:.2f}\")\n",
    "plt.plot([0, 1], [0, 1], linestyle='--', color='red')\n",
    "plt.title(\"Courbe ROC (SVM RBF)\")\n",
    "plt.xlabel(\"Taux de faux positifs (FPR)\")\n",
    "plt.ylabel(\"Taux de vrais positifs (TPR)\")\n",
    "plt.legend(loc=\"lower right\")\n",
    "plt.grid()\n",
    "plt.tight_layout()\n",
    "plt.show()\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7e243135",
   "metadata": {},
   "source": [
    "# Recherche d'hyperparamètres (C et gamma)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "d9267f30",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Meilleurs hyperparamètres : {'C': 10, 'gamma': 0.01, 'kernel': 'rbf'}\n",
      "F1-score moyen sur CV : 0.734\n"
     ]
    }
   ],
   "source": [
    "from sklearn.model_selection import GridSearchCV\n",
    "from sklearn.svm import SVC\n",
    "\n",
    "# Définition de la grille des hyperparamètres\n",
    "param_grid_svm = {\n",
    "    'C': [0.01, 0.1, 1, 10, 100],\n",
    "    'gamma': ['scale', 0.001, 0.01, 0.1, 1],\n",
    "    'kernel': ['rbf']\n",
    "}\n",
    "\n",
    "# Initialisation du modèle\n",
    "svm = SVC(probability=True, random_state=42)\n",
    "\n",
    "# GridSearch avec validation croisée 10 folds\n",
    "grid_search_svm = GridSearchCV(\n",
    "    svm,\n",
    "    param_grid=param_grid_svm,\n",
    "    scoring='f1',\n",
    "    cv=10,\n",
    "    n_jobs=-1\n",
    ")\n",
    "\n",
    "# Entraînement\n",
    "grid_search_svm.fit(X_train_scaled, y_train)\n",
    "\n",
    "# Meilleur modèle trouvé\n",
    "best_svm = grid_search_svm.best_estimator_\n",
    "\n",
    "# Résultats\n",
    "print(\"Meilleurs hyperparamètres :\", grid_search_svm.best_params_)\n",
    "print(\"F1-score moyen sur CV :\", round(grid_search_svm.best_score_, 3))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "5e693675",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy : 0.75\n",
      "F1-score : 0.75\n",
      "\n",
      "Classification report :\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.82      0.69      0.75        13\n",
      "           1       0.69      0.82      0.75        11\n",
      "\n",
      "    accuracy                           0.75        24\n",
      "   macro avg       0.76      0.76      0.75        24\n",
      "weighted avg       0.76      0.75      0.75        24\n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 21596 characters]",
      "text/plain": [
       "<Figure size 600x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 45568 characters]",
      "text/plain": [
       "<Figure size 800x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Prédictions\n",
    "y_pred_best_svm = best_svm.predict(X_test_scaled)\n",
    "y_proba_best_svm = best_svm.predict_proba(X_test_scaled)[:, 1]\n",
    "\n",
    "# Scores\n",
    "print(\"Accuracy :\", round(accuracy_score(y_test, y_pred_best_svm), 3))\n",
    "print(\"F1-score :\", round(f1_score(y_test, y_pred_best_svm), 3))\n",
    "print(\"\\nClassification report :\")\n",
    "print(classification_report(y_test, y_pred_best_svm))\n",
    "\n",
    "# Matrice de confusion\n",
    "cm = confusion_matrix(y_test, y_pred_best_svm)\n",
    "plt.figure(figsize=(6, 5))\n",
    "sns.heatmap(cm, annot=True, fmt='d', cmap='Oranges', cbar=False,\n",
    "            xticklabels=['Négatif', 'Positif'], yticklabels=['Négatif', 'Positif'])\n",
    "plt.title(\"Matrice de confusion (SVM optimisé)\")\n",
    "plt.xlabel(\"Prédictions\")\n",
    "plt.ylabel(\"Réel\")\n",
    "plt.tight_layout()\n",
    "plt.show()\n",
    "\n",
    "# Courbe ROC\n",
    "fpr, tpr, _ = roc_curve(y_test, y_proba_best_svm)\n",
    "roc_auc = auc(fpr, tpr)\n",
    "\n",
    "plt.figure(figsize=(8, 6))\n",
    "plt.plot(fpr, tpr, label=f\"AUC = {roc_auc:.2f}\", color='darkorange')\n",
    "plt.plot([0, 1], [0, 1], linestyle='--', color='gray')\n",
    "plt.title(\"Courbe ROC (SVM optimisé)\")\n",
    "plt.xlabel(\"Taux de faux positifs\")\n",
    "plt.ylabel(\"Taux de vrais positifs\")\n",
    "plt.legend(loc=\"lower right\")\n",
    "plt.grid()\n",
    "plt.tight_layout()\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "68ff641d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "SVM linéaire - Accuracy : 0.75\n",
      "SVM linéaire - F1-score : 0.75\n",
      "\n",
      "Classification Report :\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.82      0.69      0.75        13\n",
      "           1       0.69      0.82      0.75        11\n",
      "\n",
      "    accuracy                           0.75        24\n",
      "   macro avg       0.76      0.76      0.75        24\n",
      "weighted avg       0.76      0.75      0.75        24\n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 20420 characters]",
      "text/plain": [
       "<Figure size 600x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 42484 characters]",
      "text/plain": [
       "<Figure size 800x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from sklearn.svm import SVC\n",
    "from sklearn.metrics import accuracy_score, f1_score, classification_report, confusion_matrix, roc_curve, auc\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "\n",
    "# 1. Initialisation du modèle SVM linéaire\n",
    "svm_linear = SVC(kernel='linear', probability=True, random_state=42)\n",
    "\n",
    "# 2. Entraînement sur le jeu d'entraînement\n",
    "svm_linear.fit(X_train_scaled, y_train)\n",
    "\n",
    "# 3. Prédictions\n",
    "y_pred_svm_lin = svm_linear.predict(X_test_scaled)\n",
    "y_proba_svm_lin = svm_linear.predict_proba(X_test_scaled)[:, 1]\n",
    "\n",
    "# 4. Évaluation\n",
    "acc_lin = accuracy_score(y_test, y_pred_svm_lin)\n",
    "f1_lin = f1_score(y_test, y_pred_svm_lin)\n",
    "print(\"SVM linéaire - Accuracy :\", round(acc_lin, 3))\n",
    "print(\"SVM linéaire - F1-score :\", round(f1_lin, 3))\n",
    "print(\"\\nClassification Report :\")\n",
    "print(classification_report(y_test, y_pred_svm_lin))\n",
    "\n",
    "# 5. Matrice de confusion\n",
    "cm = confusion_matrix(y_test, y_pred_svm_lin)\n",
    "plt.figure(figsize=(6, 5))\n",
    "sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', cbar=False,\n",
    "            xticklabels=['Négatif', 'Positif'],\n",
    "            yticklabels=['Négatif', 'Positif'])\n",
    "plt.title(\"Matrice de confusion — SVM Linéaire\")\n",
    "plt.xlabel(\"Prédiction\")\n",
    "plt.ylabel(\"Réel\")\n",
    "plt.tight_layout()\n",
    "plt.show()\n",
    "\n",
    "# 6. Courbe ROC\n",
    "fpr, tpr, thresholds = roc_curve(y_test, y_proba_svm_lin)\n",
    "roc_auc = auc(fpr, tpr)\n",
    "plt.figure(figsize=(8, 6))\n",
    "plt.plot(fpr, tpr, color='blue', label=f'AUC = {roc_auc:.2f}')\n",
    "plt.plot([0, 1], [0, 1], linestyle='--', color='red')\n",
    "plt.title('Courbe ROC — SVM Linéaire')\n",
    "plt.xlabel('Faux positifs (FPR)')\n",
    "plt.ylabel('Vrais positifs (TPR)')\n",
    "plt.grid()\n",
    "plt.legend(loc='lower right')\n",
    "plt.tight_layout()\n",
    "plt.show()\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
