0% ont trouvé ce document utile (0 vote)
7 vues4 pages

Prétraitement des Données en ML

Le document présente un atelier de formation sur le prétraitement des données en machine learning, dirigé par Dr. OM HENI Nizar, avec des objectifs pédagogiques clairs pour les étudiants de 5ème année en ingénierie des données. Il couvre des techniques essentielles telles que la gestion des valeurs manquantes, la détection et le traitement des outliers, ainsi que l'encodage des variables catégorielles. Des études de cas et des exercices pratiques sont inclus pour illustrer l'importance du prétraitement dans l'amélioration des performances des modèles.

Transféré par

Amine Baklouti
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
7 vues4 pages

Prétraitement des Données en ML

Le document présente un atelier de formation sur le prétraitement des données en machine learning, dirigé par Dr. OM HENI Nizar, avec des objectifs pédagogiques clairs pour les étudiants de 5ème année en ingénierie des données. Il couvre des techniques essentielles telles que la gestion des valeurs manquantes, la détection et le traitement des outliers, ainsi que l'encodage des variables catégorielles. Des études de cas et des exercices pratiques sont inclus pour illustrer l'importance du prétraitement dans l'amélioration des performances des modèles.

Transféré par

Amine Baklouti
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

# 🧠 Workshop Machine Learning — Session 1 ## **Prétraitement des Données (Data

Sciences **Formateur :** Dr. OM HENI Nizar | **Date :** 01/11/2025 --- ## 📋
Preprocessing)** **Durée :** 60 minutes | **Public :** Étudiants 5ème année Ingénieur Data
Objectifs
pédagogiques de la session À l'issue de cette session, les participants seront capables de : -
Diagnostiquer et traiter les problèmes de qualité des données - Appliquer les techniques
appropriées d'imputation des valeurs manquantes - Détecter et gérer les outliers selon le
contexte métier - Choisir et appliquer les bonnes méthodes de normalisation/standardisation -

reproductible --- ## 🗺️
Encoder efficacement les variables catégorielles - Structurer un pipeline de preprocessing
Plan détaillé de la session 1. **Introduction** - Importance du
preprocessing dans le pipeline ML 2. **Théorie : Nettoyage des données** - Valeurs
manquantes, doublons, outliers 3. **Pratique : Exploration et nettoyage** - Hands-on sur

🎯
dataset Kaggle 4. **Q&A et transition** - Questions et préparation session suivante --- #
Introduction : Le preprocessing, fondation du ML ##
1️⃣
Pourquoi le preprocessing est-il critique
? Le preprocessing représente **60-80% du temps** d'un projet ML en entreprise. Sans cette
étape : - **Garbage In, Garbage Out** : modèles biaisés et peu fiables - **Convergence
difficile** : algorithmes instables ou qui n'apprennent pas - **Performances dégradées** :

production ## 📊
métriques artificiellement mauvaises - **Déploiement impossible** : modèles non-robustes en
Impact quantifiable **Étude de cas réel :** Modèle de prédiction de prix
immobilier - **Sans preprocessing :** RMSE = 45,000€, R² = 0.65 - **Avec preprocessing :**
RMSE = 28,000€, R² = 0.87 - **Gain :** +34% d'amélioration des performances ##
pipeline ML complet ``` Données brutes → Preprocessing → Feature Engineering → Modeling
🔄 Le

Production variable fiable features optimal valides robuste ``` --- # 2️⃣
→ Evaluation → Deployment ↑ ↑ ↑ ↑ ↑ ↑ Qualité Transformation Création Algorithme Métriques
Théorie : Nettoyage et

### 🔍
transformation des données ## 2.1 Gestion des valeurs manquantes - Approche stratégique
Diagnostic des valeurs manquantes Les valeurs manquantes ne sont **jamais
aléatoires** en pratique : | Type de manque | Description | Stratégie | |----------------|-------------|----
-------| | **MCAR** (Missing Completely At Random) | Absence totalement aléatoire |
Suppression acceptable | | **MAR** (Missing At Random) | Dépend d'autres variables

valeur manquante elle-même | Modélisation explicite | ### 📈


