{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":3004,"databundleVersionId":861823,"sourceType":"competition"}],"dockerImageVersionId":30822,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Projet Deep Learning : Digit Recognizer\n\nCe projet a pour objectif de reconnaître des chiffres manuscrits à l'aide de modèles de deep learning. Il s'inscrit dans le cadre d'une compétition Kaggle intitulée **Digit Recognizer**.\n\n## Objectifs du projet :\n- Développer plusieurs modèles pour classifier les chiffres manuscrits.\n- Optimiser les performances pour obtenir une meilleure précision.\n- Soumettre les résultats sous la forme d'un fichier CSV sur Kaggle.\n","metadata":{}},{"cell_type":"markdown","source":"## Importation des Bibliothèques Nécessaires\n\nDans cette section, nous importons toutes les bibliothèques nécessaires pour traiter les données, créer des modèles de deep learning, et évaluer leurs performances.\n","metadata":{}},{"cell_type":"code","source":"# Importation des bibliothèques nécessaires\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\n# Configurer les graphiques pour être affichés dans le notebook\n%matplotlib inline\n\n# Paramètres pour rendre les graphiques plus lisibles\nsns.set_style('whitegrid')\nplt.rcParams['figure.figsize'] = (10, 6)\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-01-14T09:30:03.928466Z","iopub.execute_input":"2025-01-14T09:30:03.928966Z","iopub.status.idle":"2025-01-14T09:30:05.671570Z","shell.execute_reply.started":"2025-01-14T09:30:03.928928Z","shell.execute_reply":"2025-01-14T09:30:05.670333Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Chargement et Visualisation des Données\n\nNous allons charger les données d'entraînement et de test fournies par Kaggle. Une analyse exploratoire rapide sera effectuée pour mieux comprendre la distribution des classes et les caractéristiques des images.\n","metadata":{}},{"cell_type":"code","source":"# Charger les données depuis les fichiers CSV\ntrain_data_path = '/kaggle/input/digit-recognizer/train.csv'\ntest_data_path = '/kaggle/input/digit-recognizer/test.csv'\n\n# Charger les datasets\ntrain_data = pd.read_csv(train_data_path)\ntest_data = pd.read_csv(test_data_path)\n\n# Aperçu des données d'entraînement\nprint(\"Train Data Info:\")\nprint(train_data.info())\nprint(\"\\nTrain Data Preview:\")\nprint(train_data.head())\n\n# Aperçu des données de test\nprint(\"\\nTest Data Info:\")\nprint(test_data.info())\nprint(\"\\nTest Data Preview:\")\nprint(test_data.head())\n\n# Vérifier la répartition des classes dans le dataset d'entraînement\nlabel_counts = train_data['label'].value_counts()\nprint(\"\\nLabel Distribution:\")\nprint(label_counts)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T09:30:05.672793Z","iopub.execute_input":"2025-01-14T09:30:05.673430Z","iopub.status.idle":"2025-01-14T09:30:10.979335Z","shell.execute_reply.started":"2025-01-14T09:30:05.673371Z","shell.execute_reply":"2025-01-14T09:30:10.978153Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Visualiser la répartition des étiquettes\nsns.barplot(x=label_counts.index, y=label_counts.values, palette='viridis')\nplt.title(\"Distribution of Digits in the Training Data\")\nplt.xlabel(\"Digits\")\nplt.ylabel(\"Count\")\nplt.show()\n\n# Visualiser quelques exemples d'images\ndef plot_sample_images(data, labels_column='label', num_samples=6):\n    \"\"\"\n    Affiche un certain nombre d'images aléatoires du dataset.\n    \"\"\"\n    sample = data.sample(num_samples, random_state=42)\n    fig, axes = plt.subplots(1, num_samples, figsize=(15, 5))\n    for i, ax in enumerate(axes):\n        image = sample.iloc[i, 1:].values.reshape(28, 28)  # Reshape des pixels en 28x28\n        label = sample.iloc[i][labels_column]\n        ax.imshow(image, cmap='gray')\n        ax.set_title(f\"Label: {label}\")\n        ax.axis('off')\n    plt.tight_layout()\n    plt.show()\n\n# Appeler la fonction pour visualiser des exemples\nplot_sample_images(train_data)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T09:30:10.980377Z","iopub.execute_input":"2025-01-14T09:30:10.980927Z","iopub.status.idle":"2025-01-14T09:30:12.327584Z","shell.execute_reply.started":"2025-01-14T09:30:10.980884Z","shell.execute_reply":"2025-01-14T09:30:12.326374Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Prétraitement des Données\n\nAvant d'entraîner les modèles, les données doivent être préparées. Cette étape inclut :\n- Verification des valeurs manquantes.\n- Supprimer les doublons.\n- Normalisation des données.\n- La division des données d'entraînement en ensembles d'entraînement et de validation.\n- La mise en forme des données pour correspondre aux exigences des différents modèles (MLP, CNN, etc.).\n","metadata":{}},{"cell_type":"code","source":"# Vérification des valeurs manquantes\nprint(\"Checking for missing values:\")\nprint(train_data.isnull().sum().sum())\n\nprint(\"\\nChecking for duplicates:\")\nprint(f\"Number of duplicate rows: {train_data.duplicated().sum()}\")\n\n# Supprimer les doublons si nécessaire\ntrain_data = train_data.drop_duplicates()\n\nprint(\"\\nAfter cleaning, dataset shape:\")\nprint(train_data.shape)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T09:30:12.328426Z","iopub.execute_input":"2025-01-14T09:30:12.328724Z","iopub.status.idle":"2025-01-14T09:30:13.428453Z","shell.execute_reply.started":"2025-01-14T09:30:12.328695Z","shell.execute_reply":"2025-01-14T09:30:13.427269Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Normalisation des données d'entraînement (mise à l'échelle entre 0 et 1)\nmnist_train_data = train_data.iloc[:, 1:] / 255.0  # Exclure la colonne 'label' pour normaliser\nmnist_train_label = train_data['label']  # Étiquettes\n\n# Normalisation des données de test\nmnist_test_data = test_data / 255.0  # Les données de test n'ont pas de colonne 'label'\n\n# Afficher un aperçu des données normalisées\nprint(\"\\nPreview of normalized training data:\")\nprint(mnist_train_data.head())\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T09:30:13.429467Z","iopub.execute_input":"2025-01-14T09:30:13.429777Z","iopub.status.idle":"2025-01-14T09:30:13.554466Z","shell.execute_reply.started":"2025-01-14T09:30:13.429724Z","shell.execute_reply":"2025-01-14T09:30:13.553091Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\n# Diviser les données en ensembles d'entraînement et de validation\nX_train, X_val, y_train, y_val = train_test_split(\n    mnist_train_data, mnist_train_label, test_size=0.2, random_state=42, stratify=mnist_train_label\n)\n\nprint(\"\\nShapes of datasets:\")\nprint(f\"X_train: {X_train.shape}, y_train: {y_train.shape}\")\nprint(f\"X_val: {X_val.shape}, y_val: {y_val.shape}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T09:30:13.557178Z","iopub.execute_input":"2025-01-14T09:30:13.557500Z","iopub.status.idle":"2025-01-14T09:30:14.029698Z","shell.execute_reply.started":"2025-01-14T09:30:13.557473Z","shell.execute_reply":"2025-01-14T09:30:14.028275Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Développement des Modèles\n\nDans cette section, nous développons plusieurs modèles pour résoudre le problème :\n1. **Baseline MLP** : Un modèle simple avec des couches denses.\n2. **Advanced CNN** : Un modèle convolutif avancé avec des techniques de régularisation.\n3. **Alternative CNN** : Un modèle expérimental pour comparer les performances.\n\nChaque modèle est entraîné et évalué sur l'ensemble de validation.\n","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense\nfrom tensorflow.keras.optimizers import Adam\n\n# Conversion des données en Numpy Array\nX_train_array = X_train.to_numpy()  # Convertir X_train en array Numpy\nX_val_array = X_val.to_numpy()\n\n# Préparation des données aplaties pour MLP\nX_train_flattened = X_train_array.reshape(X_train_array.shape[0], -1)  # De (num_samples, 28, 28) à (num_samples, 784)\nX_val_flattened = X_val_array.reshape(X_val_array.shape[0], -1)\n\n# Baseline MLP\nmodel_1 = Sequential([\n    Dense(128, activation='relu', input_shape=(784,)),  # Correspond à une entrée aplatie (28x28 = 784)\n    Dense(64, activation='relu'),\n    Dense(10, activation='softmax')  # 10 classes pour la classification\n])\n\n# Compiler le modèle\nmodel_1.compile(optimizer=Adam(learning_rate=0.001), \n                loss='sparse_categorical_crossentropy', \n                metrics=['accuracy'])\n\n# Entraîner le modèle avec les données aplaties\nhistory_1 = model_1.fit(X_train_flattened, y_train, \n                        validation_data=(X_val_flattened, y_val), \n                        epochs=10, \n                        batch_size=64)\n\n# Résultats du modèle de base\nprint(\"\\nModel 1 - Baseline MLP:\")\nmodel_1.evaluate(X_val_flattened, y_val)\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T09:30:14.032057Z","iopub.execute_input":"2025-01-14T09:30:14.032573Z","iopub.status.idle":"2025-01-14T09:30:46.343636Z","shell.execute_reply.started":"2025-01-14T09:30:14.032535Z","shell.execute_reply":"2025-01-14T09:30:46.342541Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout\nfrom tensorflow.keras.optimizers import Adam\n\n# Préparer les données pour CNN (ajouter une dimension pour le canal grayscale)\nX_train_cnn = X_train.to_numpy().reshape(-1, 28, 28, 1)  # De (num_samples, 28, 28) à (num_samples, 28, 28, 1)\nX_val_cnn = X_val.to_numpy().reshape(-1, 28, 28, 1)\n\n# Modèle CNN avec régularisation\nmodel_2 = Sequential([\n    Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),\n    MaxPooling2D((2, 2)),\n    Dropout(0.3),  # Régularisation pour éviter le sur-apprentissage\n    Conv2D(64, (3, 3), activation='relu'),\n    MaxPooling2D((2, 2)),\n    Dropout(0.3),\n    Flatten(),\n    Dense(128, activation='relu'),\n    Dropout(0.5),\n    Dense(10, activation='softmax')  # 10 classes pour la classification\n])\n\n# Compiler le modèle\nmodel_2.compile(optimizer=Adam(learning_rate=0.001), \n                loss='sparse_categorical_crossentropy', \n                metrics=['accuracy'])\n\n# Entraîner le modèle CNN\nhistory_2 = model_2.fit(X_train_cnn, y_train, \n                        validation_data=(X_val_cnn, y_val), \n                        epochs=15, \n                        batch_size=64)\n\n# Résultats du modèle CNN\nprint(\"\\nModel 2 - Advanced CNN with Regularization:\")\nmodel_2.evaluate(X_val_cnn, y_val)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T09:30:46.344479Z","iopub.execute_input":"2025-01-14T09:30:46.345108Z","iopub.status.idle":"2025-01-14T09:34:54.365199Z","shell.execute_reply.started":"2025-01-14T09:30:46.345076Z","shell.execute_reply":"2025-01-14T09:34:54.364124Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, BatchNormalization\nfrom tensorflow.keras.optimizers import Adam\n\n# Préparer les données pour CNN (ajouter une dimension pour le canal grayscale)\nX_train_cnn = X_train.to_numpy().reshape(-1, 28, 28, 1)  # De (num_samples, 28, 28) à (num_samples, 28, 28, 1)\nX_val_cnn = X_val.to_numpy().reshape(-1, 28, 28, 1)\n\n# Modèle CNN avancé\nmodel_3_alternative = Sequential([\n    Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),\n    BatchNormalization(),\n    MaxPooling2D((2, 2)),\n    Dropout(0.3),\n\n    Conv2D(64, (3, 3), activation='relu'),\n    BatchNormalization(),\n    MaxPooling2D((2, 2)),\n    Dropout(0.3),\n\n    Conv2D(128, (3, 3), activation='relu'),\n    BatchNormalization(),\n    MaxPooling2D((2, 2)),\n    Dropout(0.4),\n\n    Flatten(),\n    Dense(256, activation='relu'),\n    Dropout(0.5),\n    Dense(10, activation='softmax')  # 10 classes pour la classification\n])\n\n# Compiler le modèle\nmodel_3_alternative.compile(optimizer=Adam(learning_rate=0.001), \n                            loss='sparse_categorical_crossentropy', \n                            metrics=['accuracy'])\n\n# Entraîner le modèle\nhistory_3_alternative = model_3_alternative.fit(X_train_cnn, y_train, \n                                                validation_data=(X_val_cnn, y_val), \n                                                epochs=20, \n                                                batch_size=64)\n\n# Résultats du modèle CNN avancé\nprint(\"\\nModel 3 - Advanced CNN Alternative:\")\nmodel_3_alternative.evaluate(X_val_cnn, y_val)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T09:34:54.366421Z","iopub.execute_input":"2025-01-14T09:34:54.366802Z","iopub.status.idle":"2025-01-14T09:44:26.266459Z","shell.execute_reply.started":"2025-01-14T09:34:54.366692Z","shell.execute_reply":"2025-01-14T09:44:26.265380Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\n# Fonction pour tracer les courbes de précision et de perte\ndef plot_training_history(histories, titles):\n    for i, history in enumerate(histories):\n        plt.figure(figsize=(12, 5))\n        \n        # Tracer la courbe d'accuracy\n        plt.subplot(1, 2, 1)\n        plt.plot(history.history['accuracy'], label='Train Accuracy')\n        plt.plot(history.history['val_accuracy'], label='Validation Accuracy')\n        plt.title(f\"{titles[i]} - Accuracy\")\n        plt.xlabel(\"Epochs\")\n        plt.ylabel(\"Accuracy\")\n        plt.legend()\n        \n        # Tracer la courbe de perte\n        plt.subplot(1, 2, 2)\n        plt.plot(history.history['loss'], label='Train Loss')\n        plt.plot(history.history['val_loss'], label='Validation Loss')\n        plt.title(f\"{titles[i]} - Loss\")\n        plt.xlabel(\"Epochs\")\n        plt.ylabel(\"Loss\")\n        plt.legend()\n        \n        plt.tight_layout()\n        plt.show()\n\n# Appeler la fonction pour comparer les modèles entraînés\nplot_training_history(\n    [history_1, history_2, history_3_alternative],  # Historique des entraînements des modèles\n    [\"Baseline MLP\", \"Advanced CNN\", \"Advanced CNN Alternative\"]  # Titres des modèles\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T09:44:26.267628Z","iopub.execute_input":"2025-01-14T09:44:26.268098Z","iopub.status.idle":"2025-01-14T09:44:28.598364Z","shell.execute_reply.started":"2025-01-14T09:44:26.268028Z","shell.execute_reply":"2025-01-14T09:44:28.597166Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Modèle CNN avec Régularisation et Optimisation Avancée\n\nDans cette section, nous construisons un modèle CNN pour classifier les chiffres manuscrits. Les principales étapes sont :\n\n1. **Préparation des Données** : Les images sont redimensionnées en 28x28x1 pour correspondre au format d'entrée du CNN.\n2. **Architecture du Modèle** :\n   - Couches convolutives et MaxPooling pour l'extraction de caractéristiques.\n   - Dropout et régularisation L2 pour éviter le sur-apprentissage.\n   - Couches denses pour la classification.\n3. **Optimisation** :\n   - Planificateur de taux d'apprentissage exponentiel.\n   - Optimiseur SGD avec momentum.\n   - Callbacks : EarlyStopping et ReduceLROnPlateau.\n4. **Évaluation et Visualisation** :\n   - Perte et précision calculées sur l'ensemble de validation.\n   - Courbes d'entraînement et de validation tracées.\n\nCe modèle est entraîné sur 20 époques avec une taille de batch de 64. Les performances sont visualisées pour analyser les progrès.\n","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout\nfrom tensorflow.keras.optimizers import SGD, Adam\nfrom tensorflow.keras.optimizers.schedules import ExponentialDecay\nfrom tensorflow.keras.regularizers import l2\nfrom tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau\n\n# Préparer les données CNN\nX_train_cnn = X_train.to_numpy().reshape(-1, 28, 28, 1)  # Convertir en numpy et ajouter une dimension de canal\nX_val_cnn = X_val.to_numpy().reshape(-1, 28, 28, 1)      # Idem pour les données de validation\n\n# Définir le modèle CNN avec régularisation (Dropout et L2)\nmodel = Sequential([\n    Conv2D(32, (3, 3), activation='relu', kernel_regularizer=l2(0.001), input_shape=(28, 28, 1)),\n    MaxPooling2D((2, 2)),\n    Dropout(0.3),  # Dropout pour éviter le sur-apprentissage\n    Conv2D(64, (3, 3), activation='relu', kernel_regularizer=l2(0.001)),\n    MaxPooling2D((2, 2)),\n    Dropout(0.4),\n    Flatten(),\n    Dense(128, activation='relu', kernel_regularizer=l2(0.001)),\n    Dropout(0.5),\n    Dense(10, activation='softmax')  # 10 classes pour la classification\n])\n\n# Définir un Learning Rate Scheduler exponentiel\nlr_schedule = ExponentialDecay(\n    initial_learning_rate=0.01,  # Taux d'apprentissage initial\n    decay_steps=10000,           # Nombre de pas avant chaque réduction\n    decay_rate=0.9               # Facteur de réduction\n)\n\n# Utiliser SGD avec momentum comme optimiseur avancé\noptimizer = SGD(learning_rate=lr_schedule, momentum=0.9)\n\n# Compiler le modèle\nmodel.compile(optimizer=optimizer,\n              loss='sparse_categorical_crossentropy',\n              metrics=['accuracy'])\n\n# Définir les callbacks pour Early Stopping et ReduceLROnPlateau\nearly_stopping = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True)\nlr_scheduler = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=3, min_lr=1e-6)\n\n# Entraîner le modèle avec les stratégies définies\nhistory = model.fit(\n    X_train_cnn, y_train,                # Données d'entraînement\n    validation_data=(X_val_cnn, y_val), # Données de validation\n    epochs=20,                          # Nombre d'époques\n    batch_size=64,                      # Taille des batchs\n    callbacks=[early_stopping, lr_scheduler]  # Stratégies avancées\n)\n\n# Évaluer le modèle\nval_loss, val_accuracy = model.evaluate(X_val_cnn, y_val)\nprint(f\"\\nValidation Loss: {val_loss:.4f}\")\nprint(f\"Validation Accuracy: {val_accuracy * 100:.2f}%\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T09:44:28.599277Z","iopub.execute_input":"2025-01-14T09:44:28.599560Z","iopub.status.idle":"2025-01-14T09:49:52.387789Z","shell.execute_reply.started":"2025-01-14T09:44:28.599534Z","shell.execute_reply":"2025-01-14T09:49:52.386717Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\n# Visualisation des courbes de précision et de perte\nplt.figure(figsize=(12, 5))\n\n# Courbe de précision\nplt.subplot(1, 2, 1)\nplt.plot(history.history['accuracy'], label='Train Accuracy')\nplt.plot(history.history['val_accuracy'], label='Validation Accuracy')\nplt.title(\"Model Accuracy\")\nplt.xlabel(\"Epochs\")\nplt.ylabel(\"Accuracy\")\nplt.legend()\n\n# Courbe de perte\nplt.subplot(1, 2, 2)\nplt.plot(history.history['loss'], label='Train Loss')\nplt.plot(history.history['val_loss'], label='Validation Loss')\nplt.title(\"Model Loss\")\nplt.xlabel(\"Epochs\")\nplt.ylabel(\"Loss\")\nplt.legend()\n\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T09:49:52.388808Z","iopub.execute_input":"2025-01-14T09:49:52.389112Z","iopub.status.idle":"2025-01-14T09:49:53.094080Z","shell.execute_reply.started":"2025-01-14T09:49:52.389084Z","shell.execute_reply":"2025-01-14T09:49:53.092888Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Évaluation et Comparaison des Modèles\n\n### 1. Rapport de Classification\nLe rapport de classification fournit des métriques clés (précision, rappel, F1-score) pour évaluer les performances du modèle sur chaque classe.\n\n### 2. Matrice de Confusion\nLa matrice de confusion montre les prédictions correctes et incorrectes, aidant à identifier les classes où le modèle fait le plus d'erreurs.\n\n### 3. Validation Croisée avec Régression Logistique\nUn modèle de régression logistique est utilisé comme baseline simple, évalué avec une validation croisée.\n\n### 4. Comparaison des Modèles\nL'accuracy des modèles (MLP, Advanced CNN, Alternative CNN) est comparée pour déterminer le modèle le plus performant.\n\n### 5. Évaluation Individuelle des Modèles\nDes rapports de classification sont générés pour chaque modèle pour analyser leurs forces et faiblesses.\n","metadata":{}},{"cell_type":"code","source":"from sklearn.metrics import classification_report\n\n# Prédictions pour les données de validation (dernier modèle entraîné, par exemple CNN avancé)\ny_val_pred = model.predict(X_val_cnn)\ny_val_pred_classes = y_val_pred.argmax(axis=1)  # Classes prédites\n\n# Rapport de classification\nprint(\"\\nClassification Report (Model Evaluation):\")\nprint(classification_report(y_val, y_val_pred_classes))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T09:49:53.095137Z","iopub.execute_input":"2025-01-14T09:49:53.095470Z","iopub.status.idle":"2025-01-14T09:49:54.903488Z","shell.execute_reply.started":"2025-01-14T09:49:53.095438Z","shell.execute_reply":"2025-01-14T09:49:54.902385Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay\nimport matplotlib.pyplot as plt\n\n# Calculer la matrice de confusion\ncm = confusion_matrix(y_val, y_val_pred_classes)\n\n# Afficher la matrice de confusion\ndisp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=range(10))\ndisp.plot(cmap='Blues', values_format='d')\nplt.title(\"Confusion Matrix (Model Evaluation)\")\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T09:49:54.904472Z","iopub.execute_input":"2025-01-14T09:49:54.904845Z","iopub.status.idle":"2025-01-14T09:49:55.453168Z","shell.execute_reply.started":"2025-01-14T09:49:54.904807Z","shell.execute_reply":"2025-01-14T09:49:55.451794Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.linear_model import LogisticRegression\nfrom sklearn.model_selection import cross_val_score\n\n# Préparer les données aplaties pour la validation croisée\nX_train_flattened = X_train.to_numpy().reshape(X_train.shape[0], -1)\nX_val_flattened = X_val.to_numpy().reshape(X_val.shape[0], -1)\n\n# Modèle simple pour comparaison\nlog_reg = LogisticRegression(max_iter=1000)\n\n# Validation croisée\nscores = cross_val_score(log_reg, X_train_flattened, y_train, cv=5, scoring='accuracy')\nprint(\"\\nCross-Validation Accuracy (Logistic Regression):\")\nprint(scores)\nprint(f\"Mean Accuracy: {scores.mean() * 100:.2f}%\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T09:49:55.454313Z","iopub.execute_input":"2025-01-14T09:49:55.454645Z","iopub.status.idle":"2025-01-14T09:53:18.789944Z","shell.execute_reply.started":"2025-01-14T09:49:55.454616Z","shell.execute_reply":"2025-01-14T09:53:18.787726Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Exemple de comparaison des accuracy finales\nprint(\"\\nComparison of Models:\")\nprint(f\"Baseline MLP - Validation Accuracy: {history_1.history['val_accuracy'][-1] * 100:.2f}%\")\nprint(f\"Advanced CNN - Validation Accuracy: {history_2.history['val_accuracy'][-1] * 100:.2f}%\")\nprint(f\"Alternative CNN - Validation Accuracy: {history_3_alternative.history['val_accuracy'][-1] * 100:.2f}%\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T09:53:18.790917Z","iopub.execute_input":"2025-01-14T09:53:18.791358Z","iopub.status.idle":"2025-01-14T09:53:18.798908Z","shell.execute_reply.started":"2025-01-14T09:53:18.791316Z","shell.execute_reply":"2025-01-14T09:53:18.797899Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.metrics import classification_report\n\n# Prédictions pour le modèle MLP (Baseline MLP)\nX_val_flattened = X_val.to_numpy().reshape(X_val.shape[0], -1)  # Aplatir les données pour le MLP\ny_val_pred_mlp = model_1.predict(X_val_flattened)  # Prédictions MLP\ny_val_pred_classes_mlp = y_val_pred_mlp.argmax(axis=1)  # Classes prédites pour MLP\n\nprint(\"\\nClassification Report (Baseline MLP):\")\nprint(classification_report(y_val, y_val_pred_classes_mlp))\n\n# Prédictions pour le modèle Advanced CNN\ny_val_pred_cnn = model_2.predict(X_val_cnn)  # Prédictions CNN\ny_val_pred_classes_cnn = y_val_pred_cnn.argmax(axis=1)  # Classes prédites pour CNN\n\nprint(\"\\nClassification Report (Advanced CNN):\")\nprint(classification_report(y_val, y_val_pred_classes_cnn))\n\n# Prédictions pour le modèle Alternative CNN (dernier modèle)\ny_val_pred_alt_cnn = model.predict(X_val_cnn)  # Prédictions Alternative CNN\ny_val_pred_classes_alt_cnn = y_val_pred_alt_cnn.argmax(axis=1)  # Classes prédites pour Alternative CNN\n\nprint(\"\\nClassification Report (Alternative CNN):\")\nprint(classification_report(y_val, y_val_pred_classes_alt_cnn))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T09:53:18.800319Z","iopub.execute_input":"2025-01-14T09:53:18.800668Z","iopub.status.idle":"2025-01-14T09:53:22.773421Z","shell.execute_reply.started":"2025-01-14T09:53:18.800631Z","shell.execute_reply":"2025-01-14T09:53:22.772029Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Génération des Prédictions et Soumission\n\n### Étapes :\n1. **Prédictions par Modèle** :\n   - MLP : Données aplaties.\n   - Advanced CNN et Alternative CNN : Données redimensionnées en 28x28x1.\n\n2. **Vote Majoritaire** :\n   - Combine les prédictions des trois modèles pour choisir la classe finale.\n\n3. **Fichier de Soumission** :\n   - Crée un CSV avec `ImageId` et `Label` (prédictions combinées).\n   - Sauvegarde sous `submission_combined.csv`.\n\n4. **Vérification** :\n   - Affiche les premières lignes du fichier pour vérifier son format.\n\nCe fichier est prêt pour être soumis sur Kaggle.\n","metadata":{}},{"cell_type":"code","source":"import pandas as pd\n\n# Préparer les données de test pour le modèle CNN\nX_test_cnn = test_data.to_numpy().reshape(-1, 28, 28, 1)  # Redimensionner pour CNN\n\n# Générer des prédictions pour le jeu de test\ntest_predictions = model.predict(X_test_cnn)  # Changez \"model\" par votre modèle\ntest_pred_classes = test_predictions.argmax(axis=1)  # Classes prédites\nimport numpy as np\nimport pandas as pd\n\n# Étape 1 : Générer les prédictions pour le jeu de test\n\n# 1.1 Prédictions pour le Baseline MLP\nX_test_flattened = test_data.to_numpy().reshape(test_data.shape[0], -1)  # Aplatir les données\ntest_predictions_mlp = model_1.predict(X_test_flattened)  # Utiliser le modèle MLP\ntest_pred_classes_mlp = test_predictions_mlp.argmax(axis=1)  # Convertir en classes prédictes\n\n# 1.2 Prédictions pour l'Advanced CNN\nX_test_cnn = test_data.to_numpy().reshape(-1, 28, 28, 1)  # Redimensionner pour le CNN\ntest_predictions_cnn = model_2.predict(X_test_cnn)  # Utiliser le modèle Advanced CNN\ntest_pred_classes_cnn = test_predictions_cnn.argmax(axis=1)  # Convertir en classes prédictes\n\n# 1.3 Prédictions pour l'Alternative CNN\ntest_predictions_alt_cnn = model.predict(X_test_cnn)  # Utiliser le modèle Alternative CNN\ntest_pred_classes_alt_cnn = test_predictions_alt_cnn.argmax(axis=1)  # Convertir en classes prédictes\n\n# Étape 2 : Appliquer le vote majoritaire pour combiner les prédictions\npredictions_combined = np.array([test_pred_classes_mlp, test_pred_classes_cnn, test_pred_classes_alt_cnn])\nfinal_predictions = np.apply_along_axis(lambda x: np.bincount(x).argmax(), axis=0, arr=predictions_combined)\n\n# Étape 3 : Préparer le fichier de soumission\n\n# Créer un DataFrame pour la soumission combinée\nsubmission_combined = pd.DataFrame({\n    \"ImageId\": range(1, len(final_predictions) + 1),  # Identifiants des images (1, 2, ...)\n    \"Label\": final_predictions  # Classes combinées\n})\n\n# Sauvegarder le fichier de soumission\nsubmission_combined.to_csv(\"submission_combined.csv\", index=False)\nprint(\"Submission file for Combined Predictions saved as 'submission_combined.csv'\")\n\n# Vérifier les premières lignes du fichier de soumission\nprint(submission_combined.head())\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-14T09:53:22.774581Z","iopub.execute_input":"2025-01-14T09:53:22.774931Z","iopub.status.idle":"2025-01-14T09:53:41.594635Z","shell.execute_reply.started":"2025-01-14T09:53:22.774893Z","shell.execute_reply":"2025-01-14T09:53:41.593377Z"}},"outputs":[],"execution_count":null}]}