2  đŸ§č Data Wrangling (Nettoyage et PrĂ©paration)

2.1 🔍 Valeurs Manquantes

💡 Concept ClĂ© : Le Mythe du Dataset Parfait

Dans l’investigation numĂ©rique, le Data Wrangling est le socle de l’intĂ©gritĂ© du verdict. Le premier dĂ©fi est la donnĂ©e manquante (NaN). Avant de “boucher un trou”, l’enquĂȘteur doit se demander : “Pourquoi cet indice a-t-il Ă©tĂ© effacĂ© ?”

2.1.1 đŸ•”ïžâ€â™‚ïž MĂ©canismes de l’Absence

La stratĂ©gie de traitement dĂ©pend de la nature statistique de l’absence :

MCAR

AlĂ©atoire Pur L’absence est un pur hasard.

  • Exemple : Une goutte de cafĂ© sur un formulaire rend l’ñge illisible.

MAR

AlĂ©atoire Conditionnel L’absence dĂ©pend d’une autre variable connue.

  • Exemple : Un capteur omet le rythme cardiaque uniquement quand le patient dort.

MNAR

Non AlĂ©atoire L’absence dĂ©pend de la valeur elle-mĂȘme.

  • Exemple : Les hauts revenus refusent de dĂ©clarer leur salaire. L’absence est un indice en soi.

2.1.2 đŸ› ïž StratĂ©gies de Traitement

# ❌ Suppression des lignes avec au moins un NaN
df_clean = df.dropna()

# ❌ Suppression d'une colonne trop vide
df_clean = df.drop(columns=['Variable_Inutile'])

Verdict : À n’utiliser que si le manque est MCAR et reprĂ©sente moins de 5% du total. Risque majeur de perte d’information.

# ✅ Remplissage par la MĂ©diane (Robuste aux outliers)
df['Salaire'] = df['Salaire'].fillna(df['Salaire'].median())

# ✅ Remplissage par le Mode (Pour le qualitatif)
df['Ville'] = df['Ville'].fillna(df['Ville'].mode()[0])

Verdict : Préserve la taille du dataset, mais réduit la variance globale.

from sklearn.impute import IterativeImputer

# 🚀 Utilise l'IA pour "deviner" les valeurs manquantes
imputer = IterativeImputer(max_iter=10, random_state=42)
df_impute = pd.DataFrame(imputer.fit_transform(df), columns=df.columns)

Verdict : La mĂ©thode la plus rigoureuse. Utilise les corrĂ©lations entre variables pour estimer l’absence.

⚠ Danger : Ignorer le MNAR

Si vos donnĂ©es sont MNAR, boucher les trous sans prĂ©caution dĂ©truit l’information. Astuce Pro : CrĂ©ez une colonne binaire Salaire_Est_Manquant pour que le modĂšle “sache” qu’il y a eu une absence suspecte.

🎒 Astuce Pro : SĂ©ries Temporelles

Pour les flux chronologiques (Bourse, IoT), utilisez la méthode LOCF (Last Observation Carried Forward) : df.fillna(method='ffill').

2.2 đŸ•”ïžâ€â™‚ïž Mission 1

L’inspecteur principal vous a transmis un dossier contenant les donnĂ©es de toutes les personnes prĂ©sentes sur les lieux. Voici comment la base a Ă©tĂ© constituĂ©e :

import pandas as pd
import numpy as np

data = {
    'nom': ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'],
    'age': [25, np.nan, 35, 42, np.nan],
    'has_alibi': [True, False, False, True, False]
}
df_suspects = pd.DataFrame(data)

Cependant, la base est bruitée. Votre premier objectif : nettoyer les valeurs manquantes et filtrer les suspects qui ont un alibi (colonne has_alibi).

Complétez le code ci-dessous pour démasquer les coupables potentiels.

2.3 đŸ§č Harmonisation & Correction

L’enfer des donnĂ©es saisies manuellement

L’hĂ©tĂ©rogĂ©nĂ©itĂ© des formats est un obstacle majeur au traitement algorithmique automatisĂ©. Un algorithme de Machine Learning est d’une bĂȘtise absolue concernant la sĂ©mantique : pour lui, “Homme”, “homme” et “H” (avec un espace Ă  la fin) sont trois catĂ©gories totalement distinctes. L’uniformitĂ© est la rĂšgle d’or pour Ă©viter la dilution de la puissance statistique de votre modĂšle.