observées | Imputation sophistiquée | | **MNAR** (Missing Not At Random) | Dépend de la
Seuils de décision pratiques
```python # Règles métier pour la gestion des valeurs manquantes missing_percentage =
([Link]().sum() / len(df)) * 100 def missing_strategy(missing_pct): if missing_pct < 5: return
"Suppression sûre" elif missing_pct < 15: return "Imputation simple (médiane/mode)" elif

suppression de la variable" ``` ### 🛠️


missing_pct < 40: return "Imputation avancée (KNN/MICE)" else: return "Considérer
Techniques d'imputation avancées **1. Imputation
statistique classique** ```python from [Link] import SimpleImputer # Variables
numériques : médiane (robuste aux outliers) num_imputer = SimpleImputer(strategy='median')
df[num_cols] = num_imputer.fit_transform(df[num_cols]) # Variables catégorielles : mode
cat_imputer = SimpleImputer(strategy='most_frequent') df[cat_cols] =
cat_imputer.fit_transform(df[cat_cols]) ``` **2. Imputation par proximité (KNN)** ```python from
[Link] import KNNImputer # Utilise les K plus proches voisins pour imputer
knn_imputer = KNNImputer(n_neighbors=5) df_imputed =
knn_imputer.fit_transform(df_numeric) ``` **3. Imputation itérative (MICE)** ```python from
[Link] import enable_iterative_imputer from [Link] import
IterativeImputer # Modélise chaque variable avec valeurs manquantes mice_imputer =

et traitement des outliers ### 🎯


IterativeImputer(random_state=42) df_mice = mice_imputer.fit_transform(df) ``` ## 2.2 Détection
Définition contextuelle des outliers Un outlier n'est **jamais
absolu** - il dépend du contexte métier : - **Revenue = 1M€** → Normal pour un CEO, aberrant
pour un stagiaire - **Température = 45°C** → Normal au Sahara, aberrant à Paris ###
Méthodes de détection **1. Méthode IQR (Interquartile Range) - La plus robuste** ```python def
📊
detect_outliers_iqr(df, column): Q1 = df[column].quantile(0.25) Q3 = df[column].quantile(0.75)
IQR = Q3 - Q1 lower_bound = Q1 - 1.5 * IQR upper_bound = Q3 + 1.5 * IQR outliers =
df[(df[column] < lower_bound) | (df[column] > upper_bound)] return outliers, lower_bound,
upper_bound ``` **2. Z-Score (distribution normale)** ```python from scipy import stats def
detect_outliers_zscore(df, column, threshold=3): z_scores = [Link]([Link](df[column]))
outliers = df[z_scores > threshold] return outliers ``` **3. Isolation Forest (multivarié)** ```python
from [Link] import IsolationForest iso_forest = IsolationForest(contamination=0.1,

== -1 ``` ### 🎯
random_state=42) outliers = iso_forest.fit_predict(df[numeric_columns]) df['is_outlier'] = outliers
Stratégies de traitement | Contexte | Action recommandée | Justification | |-------
---|-------------------|---------------| | **Erreur de saisie** | Correction ou suppression | Données
invalides | | **Valeur extrême légitime** | Conservation | Information précieuse | | **Anomalie
détectable** | Traitement spécial | Cas particulier | | **Bruit de mesure** | Winsorization
(écrêtage) | Réduction impact | ```python # Winsorization - écrêtage aux percentiles from

[0.05, 0.05]) ``` ## 2.3 Normalisation et standardisation - Choix technique ### ⚖️


