Objectifs d'Apprentissage
À la fin de ce module, vous serez capable de :
- Différencier l'apprentissage supervisé, non-supervisé et par renforcement.
- Maîtriser le workflow standard du Machine Learning (données → modèle → prédictions).
- Gérer les défauts réels : valeurs manquantes, outliers, données déséquilibrées.
- Créer et transformer des features pour améliorer les modèles.
- Évaluer correctement les modèles avec K-Fold Cross-Validation.
- Optimiser les hyperparamètres avec GridSearchCV et RandomizedSearchCV.
- Construire un pipeline complet : nettoyage → feature engineering → modélisation.
2.1 - Qu'est-ce que le Machine Learning ?
Définition
Le Machine Learning (apprentissage automatique) est une branche de l'intelligence artificielle qui permet aux ordinateurs d'apprendre à partir des données sans être explicitement programmés.
Exemple : Au lieu de dire à l'ordinateur « Si prix > 100€, classe comme premium », vous lui fournissez 1000 exemples et il apprend le pattern lui-même.
Les Trois Types d'Apprentissage
1️⃣ Apprentissage Supervisé (Supervised Learning)
Vous avez des données étiquetées : chaque entrée (input) a une sortie (output) connue.
- Objectif : Apprendre la relation entre inputs et outputs
- Cas d'Usage : Prédiction, Classification
- Exemples :
- Prédire le prix d'une maison (régression)
- Classifier un email comme spam ou non-spam (classification)
- Prédire si un client va quitter l'entreprise (churn)
2️⃣ Apprentissage Non-Supervisé (Unsupervised Learning)
Vous avez seulement des données, pas d'étiquettes. Le modèle doit découvrir la structure cachée.
- Objectif : Trouver des patterns, grouper des données similaires
- Cas d'Usage : Clustering, Réduction de dimensionalité
- Exemples :
- Segmenter les clients en groupes similaires
- Détecter des anomalies dans les transactions
- Recommander des produits similaires
3️⃣ Apprentissage par Renforcement (Reinforcement Learning)
L'agent apprend en interagissant avec l'environnement et reçoit des récompenses.
Note : Nous n'aborderons pas ce type dans ce cours (plus avancé). Cas d'usage : robotique, jeux vidéo, voitures autonomes.
Schéma Comparatif
Apprentissage Supervisé :
Données (X, y) → Modèle apprend → Prédictions précises
Apprentissage Non-supervisé :
Données (X) → Modèle apprend → Découvre structure
2.2 - Scikit-Learn : La Bibliothèque Standard
Pourquoi Scikit-Learn ?
- ✓Simple et cohérente : Tous les modèles suivent la même interface
- ✓Complète : 200+ algorithmes pré-implémentés
- ✓Bien documentée : Excellente documentation et communauté active
- ✓Performante : Optimisée en C et très rapide
- ✓Gratuite et open-source
Installation
pip install scikit-learn numpy pandas matplotlib
Architecture de Scikit-Learn
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
Structure : sklearn organise tous les outils en modules :
preprocessing : Nettoyage et normalisation
model_selection : Division train-test, cross-validation
linear_model, ensemble : Modèles ML
metrics : Évaluation des performances
2.3 - Le Workflow du Machine Learning
Le Machine Learning suit toujours le même processus. Comprendre chaque étape est crucial.
Étape 1️⃣ : Charger et Explorer les Données
📝 Exemple Python
import pandas as pd
import numpy as np
# Charger les données
data = pd.read_csv('customers.csv')
# Explorer les données
print(data.head()) # 5 premières lignes
print(f"Shape : {data.shape}") # (1000, 5)
print(data.info()) # Types et NaN
print(data.describe()) # Statistiques
# Example output :
# age income credit_score account_years churned
# 0 25 30000 700 2 0
# 1 45 75000 750 5 0
# 2 35 50000 650 3 1
Étape 2️⃣ : Préparer les Données - Features vs Target
CRUCIAL C'est l'étape la plus importante ! Une bonne préparation = un bon modèle.
Concepts Clés
- Features (X) : Les variables d'entrée (les prédicteurs)
- Aussi appelées "variables indépendantes" ou "prédicteurs"
- Ce que vous DONNEZ au modèle
- Exemple : âge, revenu, score de crédit
- Target (y) : La variable de sortie (ce qu'on veut prédire)
- Aussi appelée "variable dépendante" ou "label"
- Ce que vous voulez PRÉDIRE
- Exemple : client a churné (oui/non) = 1 ou 0
📝 Exemple Python
# Séparer features et target
X = data.drop('churned', axis=1) # Toutes les colonnes sauf 'churned'
y = data['churned'] # Seulement la colonne 'churned'
print(f"X shape : {X.shape}") # (1000, 4)
print(f"y shape : {y.shape}") # (1000,)
# Vérifier les valeurs manquantes
print(X.isnull().sum())
print(y.isnull().sum())
Étape 3️⃣ : Diviser les Données (Train-Test Split)
Pourquoi diviser ?
- Entraîner le modèle sur certaines données
- Tester sa performance sur des données jamais vues avant
- Cela évite l'overfitting (le modèle apprend par cœur)
📝 Exemple Python
from sklearn.model_selection import train_test_split
# Diviser 80% entraînement, 20% test
X_train, X_test, y_train, y_test = train_test_split(
X, y,
test_size=0.2, # 20% pour le test
random_state=42 # Pour reproductibilité
)
print(f"Train : {X_train.shape[0]}, Test : {X_test.shape[0]}")
✓ Règles d'Or :
- 80/20 est le standard (80% train, 20% test)
- Utiliser
random_state=42 pour reproductibilité
- JAMAIS évaluer sur les données d'entraînement !
Étape 4️⃣ : Créer et Entraîner un Modèle
📝 Exemple Python
from sklearn.linear_model import LogisticRegression
# Créer une instance du modèle
model = LogisticRegression(random_state=42)
# Entraîner le modèle sur les données d'entraînement
# .fit() = "apprendre" les patterns des données
model.fit(X_train, y_train)
print("✓ Modèle entraîné avec succès!")
Qu'est-ce que .fit() fait ?
Le modèle parcourt les données d'entraînement et apprend les coefficients (poids) qui permettent de prédire le mieux possible.
Étape 5️⃣ : Faire des Prédictions
📝 Exemple Python
# Prédictions sur les données de test
y_pred = model.predict(X_test)
print(f"Premières prédictions : {y_pred[:10]}")
# [0 1 0 0 1 0 1 1 0 1]
# 0 = pas de churn, 1 = churn
# Prédictions pour UNE nouvelle instance
new_customer = [[35, 50000, 680, 3]]
prediction = model.predict(new_customer)
print(f"Prédiction : {prediction[0]}")
# Prédictions avec probabilités
probabilities = model.predict_proba(X_test)
print(f"Prob(no churn), Prob(churn) : {probabilities[:3]}")
# [[0.75 0.25] → 75% chance pas de churn
# [0.30 0.70] → 30% chance pas de churn
# ...
Étape 6️⃣ : Évaluer la Performance
📝 Exemple Python
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
# Accuracy (Précision globale)
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy : {accuracy:.2%}")
# Rapport détaillé
print(classification_report(y_test, y_pred,
target_names=['Pas de Churn', 'Churn']))
# Matrice de confusion
cm = confusion_matrix(y_test, y_pred)
print(cm)
2.4 - Gestion des Données Réelles
IMPORTANT Les données réelles sont toujours imparfaites ! Valeurs manquantes, outliers, déséquilibres... doivent être gérés.
Valeurs Manquantes (Missing Values)
Stratégies pour gérer les valeurs manquantes
1. Supprimer les lignes avec valeurs manquantes
📝 Exemple Python
import pandas as pd
import numpy as np
# Approche 1 : Supprimer TOUTES les lignes avec ANY valeur manquante
data_cleaned_strict = data.dropna()
print(f"Après dropna() strict : {len(data_cleaned_strict)} lignes")
# ⚠️ Problème : Perte excessive de données
# Approche 2 : Garder si au moins 2 valeurs non-NaN
data_cleaned = data.dropna(thresh=2)
print(f"Après dropna(thresh=2) : {len(data_cleaned)} lignes")
2. Remplir avec une valeur constante (Imputation)
📝 Exemple Python
from sklearn.impute import SimpleImputer
# Stratégie 1 : Remplir avec la moyenne
imputer_mean = SimpleImputer(strategy='mean')
X_imputed_mean = imputer_mean.fit_transform(X_train)
# Stratégie 2 : Remplir avec la médiane
imputer_median = SimpleImputer(strategy='median')
X_imputed_median = imputer_median.fit_transform(X_train)
# Stratégie 3 : Remplir avec le mode (plus fréquent)
imputer_freq = SimpleImputer(strategy='most_frequent')
X_imputed_freq = imputer_freq.fit_transform(X_train)
# ⚠️ IMPORTANT : fit sur TRAIN, transform sur TEST
imputer = SimpleImputer(strategy='mean')
X_train_imputed = imputer.fit_transform(X_train)
X_test_imputed = imputer.transform(X_test) # Utiliser SAME imputer!
Quand utiliser quelle stratégie ?
| Stratégie |
Cas d'Usage |
Avantages |
Inconvénients |
| Supprimer |
< 5% manquantes |
Simple, pas de biais |
Perd des données |
| Moyenne/Médiane |
Variables continues |
Garde tous les données |
Peut réduire variance |
| Mode |
Variables catégoriques |
Conserve distribution |
Peut introduire biais |
Détection d'Outliers (Valeurs Aberrantes)
Les outliers sont des valeurs extrêmes qui peuvent biaiser le modèle.
Méthode 1 : Règle 3-Sigma (Écart-type)
📝 Exemple Python
import numpy as np
data = np.array([10, 15, 12, 18, 16, 1000]) # 1000 = outlier
mean = data.mean()
std = data.std()
# 99.7% des données sont entre mean ± 3*std
lower_bound = mean - 3 * std
upper_bound = mean + 3 * std
outliers_mask = (data < lower_bound) | (data > upper_bound)
print(f"Outliers : {data[outliers_mask]}")
Méthode 2 : IQR (Interquartile Range)
📝 Exemple Python
import numpy as np
Q1 = np.percentile(data, 25)
Q3 = np.percentile(data, 75)
IQR = Q3 - Q1
lower_bound_iqr = Q1 - 1.5 * IQR
upper_bound_iqr = Q3 + 1.5 * IQR
outliers_mask_iqr = (data < lower_bound_iqr) | (data > upper_bound_iqr)
print(f"Outliers : {data[outliers_mask_iqr]}")
Méthode 3 : Isolation Forest (Algorithme ML)
📝 Exemple Python
from sklearn.ensemble import IsolationForest
# Isolation Forest détecte les points isolés
iso_forest = IsolationForest(contamination=0.05, random_state=42)
outlier_predictions = iso_forest.fit_predict(data.reshape(-1, 1))
print(f"Outliers : {data[outlier_predictions == -1]}")
✓ Traitement des Outliers :
- Supprimer : Si peu nombreux (< 5%)
- Capper : Limiter aux bornes [min, max]
- Transformer : Appliquer log, sqrt pour réduire l'impact
2.5 - Feature Engineering
Feature Engineering = créer ou transformer les features pour améliorer la performance du modèle.
Types de Feature Engineering
1️⃣ Features Temporelles
📝 Exemple Python
import pandas as pd
import numpy as np
# Convertir en datetime
data['signup_date'] = pd.to_datetime(data['signup_date'])
# Feature 1 : Nombre de jours depuis inscription
reference_date = pd.to_datetime('2023-06-01')
data['days_since_signup'] = (reference_date - data['signup_date']).dt.days
# Feature 2 : Mois d'inscription
data['signup_month'] = data['signup_date'].dt.month
# Feature 3 : Année d'inscription
data['signup_year'] = data['signup_date'].dt.year
2️⃣ Features Arithmétiques (Combinaison)
📝 Exemple Python
# Feature : Dépense moyenne par achat
data['avg_purchase_value'] = data['total_spent'] / data['num_purchases']
# Feature : Log de la dépense (réduire les outliers)
data['log_total_spent'] = np.log1p(data['total_spent'])
3️⃣ Features Catégoriques (One-Hot Encoding)
📝 Exemple Python
# Avant : Colonne catégorique 'city'
# city : ['Paris', 'Lyon', 'Marseille', ...]
# Après : Créer colonnes binaires pour chaque catégorie
data_encoded = pd.get_dummies(data, columns=['city'], prefix='city')
# Résultat :
# city_Lyon : [0, 1, 0, ...]
# city_Marseille : [0, 0, 1, ...]
# city_Paris : [1, 0, 0, ...]
4️⃣ Features Binaires (Flagging)
📝 Exemple Python
# Feature : Est un client VIP (dépense > 500)
data['is_vip'] = (data['total_spent'] > 500).astype(int)
# Feature : Client fidèle (plus de 3 achats)
data['is_loyal'] = (data['num_purchases'] > 3).astype(int)
5️⃣ Binning (Discrétisation)
📝 Exemple Python
# Convertir une variable continue en catégories
data['age_group'] = pd.cut(data['age'],
bins=[0, 30, 50, 70, 150],
labels=['Jeune', 'Adulte', 'Senior', 'Très Senior'])
2.6 - Validation Croisée (K-Fold Cross-Validation)
Le Problème du Train-Test Split Simple
Avec un simple 80/20 split, on utilise seulement 20% des données pour évaluer.
K-Fold Cross-Validation utilise TOUTES les données pour entraîner ET tester.
📝 Exemple Python
from sklearn.model_selection import KFold, cross_val_score
from sklearn.linear_model import LogisticRegression
# K-Fold simple
kfold = KFold(n_splits=5, shuffle=True, random_state=42)
model = LogisticRegression(random_state=42, max_iter=1000)
# Évaluer le modèle avec cross-validation
scores = cross_val_score(model, X, y, cv=kfold, scoring='accuracy')
print(f"Scores par fold : {scores}")
print(f"Score moyen : {scores.mean():.4f}")
print(f"Écart-type : {scores.std():.4f}")
✓ Stratified K-Fold : Pour données déséquilibrées (ex: 90% classe 0, 10% classe 1), utiliser
StratifiedKFold pour garder les proportions.
from sklearn.model_selection import StratifiedKFold
skfold = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
scores = cross_val_score(model, X, y, cv=skfold, scoring='accuracy')
Visualisation : Comment fonctionne K-Fold
100 données divisées en 5 folds :
Fold 1 : | TEST | TRAIN | TRAIN | TRAIN | TRAIN |
Fold 2 : | TRAIN | TEST | TRAIN | TRAIN | TRAIN |
Fold 3 : | TRAIN | TRAIN | TEST | TRAIN | TRAIN |
Fold 4 : | TRAIN | TRAIN | TRAIN | TEST | TRAIN |
Fold 5 : | TRAIN | TRAIN | TRAIN | TRAIN | TEST |
Chaque fois, une partie différente est testée!
Résultats plus robustes car 100% des données sont utilisées.
2.7 - Tuning d'Hyperparamètres avec GridSearchCV
Les hyperparamètres sont les paramètres qu'on définit AVANT l'entraînement.
Exemple de GridSearchCV
📝 Exemple Python
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier
# Définir les hyperparamètres à tester
param_grid = {
'n_estimators': [10, 50, 100, 200],
'max_depth': [5, 10, 15, None],
'min_samples_split': [2, 5, 10],
'min_samples_leaf': [1, 2, 4]
}
# Créer GridSearchCV (144 combinaisons!)
grid_search = GridSearchCV(
estimator=RandomForestClassifier(random_state=42),
param_grid=param_grid,
cv=5, # 5-fold cross-validation
scoring='accuracy',
n_jobs=-1 # Utiliser tous les CPU
)
# Entraîner
grid_search.fit(X_train, y_train)
# Résultats
print(f"Meilleurs paramètres : {grid_search.best_params_}")
print(f"Meilleur score : {grid_search.best_score_:.4f}")
# Utiliser le meilleur modèle
best_model = grid_search.best_estimator_
y_pred = best_model.predict(X_test)
Quand utiliser RandomizedSearchCV ?
Si trop de paramètres, faire une recherche aléatoire au lieu d'exhaustive :
📝 Exemple Python
from sklearn.model_selection import RandomizedSearchCV
# Recherche aléatoire : teste seulement n_iter combinaisons
randomized_search = RandomizedSearchCV(
estimator=RandomForestClassifier(random_state=42),
param_distributions=param_grid,
n_iter=50, # Tester 50 combinaisons aléatoires seulement
cv=5,
scoring='accuracy',
n_jobs=-1,
random_state=42
)
randomized_search.fit(X_train, y_train)
| Approche |
Combinaisons |
Temps |
Avantages |
| GridSearchCV |
Toutes |
Lent (~10 min) |
Trouve l'optimum |
| RandomizedSearchCV |
50 aléatoires |
Rapide (~2 min) |
Généralement bon |
2.8 - Exercices Pratiques
Exercice 1 : Workflow Complet
Énoncé : Créez un dataset synthétique avec des défauts (valeurs manquantes, outliers). Nettoyez les données, entraînez un modèle LogisticRegression, et évaluez avec K-Fold CV.
Voir les indices
- Créer un DataFrame avec features et target
- Ajouter 10-15% de valeurs manquantes
- Utiliser SimpleImputer avec strategy='median'
- Détecter outliers avec IQR ou Isolation Forest
- Normaliser avec StandardScaler
- Utiliser StratifiedKFold pour l'évaluation
- Afficher accuracy moyen et écart-type
Exercice 2 : Feature Engineering
Énoncé : Prenez un dataset de clients. Créez au moins 5 nouvelles features :
- 1 feature temporelle (jours depuis inscription)
- 1 feature arithmétique (ratio, moyenne)
- 1 feature polynomiale (x²)
- 1 feature binaire (flag)
- 1 feature one-hot encoding
Comparez la performance avant/après feature engineering.
Voir les indices
Utilisez GridSearchCV pour trouver les meilleurs hyperparamètres avec et sans les nouvelles features. Comparez les meilleur scores.
Exercice 3 : GridSearchCV vs RandomizedSearchCV
Énoncé : Comparez le temps et les résultats entre GridSearchCV et RandomizedSearchCV sur le même dataset et modèle. Quelle approche choisir pour quel cas ?
Voir les indices
Utilisez import time et time.time() pour mesurer les temps. Visualisez les résultats avec matplotlib.
Résumé du Module 2
- Apprentissage supervisé : Données étiquetées, on apprend la relation input-output
- Apprentissage non-supervisé : Découvrir la structure cachée des données
- Scikit-Learn : Interface cohérente, 200+ algorithmes, bien documentée
- Workflow standard : Charger → Préparer → Diviser → Entraîner → Prédire → Évaluer
- Features vs Target : Distinction cruciale entre prédicteurs (X) et variable à prédire (y)
- Valeurs manquantes : SimpleImputer avec stratégies (mean, median, most_frequent)
- Outliers : Détection avec 3-Sigma, IQR, ou Isolation Forest
- Feature Engineering : Créer des features (temporelles, arithmétiques, polynomiales, binaires, one-hot)
- K-Fold CV : Évaluation robuste avec 100% des données au lieu de 20%
- GridSearchCV : Recherche exhaustive pour optimiser hyperparamètres
- RandomizedSearchCV : Recherche aléatoire rapide pour gros espaces de paramètres
- Normalisation : Adapter les scales pour meilleure convergence et performance
- ⚠️ Règle d'Or : fit() sur TRAIN, transform() sur TEST (même imputer/scaler)