L’harmonisation est une Ă©tape de nettoyage stricte visant Ă  unifier le “grain” de la donnĂ©e. Elle repose sur deux piliers principaux : le traitement du texte libre et la standardisation temporelle.

2.3.1 đŸ”€ Nettoyage Typographique

Les données issues de formulaires ou de saisies manuelles sont systématiquement polluées par des erreurs typographiques. Les corriger nécessite une approche industrielle.

Les Rùgles d’Or de la Typographie :

  1. La Casse UnifiĂ©e : Tout convertir en minuscules (ou majuscules) pour regrouper les variations d’une mĂȘme entitĂ©.
  2. Le Trim (Élagage) : Supprimer les espaces invisibles en dĂ©but et fin de chaĂźne.
  3. Le Remplacement (Regex) : Utiliser les expressions réguliÚres pour supprimer les caractÚres spéciaux indésirables ou extraire des motifs précis.
import pandas as pd

# ❌ Avant : ['  Homme', 'homme', 'H', 'Femme ']
df['Genre'] = df['Genre'].str.lower()       # Étape 1 : Tout en minuscules -> ['  homme', 'homme', 'h', 'femme ']
df['Genre'] = df['Genre'].str.strip()       # Étape 2 : Enlever les espaces -> ['homme', 'homme', 'h', 'femme']
df['Genre'] = df['Genre'].replace({'h': 'homme', 'f': 'femme'}) # Étape 3 : Mapping
# ✅ Aprùs : ['homme', 'homme', 'homme', 'femme']

2.3.2 ⏱ Standardisation Temporelle

Des dates saisies sous des formats multiples (12/04/2026, 2026-04-12, 12 April 26) empĂȘchent toute agrĂ©gation cohĂ©rente et ruinent les modĂšles de sĂ©ries temporelles.

Le Standard Industriel : ISO 8601

L’imposition du format standard international AAAA-MM-JJ (AnnĂ©e-Mois-Jour) garantit une manipulation sans erreur par toutes les bibliothĂšques logicielles (Python, SQL, Spark).

De plus, il est souvent critique d’extraire des Features (CaractĂ©ristiques) Temporelles Ă  partir d’une date (comme le jour de la semaine ou le mois) car l’algorithme ne “comprend” pas une date brute.

# Convertir une colonne hétérogÚne en un objet Datetime standardisé
df['Date_Achat'] = pd.to_datetime(df['Date_Achat'], format='mixed')

# Extraction d'informations temporelles (Feature Engineering de base)
df['Annee'] = df['Date_Achat'].dt.year
df['Mois'] = df['Date_Achat'].dt.month
df['Est_Weekend'] = df['Date_Achat'].dt.dayofweek > 4 # Retourne un booléen

Validation de Domaine

Une fois vos donnĂ©es harmonisĂ©es, appliquez toujours une Validation de Domaine. S’assurer que les donnĂ©es respectent les plages de valeurs logiques propres au mĂ©tier (ex: l’ñge ne peut pas ĂȘtre de 250 ans, un mois ne peut pas dĂ©passer 12) est la derniĂšre barriĂšre de sĂ©curitĂ© avant la modĂ©lisation.

2.4 📈 Transformation et Normalisation

Le problÚme des échelles disparates

Imaginez que vous prĂ©disiez le prix d’une maison avec deux variables : le Nombre de chambres (entre 1 et 5) et le Prix du terrain (entre 10 000 et 1 000 000 €). Pour un algorithme mathĂ©matique (comme un rĂ©seau de neurones), la variable avec les plus grands nombres va â€œĂ©craser” l’autre lors du calcul des gradients, la rendant virtuellement invisible. La transformation numĂ©rique ramĂšne tout le monde sur un pied d’égalitĂ©.

Il existe deux grandes approches pour rĂ©soudre ce problĂšme, avec des formules et des cas d’usage trĂšs diffĂ©rents.

2.4.1 📏 Normalisation (Min-Max)

La normalisation compresse (ou Ă©tire) les donnĂ©es pour qu’elles s’insĂšrent exactement dans une plage dĂ©finie, gĂ©nĂ©ralement entre 0 et 1.

La mathématique (Formule LaTeX) : X_{norm} = \frac{X - X_{min}}{X_{max} - X_{min}}

  • Avantage : Maintient toutes les donnĂ©es dans des limites strictes.
  • Le PiĂšge : Comme elle utilise le X_{min} et le X_{max}, elle est extrĂȘmement vulnĂ©rable aux valeurs aberrantes (Outliers). Si une seule maison coĂ»te 1 milliard d’euros (une erreur de saisie), toutes les autres maisons seront Ă©crasĂ©es autour de 0.001.

