Audit, correction et analyse de robustesse d'un modèle de prédiction de retards de vols pour une compagnie aérienne, dans le cadre du cours Ma412 (Outils mathématiques pour la science des données et l'aide à la décision).
PDF Rapport complet8 pages · audit, correction, analyse de robustesse Télécharger →Un notebook de départ fourni par l'enseignant contenait un pipeline de prédiction volontairement défaillant : jeu de données de 300 vols décrits par 13 variables (compagnie, origine, destination, météo, congestion, retard précédent…), avec une cible binaire Retard ∈ {0, 1}. Mon travail : auditer le pipeline, corriger ses failles méthodologiques, comparer deux modèles, analyser les erreurs et la robustesse, puis formuler une recommandation opérationnelle.
Le notebook de départ contenait 7 problèmes méthodologiques, dont deux critiques qui rendaient toutes les métriques rapportées non significatives : un ratio train/test inversé (80% des données pour l'entraînement... sur seulement 60 échantillons) et une évaluation directement sur les données d'entraînement (93,3% de précision qui ne mesurait que de la mémorisation).
| Sévérité | Problème |
|---|---|
| Critique | Split 80/20 inversé : entraînement sur 60 échantillons seulement, test sur 240 |
| Critique | Évaluation sur les données d'entraînement (93,3% = mémorisation, pas généralisation) |
| Majeure | Identifiant de vol conservé comme variable (300 colonnes binaires parasites) |
| Majeure | Imputation uniforme par zéro, invalide pour certaines variables |
| Majeure | Encodage sans suppression de la première catégorie (piège de colinéarité parfaite) |
| Majeure | Absence de standardisation des variables (non-convergence de l'optimiseur) |
| Mineure | Nombre d'itérations maximal trop faible pour l'optimiseur |
Retrait de l'identifiant de vol, split 80/20 réalisé avant toute imputation (évite les fuites de données), imputation par médiane / mode ajustée uniquement sur l'ensemble d'entraînement, encodage avec suppression de la première catégorie, standardisation des variables, puis régression logistique.
X = df.drop(columns=["Flight_ID", "Delay"])
y = df["Delay"]
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.20, random_state=42, stratify=y
)
num_cols = ["Prev_Delay_Min", "Load_Factor_pct"]
imputer = SimpleImputer(strategy="median").fit(X_train[num_cols])
X_train[num_cols] = imputer.transform(X_train[num_cols])
X_test[num_cols] = imputer.transform(X_test[num_cols])
X_train = pd.get_dummies(X_train, drop_first=True)
X_test = pd.get_dummies(X_test, drop_first=True)
X_test = X_test.reindex(columns=X_train.columns, fill_value=0)
scaler = StandardScaler().fit(X_train)
X_train_s, X_test_s = scaler.transform(X_train), scaler.transform(X_test)
model = LogisticRegression(max_iter=1000).fit(X_train_s, y_train)
Une baseline naïve (toujours prédire "à l'heure") atteint 50,33% de précision. La régression logistique corrigée grimpe à 68,33%. Un Random Forest (100 arbres) a ensuite été testé pour capter les interactions non linéaires entre météo, congestion et retard précédent.
| Modèle | Précision | Rappel | F1 |
|---|---|---|---|
| Régression logistique | 65,38% | 62,96% | 0,6415 |
| Random Forest | 59,38% | 70,37% | 0,6441 |
Le Random Forest a été retenu malgré une précision légèrement inférieure : il détecte 2 retards réels supplémentaires (8 faux négatifs contre 10), ce qui compte davantage qu'une fausse alerte dans un contexte où manquer un retard coûte plus cher opérationnellement qu'en signaler un à tort. La variable la plus influente est l'indice de congestion aux portes d'embarquement (15,05% d'importance), confirmant que les goulots d'étranglement au sol pèsent plus que la distance ou la compagnie.
Le modèle reste modérément robuste selon la variante de prétraitement testée, mais montre une instabilité notable d'une graine aléatoire à l'autre (écart-type du F1-score de 0,073 sur 10 graines), directement lié à la petite taille du jeu de données (300 vols). Une recommandation opérationnelle est détaillée dans le rapport complet, avec abaissement du seuil de décision pour privilégier le rappel.
← Retour au portfolio