[Link] import winsorize df['variable_winsorized'] = winsorize(df['variable'], limits=
Comparaison
des méthodes | Méthode | Formule | Résultat | Usage optimal | |---------|---------|----------|------------
---| | **StandardScaler** | (x - μ) / σ | μ=0, σ=1 | SVM, Regression, PCA | | **MinMaxScaler** | (x
- min) / (max - min) | [0,1] | Neural Networks, KNN | | **RobustScaler** | (x - médiane) / IQR |

Distribution normale | Données asymétriques | ### 🔧


Centré robuste | Données avec outliers | | **PowerTransformer** | Box-Cox/Yeo-Johnson |
Implémentation pratique ```python from
[Link] import StandardScaler, MinMaxScaler, RobustScaler, PowerTransformer
# Pipeline de normalisation def create_scaler_pipeline(method='standard'): scalers = {
'standard': StandardScaler(), 'minmax': MinMaxScaler(), 'robust': RobustScaler(), 'power':
PowerTransformer(method='yeo-johnson') } return scalers[method] # Application avec
sauvegarde des paramètres scaler = create_scaler_pipeline('standard') X_train_scaled =

### ⚠️ Piège fréquent - Data Leakage ```python # ❌


scaler.fit_transform(X_train) X_test_scaled = [Link](X_test) # JAMAIS fit sur test ! ```
INCORRECT - Fuite de données scaler =

train_test_split(X_all_scaled) # ✅
StandardScaler() X_all_scaled = scaler.fit_transform(X_all) X_train, X_test =
CORRECT - Pas de fuite X_train, X_test =
train_test_split(X_all) scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train)