2.4.2 🎯 Standardisation (Z-Score)

La standardisation ne fixe pas de limites strictes. Elle décale les données pour que la distribution soit centrée sur une moyenne (\mu) de 0, avec un écart-type (\sigma) de 1.

La mathématique : Z = \frac{X - \mu}{\sigma}

  • Avantage : Elle gĂšre globalement mieux les variations naturelles et ne fige pas les donnĂ©es. Elle est indispensable lorsque les donnĂ©es sont collectĂ©es sous des conditions variables (ex: variations d’éclairage pour des images).
  • Alternative pour les extrĂȘmes : S’il y a trop de valeurs aberrantes, on utilise le Robust Scaler. Au lieu de la moyenne, il centre sur la mĂ©diane et divise par l’écart interquartile (IQR).

2.4.3 ⚠ Impact selon l’Algorithme

C’est ici que l’ingĂ©nieur se distingue du dĂ©butant. Faut-il toujours “scaler” ses donnĂ©es ? Non. Cela dĂ©pend de l’algorithme choisi.

  • 🟱 Indispensable (Distance & Gradients) : Pour les modĂšles basĂ©s sur le calcul de distances gĂ©omĂ©triques (K-Nearest Neighbors, SVM) ou sur la descente de gradient (RĂ©seaux de Neurones, RĂ©gression Logistique). Une variable sur une grande Ă©chelle dominerait les plus petites et ralentirait dramatiquement la convergence.
  • 🔮 Inutile (ModĂšles basĂ©s sur les Arbres) : Pour les algorithmes d’ensemble (Arbres de DĂ©cision, Random Forest, XGBoost, LightGBM). Ces modĂšles divisent les donnĂ©es grĂące Ă  des comparaisons de seuils logiques (Si \, X > 10). Les transformations (Z-score ou Min-Max) sont dites monotones : elles prĂ©servent l’ordre absolu. Que le seuil soit 10 ou 0.85, la coupure de l’arbre sera mathĂ©matiquement identique.

Focus Deep Learning : Batchnorm et CMN

Pour des architectures IA complexes, on intĂšgre cette mise Ă  l’échelle directement dans le modĂšle. Par exemple, la Batchnorm (Normalisation par lots) stabilise l’apprentissage Ă  chaque couche d’un rĂ©seau de neurones. En analyse audio (reconnaissance vocale type LibriSpeech), on utilise la CMN (Cepstral Mean Normalization) pour gommer les distorsions liĂ©es au bruit ambiant.

2.5 đŸ•”ïžâ€â™‚ïž Mission 2

Votre instinct Ă©tait bon : Charlie tente de fuir par la mer ! L’inspecteur principal vient de vous faire parvenir le registre piratĂ© des dĂ©parts maritimes d’aujourd’hui.

Exécutez la cellule ci-dessous pour consulter ce nouveau registre :

import pandas as pd

# Registre des embarquements du jour
donnees_port = {
    'passager': ['Alice', 'Bob', 'Charlie', 'Diana', 'Zoe'],
    'navire': ['Le Triton', 'L\'Océan', 'La Mouette', 'L\'Océan', 'Le Poséidon'],
    'quai': [4, 12, 7, 12, 2]
}
df_embarquements = pd.DataFrame(donnees_port)

print("Registre maritime téléchargé.")
display(df_embarquements)

Votre objectif : Croiser (joindre) la liste de vos coupables potentiels avec ce registre maritime pour dĂ©couvrir oĂč se cache Charlie. Indice : Regardez bien le nom des colonnes contenant les noms des individus dans les deux tables !

2.6 đŸ·ïž Encodage des Variables

La barriĂšre de la langue algorithmique

Le Machine Learning est une discipline purement mathĂ©matique : il calcule des gradients, des distances et des probabilitĂ©s. Par consĂ©quent, il ne peut traiter nativement que des nombres. Si vous lui donnez une colonne “Ville” avec “Paris”, “Lyon” et “Marseille”, il plantera. La conversion des variables catĂ©gorielles (textuelles) en format numĂ©rique est donc une Ă©tape obligatoire.

L’expert doit arbitrer entre plusieurs techniques d’encodage selon la nature des catĂ©gories et leur cardinalitĂ© (le nombre de valeurs uniques).

