🧹 Data Preprocessing

Nettoyer et préparer les données pour le Machine Learning

Des données propres = Un modèle performant
Des données sales = Un modèle inutile

🎯 Objectif : Transformer des données brutes en données exploitables
1 / 12

⚠️ Les Données Réelles Sont Sales

Pourquoi on ne peut pas sauter cette étape

🏠 Exemple : Dataset Immobilier de Casablanca

10 000 annonces collectées - Voici ce qu'on trouve :

🕳️ Valeurs Manquantes

15% des prix absents

8% des surfaces vides

→ Impossible de calculer

👥 Doublons

200 annonces identiques

Même adresse, même prix

→ Biais dans l'entraînement

🎯 Outliers

Prix : 50 millions €

Surface : -20 m²

→ Erreurs évidentes

⚠️ Sans preprocessing : Le modèle apprend des erreurs et produit des prédictions absurdes
💡 80% du temps d'un Data Scientist = Nettoyage des données
2 / 12

🔍 Étape 0 : Exploration des Données (EDA)

Comprendre avant de nettoyer

📊 Questions Essentielles

1Quelle est la taille du dataset ?

Nombre de lignes × colonnes → 10 000 lignes × 12 colonnes

2Quels types de variables ?

Numériques : Prix, Surface, Chambres
Catégorielles : Quartier, Type, État

3Combien de valeurs manquantes ?

Prix : 1 500 (15%), Surface : 800 (8%), Quartier : 0

4Distribution des variables ?

Prix : 100k - 800k (médiane 280k)
Outliers possibles au-delà de 2M

# Code Python pour l'exploration df.info() # Types et valeurs non-null df.describe() # Statistiques descriptives df.isnull().sum() # Comptage des NaN
3 / 12

👥 Éliminer les Doublons

Éviter de compter deux fois la même information

❌ Problème

Maison A: 150m², 3ch, 280k€
Maison A: 150m², 3ch, 280k€
Maison B: 120m², 2ch, 220k€
Maison A: 150m², 3ch, 280k€

250 doublons détectés !

✅ Solution

Maison A: 150m², 3ch, 280k€
Maison B: 120m², 2ch, 220k€
Maison C: 200m², 4ch, 450k€

Doublons supprimés ✓

⚠️ Attention : Doublons partiels (même adresse, prix différent) → Investiguer avant de supprimer
# Supprimer les doublons complets df_clean = df.drop_duplicates() # Supprimer selon certaines colonnes df_clean = df.drop_duplicates(subset=['adresse', 'surface'])
4 / 12

🎯 Identifier les Valeurs Aberrantes

Outliers : Erreurs ou valeurs extrêmes réelles ?

📊 3 Méthodes de Détection

1️⃣ Visualisation

Boxplot

Repère visuel des valeurs extrêmes

📦📊

2️⃣ Z-Score

Écarts-types

|Z| > 3 = outlier
(99.7% des données)

Z > 3

3️⃣ IQR

Intervalle interquartile

< Q1 - 1.5×IQR
> Q3 + 1.5×IQR

Hors IQR

🏠 Exemple Immobilier

Distribution normale :

150k - 600k € (99% des cas)

✓ Valeurs attendues

Outliers détectés :

15 millions € ❌

-50 000 € ❌

✗ À investiguer

⚠️ Outlier ≠ Toujours supprimer (peut être réel : palais royal !)
5 / 12

🔧 Que Faire des Outliers ?

4 stratégies selon le contexte

1Supprimer

Quand : Erreur évidente de saisie

Exemple : Surface = -20 m² → Suppression

2Capper (Plafonner)

Quand : Valeur extrême mais pas impossible

Exemple : Prix 5M → Remplacer par 99e percentile (800k) → Capping

3Transformer

Quand : Distribution asymétrique

Exemple : Appliquer log(prix) pour réduire l'impact → Transformation

4Garder

Quand : Valeur légitime et informative

Exemple : Palais à 15M (vérifié) → Conserver

🎯 Règle d'or : Contexte métier > Règle statistique automatique
6 / 12

🕳️ Traiter les Valeurs Manquantes

Stratégies selon le pourcentage manquant

% Manquant Stratégie Action
< 5% Supprimer les lignes Suppression
5-40% Imputation intelligente Moyenne / Médiane / Mode
> 40% Supprimer la colonne Suppression colonne
100% Supprimer immédiatement ❌ Inutile

🧠 Techniques d'Imputation Avancées

  • Moyenne/Médiane : Pour variables numériques
  • Mode : Pour variables catégorielles
  • KNN Imputer : Utilise les voisins similaires
  • Imputation par groupe : Médiane par quartier
  • Indicateur manquant : Créer colonne "était_manquant" (peut être informatif !)