🏷️
X_test_scaled = [Link](X_test) ``` ## 2.4 Encodage des variables catégorielles ###
Stratégies d'encodage par type de variable **Variables ordinales** (ordre important) :
```python # Exemple : Niveau d'éducation education_order = ['Primaire', 'Collège', 'Lycée',
'Licence', 'Master', 'Doctorat'] df['education_encoded'] = df['education'].map( {level: i for i, level in
enumerate(education_order)} ) ``` **Variables nominales** (pas d'ordre) : ```python # One-Hot
Encoding avec gestion des catégories rares from [Link] import OneHotEncoder
# Grouper les catégories rares (< 5% des observations) def group_rare_categories(series,
threshold=0.05): value_counts = series.value_counts(normalize=True) rare_categories =
value_counts[value_counts < threshold].index series_cleaned = [Link](rare_categories,
'Other') return series_cleaned # Application df['city_cleaned'] = group_rare_categories(df['city'])
encoder = OneHotEncoder(drop='first', sparse_output=False, handle_unknown='ignore')
city_encoded = encoder.fit_transform(df[['city_cleaned']]) ``` **Variables haute cardinalité** (> 10
catégories) : ```python # Target Encoding avec validation croisée pour éviter l'overfitting from
category_encoders import TargetEncoder target_encoder = TargetEncoder(cols=

X_test_encoded = target_encoder.transform(X_test) ``` --- #


Prices Kaggle ##
3️⃣
['high_cardinality_var']) X_train_encoded = target_encoder.fit_transform(X_train, y_train)

🎯 Atelier Pratique : Dataset House


Objectifs de l'atelier 1. **Diagnostic complet** du dataset (qualité,
distribution, corrélations) 2. **Nettoyage méthodique** (valeurs manquantes, outliers, doublons)

reproductible** avec sauvegarde des transformateurs ## 📊


3. **Transformation appropriée** (encoding, scaling, feature creation) 4. **Pipeline
Dataset : House Prices - Advanced
Regression Techniques **Contexte :** Prédire le prix de vente de maisons à Ames, Iowa (USA) -
**79 variables explicatives** (23 nominales, 23 ordinales, 14 discrètes, 20 continues) - **1460
observations d'entraînement** - **Variable cible :** SalePrice (prix de vente en dollars) ###
Phase 1 : Exploration diagnostique ```python import pandas as pd import numpy as np import
🔍
[Link] as plt import seaborn as sns from sklearn.model_selection import
train_test_split from [Link] import StandardScaler, LabelEncoder,
OneHotEncoder from [Link] import SimpleImputer # Chargement et première
exploration df = pd.read_csv('[Link]') print(f"Dataset shape: {[Link]}") print(f"Memory
usage: {df.memory_usage(deep=True).sum() / 1024**2:.2f} MB") # Vue d'ensemble de la qualité
des données missing_summary = [Link]({ 'Column': [Link], 'Missing_Count':
[Link]().sum(), 'Missing_Percentage': ([Link]().sum() / len(df)) * 100, 'Dtype': [Link] })
missing_summary = missing_summary[missing_summary['Missing_Count'] >
0].sort_values('Missing_Percentage', ascending=False) print(missing_summary) # Analyse de la
variable cible [Link](figsize=(12, 4)) [Link](1, 2, 1) [Link](df['SalePrice'], kde=True)
[Link]('Distribution du prix de vente') [Link](1, 2, 2) [Link](y=df['SalePrice'])
[Link]('Détection d\'outliers sur SalePrice') plt.tight_layout() [Link]() # Statistiques
descriptives par type de variable numeric_cols = df.select_dtypes(include=['int64',
'float64']).[Link]() categorical_cols = df.select_dtypes(include=['object']).[Link]()

{len(categorical_cols)}") ``` ### 🧹


print(f"Variables numériques : {len(numeric_cols)}") print(f"Variables catégorielles :
Phase 2 : Nettoyage méthodique ```python # 1. Gestion
stratégique des valeurs manquantes def analyze_missing_patterns(df): """Analyse les patterns
de valeurs manquantes""" missing_matrix = [Link]() # Variables avec beaucoup de manquant
(> 40%) - Candidates à la suppression high_missing =
missing_summary[missing_summary['Missing_Percentage'] > 40]['Column'].tolist()
print(f"Variables avec >40% de manquant : {high_missing}") # Variables avec pattern logique de
manquant logical_missing = ['PoolQC', 'MiscFeature', 'Alley', 'Fence', 'FireplaceQu']
print(f"Variables où 'manquant' = 'absent' : {logical_missing}") return high_missing,
logical_missing high_missing_vars, logical_missing_vars = analyze_missing_patterns(df) #
Stratégie de nettoyage appliquée df_clean = [Link]() # Suppression des variables trop
incomplètes df_clean = df_clean.drop(columns=high_missing_vars) # Remplacement logique
pour les variables où "manquant" signifie "absent" for col in logical_missing_vars: if col in
df_clean.columns: df_clean[col] = df_clean[col].fillna('None') # Imputation pour les variables
numériques restantes remaining_numeric_missing =
df_clean[numeric_cols].columns[df_clean[numeric_cols].isnull().any()].tolist() for col in
remaining_numeric_missing: if col != 'SalePrice': # Ne pas imputer la cible ! # Utiliser médiane
pour robustesse aux outliers df_clean[col] = df_clean[col].fillna(df_clean[col].median()) #
Imputation pour variables catégorielles remaining_categorical_missing =
df_clean[categorical_cols].columns[df_clean[categorical_cols].isnull().any()].tolist() for col in
remaining_categorical_missing: df_clean[col] = df_clean[col].fillna(df_clean[col].mode()[0])
print(f"Valeurs manquantes après nettoyage : {df_clean.isnull().sum().sum()}") ``` ```python # 2.
Détection et traitement des outliers def detect_and_treat_outliers(df, target_col='SalePrice'):
"""Détection contextuelle des outliers""" # Outliers sur la variable cible Q1 =
df[target_col].quantile(0.25) Q3 = df[target_col].quantile(0.75) IQR = Q3 - Q1
outlier_threshold_low = Q1 - 1.5 * IQR outlier_threshold_high = Q3 + 1.5 * IQR outliers_target =
df[(df[target_col] < outlier_threshold_low) | (df[target_col] > outlier_threshold_high)]
print(f"Outliers détectés sur {target_col} : {len(outliers_target)}
({len(outliers_target)/len(df)*100:.1f}%)") # Analyse contextuelle des outliers if
len(outliers_target) > 0: print("Caractéristiques des maisons 'outliers' :")
print(outliers_target[['GrLivArea', 'TotalBsmtSF', 'OverallQual', target_col]].describe()) # Décision
: conserver les outliers légitimes, supprimer les erreurs évidentes # Exemple : maisons avec
surface habitable énorme mais prix très bas suspicious_outliers = df[ (df['GrLivArea'] > 4000) &
(df[target_col] < 200000) ] print(f"Outliers suspects (grande surface, prix bas) :
{len(suspicious_outliers)}") # Suppression des outliers suspects uniquement df_clean =
[Link](suspicious_outliers.index) return df_clean, outliers_target df_clean, outliers_info =

``` ###🔧
detect_and_treat_outliers(df_clean) print(f"Dataset après traitement outliers : {df_clean.shape}")
Phase 3 : Transformation et encodage ```python # 3. Pipeline de preprocessing
complet from [Link] import StandardScaler, OneHotEncoder from
[Link] import ColumnTransformer from [Link] import Pipeline # Mise à jour
des listes de colonnes après nettoyage numeric_cols = df_clean.select_dtypes(include=['int64',
'float64']).[Link]() categorical_cols = df_clean.select_dtypes(include=
['object']).[Link]() # Retirer la variable cible des features if 'SalePrice' in numeric_cols:
numeric_cols.remove('SalePrice') # Séparation X et y X = df_clean.drop('SalePrice', axis=1) y =
df_clean['SalePrice'] # Split train/test AVANT preprocessing pour éviter le data leakage X_train,
X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42,
stratify=[Link](y, q=5, labels=False) ) # Pipeline de preprocessing numeric_transformer =
Pipeline(steps=[ ('imputer', SimpleImputer(strategy='median')), ('scaler', StandardScaler()) ])
categorical_transformer = Pipeline(steps=[ ('imputer', SimpleImputer(strategy='constant',
fill_value='missing')), ('onehot', OneHotEncoder(drop='first', handle_unknown='ignore',
sparse_output=False)) ]) # ColumnTransformer pour appliquer les bonnes transformations
preprocessor = ColumnTransformer( transformers=[ ('num', numeric_transformer,
numeric_cols), ('cat', categorical_transformer, categorical_cols) ]) # Application du
preprocessing X_train_processed = preprocessor.fit_transform(X_train) X_test_processed =
[Link](X_test) print(f"Shape après preprocessing :") print(f"X_train :
{X_train_processed.shape}") print(f"X_test : {X_test_processed.shape}") # Sauvegarde du
preprocessor pour réutilisation import joblib [Link](preprocessor,
'house_prices_preprocessor.pkl') print("Preprocessor sauvegardé !") ``` ## 📊 Livrables de
l'atelier 1. **Notebook complet** : `Session1_Preprocessing_HousePrices.ipynb` 2. **Dataset
nettoyé** : X_train_processed, X_test_processed 3. **Preprocessor sauvegardé** :

transformation --- # 🎯 ✅
`house_prices_preprocessor.pkl` 4. **Rapport de nettoyage** : Statistiques avant/après
Récapitulatif et points clés ## Check-list du preprocessing réussi - [ ]
**Diagnostic complet** : valeurs manquantes, outliers, distributions - [ ] **Stratégie
contextualisée** : pas de règles automatiques aveugles - [ ] **Pipeline reproductible** :

uniquement - [ ] **Documentation** : choix justifiés et tracés ## 🎪


transformations sauvegardées et versionnées - [ ] **Prévention du data leakage** : fit sur train
Erreurs fréquentes à éviter 1.
**Data leakage** : fit des transformations sur tout le dataset 2. **Suppression systématique** :
outliers peuvent être informatifs 3. **Imputation aveugle** : ne pas tenir compte du contexte

explosion** : variables catégorielles haute cardinalité ## 🎨


métier 4. **Oubli de sauvegarde** : impossibilité de reproduire en production 5. **One-Hot
Prochaine session : Feature
Engineering Le preprocessing a préparé des données **propres et cohérentes**. La session

**Preview** : Polynomial features, interactions, feature selection, PCA... --- ##


complémentaires ###
📚
suivante créera des **features intelligentes** pour maximiser les performances des modèles.

📖 Ressources
Documentation officielle - [Scikit-learn Preprocessing]([Link]

([Link] ### 🎓
[Link]/stable/modules/[Link]) - [Pandas User Guide]
Approfondissement - **Kaggle Learn** :
[Data Cleaning Course]([Link] - **DataCamp** : [Data

learning-in-python) ### 🛠️
Preprocessing in Python]([Link]
Outils avancés - **Pandas Profiling** : EDA automatique - **Great

preprocessing --- **🎯


Expectations** : Tests de qualité des données - **Optuna** : Optimisation des pipelines de
Fin de la Session 1 - Préparation Session 2 : Feature Engineering**

Vous aimerez peut-être aussi