2.6.1 🧼 MĂ©thodes Classiques

  • Le Label Encoding (Étiquettes) : Attribue simplement un nombre entier unique Ă  chaque catĂ©gorie (ex: Paris=1, Lyon=2, Marseille=3).
    • Le PiĂšge : Cette mĂ©thode introduit un “ordre artificiel” (2 est plus grand que 1). Si la variable est nominale (sans ordre), le modĂšle peut dĂ©duire Ă  tort que Lyon est supĂ©rieur Ă  Paris.
    • Quand l’utiliser ? Uniquement pour les variables ordinales (ex: Tailles de vĂȘtement S=1, M=2, L=3).
  • Le One-Hot Encoding (Binaire) : CrĂ©e une nouvelle colonne binaire (0 ou 1) pour chaque modalitĂ© possible de la variable catĂ©gorielle.
    • L’Avantage : Parfait pour Ă©viter un ordre artificiel sur des variables nominales.
    • Le PiĂšge : Si vous avez une variable “Code Postal” (36 000 valeurs), vous allez crĂ©er 36 000 nouvelles colonnes ! C’est ce qu’on appelle le flĂ©au de la dimensionnalitĂ©, qui sature la RAM et provoque du surapprentissage (Overfitting).

2.6.2 🚀 MĂ©thodes AvancĂ©es

Quand le One-Hot Encoding fait exploser votre mĂ©moire, il faut ruser. L’industrie utilise souvent la bibliothĂšque category_encoders pour cela.

  • Le Target Encoding (Moyenne Cible) : Substitue une catĂ©gorie par une statistique tirĂ©e de la variable cible (ce qu’on cherche Ă  prĂ©dire). Par exemple, on remplace “Paris” par le taux de fraude moyen observĂ© Ă  Paris sur l’ensemble d’entraĂźnement.
    • Avantage : Ne crĂ©e aucune nouvelle colonne, trĂšs performant pour les modĂšles basĂ©s sur les arbres (XGBoost).
    • Danger (Target Leakage) : Risque majeur de “fuite de la cible”. Si on calcule la moyenne en incluant la ligne en cours, le modĂšle prend par cƓur le rĂ©sultat au lieu de le prĂ©dire. Il faut appliquer un “lissage” ou calculer la moyenne en excluant la ligne actuelle (Leave-one-out).
  • Le Hashing Encoder (Hachage) : Projette les catĂ©gories dans un espace fini (un nombre dĂ©fini de colonnes, ex: 8 bits) via une fonction de hachage (comme MD5), sans jamais stocker le dictionnaire d’origine.
    • Avantage : Empreinte mĂ©moire minuscule et constante. Accepte de nouvelles catĂ©gories “inconnues” en production sans planter.
    • InconvĂ©nient : Accepte les “collisions” (deux mots diffĂ©rents peuvent ĂȘtre hachĂ©s dans la mĂȘme colonne), ce qui entraĂźne une lĂ©gĂšre perte d’information au profit de la vitesse.

2.6.3 đŸ’» ImplĂ©mentation en Python

import pandas as pd
from category_encoders import TargetEncoder, HashingEncoder

# 1. One-Hot Encoding natif avec Pandas (pour faible cardinalité)
df_onehot = pd.get_dummies(df, columns=['Genre'], drop_first=True)

# 2. Target Encoding (Scikit-learn Contrib)
# On encode la variable "Ville" en fonction de la variable cible "A_Fraude"
target_enc = TargetEncoder(smoothing=10) # Le smoothing évite le Target Leakage
df['Ville_Encoded'] = target_enc.fit_transform(df['Ville'], df['A_Fraude'])

# 3. Hashing Encoder (Pour les trÚs hautes cardinalités comme "ID_Produit")
# On force le résultat sur seulement 8 colonnes (n_components=8)
hash_enc = HashingEncoder(cols=['ID_Produit'], n_components=8)
df_hashed = hash_enc.fit_transform(df)

2.7 TP1 : Le Titanic

Dataset du Titanic ZIP

2.8 🌉 Conclusion et Transition

Vos donnĂ©es sont maintenant propres et prĂȘtes Ă  ĂȘtre analysĂ©es. L’étape suivante consiste Ă  explorer ces donnĂ©es pour en extraire des tendances et des relations.

C’est ce que nous allons voir dans le Chapitre 3 : Analyse Exploratoire des DonnĂ©es (EDA).