# Imputation simple df['prix'].fillna(df['prix'].median(), inplace=True) # Imputation par groupe df['prix'].fillna(df.groupby('quartier')['prix'].transform('median'))
7 / 12

⚖️ Mettre les Variables à la Même Échelle

Scaling : Normalisation vs Standardisation

⚠️ Problème sans scaling :
Surface : 50-300 m² vs Prix : 100 000 - 500 000€
→ Le modèle donne trop d'importance au prix !

📊 Min-Max (0-1)

Formule :

X' = (X - min) / (max - min)

Résultat : Toutes les valeurs entre 0 et 1

Quand l'utiliser :

  • Distribution uniforme
  • Pas d'outliers
  • Neural Networks
✓ Garde la forme ✗ Sensible aux outliers

📈 Z-Score (μ=0, σ=1)

Formule :

X' = (X - μ) / σ

Résultat : Moyenne 0, écart-type 1

Quand l'utiliser :

  • Distribution normale
  • Présence d'outliers
  • Régression, SVM, KNN
✓ Résistant outliers ⚠ Valeurs > 1 possibles
# Min-Max Scaling from sklearn.preprocessing import MinMaxScaler scaler = MinMaxScaler() df_scaled = scaler.fit_transform(df[['surface', 'prix']]) # Standardisation (Z-score) from sklearn.preprocessing import StandardScaler scaler = StandardScaler() df_scaled = scaler.fit_transform(df[['surface', 'prix']])
8 / 12

✂️ Sélection des Features

Garder seulement les meilleures variables

🎯 Pourquoi sélectionner ?

🚀

Réduire l'overfitting

Moins de bruit

Accélérer l'entraînement

Moins de calculs

📖

Améliorer l'interprétabilité

Plus simple à comprendre

1️⃣ Filter Methods

Critères statistiques

  • Corrélation avec target
  • Variance > seuil
  • Chi-2 test
Rapide

2️⃣ Wrapper Methods

Test de combinaisons

  • RFE (Recursive Feature Elimination)
  • Forward/Backward selection
Lent Précis

3️⃣ Embedded Methods

Importance dans le modèle

  • Random Forest importance
  • Lasso (L1)
Efficace

📊 Exemple : 50 features → Top 15

Avant : Accuracy 82% (overfitting)

Après : Accuracy 85% (meilleure généralisation)

💡 Plus de features ≠ Meilleur modèle
9 / 12

✂️ Diviser Intelligemment les Données

Train / Validation / Test

📊 Les 3 Ensembles

🎓 Train (60%)

Rôle : Entraîner le modèle

Le modèle apprend les patterns sur ces données

6000 maisons

🔧 Validation (20%)

Rôle : Optimiser hyperparamètres

Ajuster le modèle sans toucher au test

2000 maisons

🏆 Test (20%)

Rôle : Évaluation finale

Sanctuaire : 1 seule utilisation !

2000 maisons

⚠️ Règles d'Or du Split

  • Split AVANT preprocessing (éviter data leakage)
  • Stratified split si classes déséquilibrées
  • Temporel split si données temporelles
  • Test = sanctuaire (ne jamais utiliser avant la fin)
# Split Train/Test from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42, stratify=y )
10 / 12

🔄 Le Workflow Preprocessing Complet

Les étapes dans l'ordre

1
Exploration (EDA)

Comprendre les données : types, distribution, problèmes

2
Doublons

Supprimer les entrées identiques

3
Outliers

Détecter et traiter (supprimer / capper / transformer)

4
Valeurs Manquantes

Imputer ou supprimer selon le %

5
Encoding Catégorielles

One-Hot, Label Encoding, Target Encoding

6
Feature Engineering

Créer nouvelles features pertinentes

7
Scaling

Normalisation ou Standardisation

8
Feature Selection

Garder les meilleures variables

9
Split Train/Val/Test

Diviser pour entraînement et évaluation

✅ Données prêtes pour le Machine Learning !
11 / 12

✅ Checklist Avant d'Entraîner

Vérifications essentielles

Pas de valeurs manquantes (NaN)

Vérifier : df.isnull().sum() == 0

Pas de doublons

Vérifier : df.duplicated().sum() == 0

Outliers traités

Supprimés, cappés ou transformés selon contexte

Variables catégorielles encodées

One-Hot ou Label Encoding appliqué

Variables numériques scaled

Normalisation ou Standardisation selon l'algo

Features pertinentes créées

Feature engineering appliqué si nécessaire

Split Train/Val/Test effectué

Généralement 60/20/20

Pas de data leakage

Preprocessing fait APRÈS le split

"Clean data is happy data"
Des données bien préparées = 70% du succès

🚀 Prochaine étape : Feature Engineering
12 / 12