Portail Étudiant

Plateforme de cours en ligne

Module 2 : Introduction au Machine Learning avec Scikit-Learn

ML-M2
Comprendre les fondamentaux du Machine Learning et maîtriser le workflow standard avec Scikit-Learn. Ce module vous permettra de passer de la théorie statistique à la construction de vos premiers modèles prédictifs performants.
⏱️ Durée : 8 heures 🎓 Niveau : Débutant-Intermédiaire 🐍 Langage : Python (Scikit-Learn)

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 ?

📝 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
  1. Créer un DataFrame avec features et target
  2. Ajouter 10-15% de valeurs manquantes
  3. Utiliser SimpleImputer avec strategy='median'
  4. Détecter outliers avec IQR ou Isolation Forest
  5. Normaliser avec StandardScaler
  6. Utiliser StratifiedKFold pour l'évaluation
  7. 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

Passez au Module 3 : Régression Linéaire →