Restructuration complète des flashcards avec : - Question/définition explicite - Exemples concrets avec chiffres - Interprétation pratique - Séparation claire formule / signification Avant : "Formule - TP / (TP + FN). Parmi les vrais positifs, combien ont été détectés ?" Après : Question claire + formule + exemple concret (spam) + interprétation Cela rend l'apprentissage plus intuitif et moins confus. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
20 KiB
Examen - Généralisation des Modèles ML
Ce document contient des questions pour tester et renforcer votre compréhension des concepts du lab.
Partie 1 : Questions Théoriques (QCM)
Question 1 : Définition de la généralisation
Qu'est-ce qu'un modèle qui généralise bien ?
A) Un modèle avec 100% d'accuracy sur le training set
B) Un modèle qui performe bien sur des données jamais vues
C) Un modèle qui converge rapidement
D) Un modèle avec beaucoup de paramètres
Voir la réponse
Réponse : B
Un modèle qui généralise bien est capable de prédire correctement sur des données qu'il n'a jamais vues pendant l'entraînement. C'est la métrique la plus importante en ML. La performance sur le training set seule ne suffit pas (option A peut indiquer de l'overfitting).
Question 2 : Split des données
Pourquoi utilise-t-on 3 ensembles (Train/Validation/Test) au lieu de 2 ?
A) Pour avoir plus de données
B) Le validation set détecte l'overfitting pendant l'entraînement
C) C'est une convention arbitraire
D) Pour ralentir l'entraînement
Voir la réponse
Réponse : B
Le validation set permet de détecter l'overfitting pendant l'entraînement et d'ajuster les hyperparamètres sans biaiser l'évaluation finale. Le test set reste complètement isolé pour une évaluation non biaisée. Si on n'avait que Train/Test, on serait tenté d'ajuster les hyperparamètres en fonction du test set, ce qui invaliderait son rôle.
Question 3 : Early Stopping
Que fait l'Early Stopping quand patience=3 et min_delta=0.01 ?
A) Arrête après 3 epochs
B) Arrête si val_loss n'améliore pas de 0.01 pendant 3 epochs consécutifs
C) Arrête si train_loss augmente
D) Réduit le learning rate de 0.01
Voir la réponse
Réponse : B
L'Early Stopping surveille la val_loss. Si elle ne diminue pas d'au moins min_delta (0.01) pendant patience (3) epochs consécutifs, l'entraînement s'arrête et les meilleurs poids sont restaurés. Cela prévient l'overfitting.
Question 4 : Learning Rate Scheduler
Avec ReduceLROnPlateau(factor=0.5, patience=2) et LR initial de 0.05, quel sera le LR après 2 epochs sans amélioration ?
A) 0.05
B) 0.025
C) 0.0125
D) 0.01
Voir la réponse
Réponse : B
Après 2 epochs sans amélioration de val_loss, le LR est multiplié par factor (0.5). Donc : 0.05 × 0.5 = 0.025. Si val_loss stagne encore 2 epochs, il sera réduit à 0.0125, etc.
Question 5 : Normalisation
Pourquoi normaliser les features avec StandardScaler ?
A) Pour rendre les données plus lisibles
B) Pour accélérer le code
C) Pour que toutes les features contribuent équitablement au gradient
D) Pour réduire la taille des données
Voir la réponse
Réponse : C
Sans normalisation, les features à grande échelle (ex: revenu en milliers) dominent le gradient descent par rapport aux features à petite échelle (ex: age). StandardScaler transforme toutes les features pour avoir moyenne=0 et écart-type=1, permettant une convergence plus rapide et stable.
Partie 2 : Analyse de Cas
Cas 1 : Diagnostic d'overfitting
Analysez ces métriques :
Epoch 5: train_loss=0.25, val_loss=0.28, train_acc=92%, val_acc=90%
Epoch 10: train_loss=0.10, val_loss=0.30, train_acc=97%, val_acc=89%
Epoch 15: train_loss=0.05, val_loss=0.38, train_acc=99%, val_acc=85%
Questions :
- Quel problème identifiez-vous ?
- À quelle epoch aurait dû s'arrêter le modèle ?
- Quelles solutions proposez-vous ?
Voir l'analyse complète
1. Problème : Overfitting sévère
Signes :
- train_loss diminue continuellement (0.25 → 0.05)
- val_loss augmente (0.28 → 0.38)
- Gap croissant entre train_acc et val_acc (99% vs 85%)
- Le modèle mémorise au lieu de généraliser
2. Arrêt optimal : Epoch 5
C'est le point où val_loss est la plus basse (0.28) et le gap train/val est minimal (2%).
3. Solutions :
- Early stopping avec patience=2-3
- Régularisation : L2, Dropout
- Simplifier l'architecture (moins de neurones/couches)
- Augmenter les données d'entraînement
- Réduire le nombre d'epochs max
Cas 2 : Matrice de confusion
Prédictions
0 1
Réel 0 [[180 20]
1 [ 5 195]]
Questions :
- Calculez l'accuracy
- Calculez la precision pour la classe 1
- Calculez le recall pour la classe 0
- Le modèle est-il équilibré ?
Voir les calculs
1. Accuracy
Accuracy = (TP + TN) / Total
= (195 + 180) / (180 + 20 + 5 + 195)
= 375 / 400
= 93.75%
2. Precision (classe 1)
Precision = TP / (TP + FP)
= 195 / (195 + 20)
= 195 / 215
= 90.7%
3. Recall (classe 0)
Recall = TN / (TN + FP)
= 180 / (180 + 20)
= 180 / 200
= 90%
4. Équilibre : Oui
Les performances sont similaires pour les deux classes (90-91%). Pas de biais flagrant vers une classe. Le modèle généralise bien sur les deux types de prédictions.
Cas 3 : Choix d'hyperparamètres
Vous avez ces résultats sur le validation set :
| Config | LR initial | Patience | Epoch arrêt | Val accuracy |
|---|---|---|---|---|
| A | 0.1 | 2 | 5 | 85% |
| B | 0.05 | 3 | 10 | 97% |
| C | 0.01 | 5 | 25 | 92% |
Question : Quelle configuration choisissez-vous et pourquoi ?
Voir l'analyse
Choix : Configuration B
Raisons :
- Meilleure performance : 97% d'accuracy (la plus élevée)
- Convergence raisonnable : 10 epochs (ni trop rapide comme A, ni trop lent comme C)
- LR équilibré : 0.05 permet exploration + affinage
Pourquoi pas A ?
- Trop rapide (5 epochs) → risque d'underfitting
- Accuracy basse (85%) → le modèle n'a pas assez appris
Pourquoi pas C ?
- Trop lent (25 epochs) → coût d'entraînement élevé
- Accuracy inférieure à B (92% < 97%)
- LR trop faible (0.01) → convergence lente
Important : Cette décision est basée sur le validation set. L'évaluation finale se fera sur le test set.
Partie 3 : Exercices Pratiques
Exercice 1 : Prédire le comportement
Code :
early_stop = EarlyStopping(
monitor='val_loss',
patience=2,
min_delta=0.05,
restore_best_weights=True
)
Historique d'entraînement :
Epoch 1: val_loss = 0.50
Epoch 2: val_loss = 0.45
Epoch 3: val_loss = 0.43
Epoch 4: val_loss = 0.42
Epoch 5: val_loss = 0.41
Questions :
- À quelle epoch le modèle s'arrêtera-t-il ?
- Quels poids seront restaurés ?
Voir la solution
1. Arrêt : Epoch 5
Analyse epoch par epoch :
- Epoch 1 → 2 : amélioration de 0.05 (0.50 - 0.45 = 0.05) [OK] = min_delta
- Epoch 2 → 3 : amélioration de 0.02 (0.45 - 0.43 = 0.02) [NON] < min_delta (compteur = 1)
- Epoch 3 → 4 : amélioration de 0.01 (0.43 - 0.42 = 0.01) [NON] < min_delta (compteur = 2)
- Compteur atteint patience=2 → STOP
2. Poids restaurés : Epoch 2
Les meilleurs poids sont ceux de l'epoch 2 (dernière fois où min_delta a été atteint). val_loss = 0.45.
Exercice 2 : Compléter le code
Complétez ce code pour implémenter un modèle avec généralisation :
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import tensorflow as tf
# Données
X, y = make_classification(n_samples=1000, n_features=10, random_state=42)
# TODO: Normaliser X
scaler = ___________
X = scaler.___________
# TODO: Split en Train (64%), Val (16%), Test (20%)
X_trainval, X_test, y_trainval, y_test = train_test_split(X, y, test_size=___, random_state=42)
X_train, X_val, y_train, y_val = train_test_split(X_trainval, y_trainval, test_size=___, random_state=42)
# TODO: Créer le modèle (2 couches denses)
model = tf.keras.Sequential([
tf.keras.layers.Dense(___, activation='___', input_shape=(10,)),
tf.keras.layers.Dense(___, activation='___'),
tf.keras.layers.Dense(1, activation='sigmoid')
])
# TODO: Compiler avec Adam (lr=0.01)
model.compile(
optimizer=tf.keras.optimizers.Adam(learning_rate=___),
loss='___',
metrics=['accuracy']
)
# TODO: Early stopping (patience=3, min_delta=0.01)
early_stop = tf.keras.callbacks.EarlyStopping(
monitor='___',
patience=___,
min_delta=___,
restore_best_weights=True
)
Voir la solution
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import tensorflow as tf
# Données
X, y = make_classification(n_samples=1000, n_features=10, random_state=42)
# Normaliser X
scaler = StandardScaler()
X = scaler.fit_transform(X)
# Split en Train (64%), Val (16%), Test (20%)
X_trainval, X_test, y_trainval, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
X_train, X_val, y_train, y_val = train_test_split(X_trainval, y_trainval, test_size=0.2, random_state=42)
# Créer le modèle (2 couches denses)
model = tf.keras.Sequential([
tf.keras.layers.Dense(32, activation='relu', input_shape=(10,)),
tf.keras.layers.Dense(16, activation='relu'),
tf.keras.layers.Dense(1, activation='sigmoid')
])
# Compiler avec Adam (lr=0.01)
model.compile(
optimizer=tf.keras.optimizers.Adam(learning_rate=0.01),
loss='binary_crossentropy',
metrics=['accuracy']
)
# Early stopping (patience=3, min_delta=0.01)
early_stop = tf.keras.callbacks.EarlyStopping(
monitor='val_loss',
patience=3,
min_delta=0.01,
restore_best_weights=True
)
Explications :
- StandardScaler() : Normalisation (moyenne=0, std=1)
- test_size=0.2 : 20% pour test, puis 20% de 80% = 16% pour validation
- Dense(32/16, 'relu') : Architecture progressive avec non-linéarité
- learning_rate=0.01 : Valeur standard pour démarrer
- 'binary_crossentropy' : Loss pour classification binaire
- monitor='val_loss' : Surveiller l'overfitting
Exercice 3 : Débugger le code
Ce code a un problème. Identifiez-le et corrigez-le :
X, y = make_classification(n_samples=500, n_features=15, random_state=42)
# Split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.2, random_state=42)
# Normalisation
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_val = scaler.fit_transform(X_val)
X_test = scaler.fit_transform(X_test)
# Entraînement
model.fit(X_train, y_train, validation_data=(X_val, y_val), epochs=50)
# Évaluation
y_pred = model.predict(X_test)
Question : Quel est le problème ? Comment le corriger ?
Voir le problème et la solution
Problème : Data leakage dans la normalisation
Ligne problématique :
X_val = scaler.fit_transform(X_val) # ERREUR
X_test = scaler.fit_transform(X_test) # ERREUR
Pourquoi c'est un problème ?
fit_transform() calcule la moyenne et l'écart-type sur les données fournies. En utilisant fit sur val et test, vous introduisez une fuite d'information : le scaler "voit" les statistiques de ces ensembles.
Solution correcte :
# Normalisation
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train) # OK : fit + transform sur train
X_val = scaler.transform(X_val) # OK : transform seulement (utilise stats de train)
X_test = scaler.transform(X_test) # OK : transform seulement (utilise stats de train)
Règle d'or : Ne jamais fit sur validation ou test. Toujours utiliser les statistiques (moyenne, écart-type) calculées sur le training set uniquement.
Partie 4 : Questions Ouvertes
Question 1 : Trade-offs
Expliquez le trade-off entre un learning rate élevé et un learning rate faible.
Voir la réponse attendue
Learning Rate élevé (ex: 0.1)
Avantages :
- Convergence rapide (moins d'epochs nécessaires)
- Échappe aux minima locaux
- Exploration large de l'espace des solutions
Inconvénients :
- Peut "sauter" au-dessus de l'optimum
- Instabilité (loss qui oscille)
- Risque de divergence
Learning Rate faible (ex: 0.001)
Avantages :
- Convergence précise vers l'optimum
- Stabilité (descente graduelle)
- Moins de risque de divergence
Inconvénients :
- Convergence très lente
- Risque de bloquer dans un minimum local
- Nécessite beaucoup d'epochs
Solution : Learning Rate adaptatif
Utiliser un scheduler comme ReduceLROnPlateau pour combiner les avantages : commencer avec un LR élevé (exploration rapide) puis réduire progressivement (affinage précis).
Question 2 : Biais d'évaluation
Pourquoi est-il crucial de NE JAMAIS utiliser le test set pour ajuster les hyperparamètres ?
Voir la réponse attendue
Raison : Biais d'optimisation
Si vous ajustez les hyperparamètres (patience, learning rate, architecture) en regardant les performances sur le test set, vous introduisez un biais : vous optimisez indirectement pour le test set.
Conséquence :
Le test set perd son rôle d'évaluation non biaisée. Les performances mesurées seront surestimées car le modèle a été "ajusté" pour ce dataset spécifique.
Analogie :
C'est comme un étudiant qui révise en regardant les questions de l'examen final. Il aura une bonne note, mais ça ne reflète pas sa vraie compréhension du sujet. En production, sur de vraies nouvelles données, le modèle performera moins bien.
Processus correct :
- Train set : Entraîner le modèle
- Validation set : Ajuster les hyperparamètres
- Test set : Évaluation finale (UNE SEULE FOIS, aucun ajustement après)
Le test set doit rester "caché" jusqu'à l'évaluation finale.
Question 3 : Cas réel
Vous déployez votre modèle en production. Après 1 mois :
- Performance sur données de production : 75%
- Performance sur test set (lab) : 97%
Quelles sont les causes possibles et les solutions ?
Voir l'analyse
Causes possibles :
-
Distribution shift (concept drift)
- Les données de production sont différentes des données d'entraînement
- Solution : Réentraîner régulièrement avec nouvelles données
-
Biais dans le test set
- Le test set ne représente pas bien la réalité
- Solution : Collecter un test set plus représentatif
-
Overfitting au lab
- Le modèle a été trop optimisé pour les données du lab
- Solution : Cross-validation, datasets plus variés
-
Features manquantes en production
- Certaines features utilisées en train ne sont pas disponibles en prod
- Solution : Pipeline de features robuste, monitoring
-
Problèmes de preprocessing
- Normalisation différente entre train et production
- Solution : Versionner le scaler, pipeline unifié
-
Données de mauvaise qualité en production
- Valeurs manquantes, erreurs de saisie
- Solution : Validation des données en entrée
Actions immédiates :
- Analyser la distribution des données de production vs train
- Identifier les features qui dérivent le plus
- Monitorer les prédictions incertaines
- Réentraîner avec un mix train + production
- Mettre en place un système de feedback loop
Partie 5 : Flashcards (Révision rapide)
Epoch
Cliquez pour voir la définition
Définition : Une passe complète sur l'ensemble du training set
Exemple : Si vous avez 1000 échantillons et batch_size=100, une epoch = 10 batches
Batch
Cliquez pour voir la définition
Définition : Sous-ensemble de données traité simultanément pendant l'entraînement
Exemple : batch_size=32 signifie que le modèle traite 32 échantillons avant de mettre à jour les poids
Loss function
Cliquez pour voir la définition
Définition : Fonction qui mesure l'écart entre les prédictions du modèle et les vraies valeurs
Rôle : Le modèle cherche à minimiser cette valeur pendant l'entraînement
Exemple : binary_crossentropy pour classification binaire
Backpropagation
Cliquez pour voir la définition
Définition : Méthode de calcul des gradients via la chaîne des dérivées
Rôle : Permet de calculer comment ajuster chaque poids pour réduire la loss
Processus : Forward pass (calcul) → Loss → Backward pass (ajustement des poids)
ReLU
Cliquez pour voir la définition
Formule : f(x) = max(0, x)
Rôle : Fonction d'activation qui introduit la non-linéarité
Avantages :
- Évite le vanishing gradient
- Calcul très rapide
- Permet d'apprendre des fonctions complexes
Sigmoid
Cliquez pour voir la définition
Formule : f(x) = 1 / (1 + e^(-x))
Rôle : Transforme n'importe quelle valeur en probabilité entre 0 et 1
Utilisation : Classification binaire (couche de sortie)
Exemple : Output = 0.85 signifie 85% de probabilité pour la classe 1
Precision
Cliquez pour voir la définition
Question : Parmi toutes mes prédictions positives, combien sont vraiment correctes ?
Formule : Precision = TP / (TP + FP)
Exemple concret : Sur 100 emails que j'ai marqués comme spam, combien sont vraiment des spams ?
- 90 vrais spams (TP) + 10 faux spams (FP) = Precision = 90/100 = 90%
Interprétation : Haute precision = peu de faux positifs
Recall
Cliquez pour voir la définition
Question : Parmi tous les vrais positifs qui existent, combien ai-je réussi à détecter ?
Formule : Recall = TP / (TP + FN)
Exemple concret : Il y a 100 spams dans ma boîte mail. Combien en ai-je détectés ?
- 85 spams détectés (TP) + 15 spams ratés (FN) = Recall = 85/100 = 85%
Interprétation : Haut recall = peu de faux négatifs (je rate peu de positifs)
Overfitting
Cliquez pour voir la définition
Définition : Le modèle mémorise les données d'entraînement au lieu d'apprendre les patterns généraux
Signes à détecter :
- Train accuracy >> Test accuracy (ex: 99% vs 70%)
- Val_loss augmente alors que train_loss diminue
- Gap important entre performances train et test
Causes : Modèle trop complexe, entraînement trop long, pas assez de données
Solutions : Early stopping, régularisation (L2, Dropout), plus de données
Underfitting
Cliquez pour voir la définition
Définition : Le modèle est trop simple pour capturer les patterns dans les données
Signes à détecter :
- Train accuracy ≈ Test accuracy (mais les deux sont basses)
- Exemple : 65% sur train, 63% sur test
Causes : Modèle trop simple, pas assez d'entraînement, features insuffisantes
Solutions : Modèle plus complexe, plus d'epochs, feature engineering
Barème et Auto-évaluation
Partie 1 (QCM) : 5 points (1 point par question) Partie 2 (Analyse de cas) : 9 points (3 points par cas) Partie 3 (Exercices pratiques) : 9 points (3 points par exercice) Partie 4 (Questions ouvertes) : 9 points (3 points par question)
Total : 32 points
Échelle :
- 28-32 points : Excellent (87-100%)
- 24-27 points : Très bien (75-86%)
- 20-23 points : Bien (62-74%)
- 16-19 points : Assez bien (50-61%)
- < 16 points : Revoir les concepts fondamentaux
Conseils de révision
- Commencez par les flashcards pour mémoriser les définitions
- Faites les QCM pour tester votre compréhension théorique
- Pratiquez les exercices de code pour la manipulation concrète
- Analysez les cas pour développer l'intuition
- Répondez aux questions ouvertes pour la réflexion approfondie
Astuce : Ne regardez pas les réponses immédiatement. Essayez d'abord de répondre, puis vérifiez et comprenez vos erreurs.
Bon apprentissage !