# Exemple: Classification binaire
y_binary = [0, 1, 1, 0, 1, 0, 0, 1] # 0 = négatif, 1 = positifSéance 2: Apprentissage Supervisé - Classification
1. Introduction à la Classification
1.1 Définition
La classification est une tâche d’apprentissage supervisé où l’objectif est de prédire une classe ou catégorie discrète à partir de caractéristiques d’entrée.
Entrée: Caractéristiques d’un email (mots, expéditeur, longueur, etc.)
Sortie: Classe = “Spam” ou “Non Spam”
1.2 Différence Classification vs Régression
| Caractéristique | Classification | Régression |
|---|---|---|
| Sortie | Catégorie discrète | Valeur continue |
| Exemple | Spam/Non spam | Prix d’une maison |
| Métrique | Accuracy, F1-score | MAE, RMSE |
| Fonction | Probabilité → Classe | Valeur numérique |
2. Types de Classification
2.1 Classification Binaire
Deux classes possibles: 0 ou 1, Vrai ou Faux, Positif ou Négatif
Exemples:
- Détection de spam (spam/non spam)
- Diagnostic médical (malade/sain)
- Détection de fraude (fraude/légitime)
- Approbation de crédit (approuvé/rejeté)
2.2 Classification Multi-classes
Plus de deux classes mutuellement exclusives (une seule classe par instance)
Exemples:
- Reconnaissance de chiffres manuscrits (0-9 = 10 classes)
- Classification de fleurs Iris (Setosa, Versicolor, Virginica)
- Catégorisation d’articles (Sport, Politique, Économie, Culture)
# Exemple: Classification multi-classes
y_multiclass = [0, 1, 2, 1, 0, 2, 1] # 3 classes: 0, 1, 22.3 Classification Multi-label
Plusieurs classes simultanées possibles pour une instance
Exemples:
- Étiquetage de photos (peut contenir: personne, chien, extérieur)
- Catégorisation de films (peut être: Action, Comédie, Drame)
- Analyse de sentiments multiple (joie + surprise)
# Exemple: Classification multi-label
y_multilabel = [
[1, 0, 1], # instance a les labels 0 et 2
[0, 1, 1], # instance a les labels 1 et 2
[1, 1, 0] # instance a les labels 0 et 1
]3. Algorithmes de Classification
3.1 Arbre de Décision (Decision Tree)
Modèle qui prend des décisions basées sur des questions successives.
Principe
L’arbre divise l’espace des caractéristiques en régions par des questions binaires.
Diagramme :
graph TD
A[Age > 30?] -->|Oui| B[Revenu > 50k?]
A -->|Non| C[Étudiant?]
B -->|Oui| D[Approuvé ]
B -->|Non| E[Rejeté ]
C -->|Oui| F[Rejeté ]
C -->|Non| G[Approuvé ]
Avantages
- Facile à interpréter et visualiser
- Pas besoin de normalisation des données
- Gère les données non linéaires
- Gère les variables catégorielles et numériques
Inconvénients
- Tendance à l’overfitting
- Instable (petits changements de données → arbre différent)
- Biais vers les classes majoritaires
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
# Chargement des données
iris = load_iris()
X, y = iris.data, iris.target
# Split
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# Entraînement
clf = DecisionTreeClassifier(max_depth=3, random_state=42)
clf.fit(X_train, y_train)
# Prédiction
y_pred = clf.predict(X_test)
print(f"Accuracy: {clf.score(X_test, y_test):.2f}")3.2 Random Forest
Ensemble d’arbres de décision qui votent ensemble.
Principe
- Créer N arbres sur des sous-ensembles aléatoires de données
- Chaque arbre vote pour une classe
- Prédiction finale = vote majoritaire
Avantages
- Très performant et robuste
- Réduit l’overfitting par rapport à un arbre unique
- Gère bien les grandes dimensions
- Donne l’importance des features
Inconvénients
- Moins interprétable qu’un arbre unique
- Plus lent à entraîner et prédire
- Mémoire importante
from sklearn.ensemble import RandomForestClassifier
# Entraînement
rf = RandomForestClassifier(n_estimators=100, max_depth=3, random_state=42)
rf.fit(X_train, y_train)
# Prédiction
y_pred = rf.predict(X_test)
print(f"Accuracy: {rf.score(X_test, y_test):.2f}")
# Importance des features
importances = rf.feature_importances_
for i, imp in enumerate(importances):
print(f"Feature {iris.feature_names[i]}: {imp:.3f}")3.3 Support Vector Machine (SVM)
Trouve l’hyperplan optimal qui sépare les classes avec la marge maximale.
Principe
- Marge: distance entre l’hyperplan et les points les plus proches (vecteurs de support)
- Objectif: Maximiser cette marge
- Kernel trick: Permet de gérer des données non linéairement séparables
from sklearn.svm import SVC
# SVM linéaire
svm_linear = SVC(kernel='linear', C=1.0)
svm_linear.fit(X_train, y_train)
# SVM avec kernel RBF (pour données non linéaires)
svm_rbf = SVC(kernel='rbf', C=1.0, gamma='scale')
svm_rbf.fit(X_train, y_train)
print(f"SVM Linear Accuracy: {svm_linear.score(X_test, y_test):.2f}")
print(f"SVM RBF Accuracy: {svm_rbf.score(X_test, y_test):.2f}")Avantages
- Très efficace en haute dimension
- Robuste aux outliers
- Versatile (différents kernels)
Inconvénients
- Lent sur de grandes données
- Difficile à interpréter
- Sensible au choix des hyperparamètres
3.4 Naïve Bayes
Basé sur le théorème de Bayes avec hypothèse d’indépendance des features.
Principe - Théorème de Bayes
\[P(y|X) = \frac{P(X|y) \cdot P(y)}{P(X)}\]
Où:
- \(P(y|X)\) = probabilité de la classe \(y\) sachant les features \(X\) (posterior)
- \(P(X|y)\) = vraisemblance
- \(P(y)\) = probabilité a priori de la classe
- \(P(X)\) = évidence (constante)
Hypothèse “Naïve”
Les features sont indépendantes conditionnellement à la classe:
\[P(X|y) = P(x_1|y) \cdot P(x_2|y) \cdot ... \cdot P(x_n|y)\]
from sklearn.naive_bayes import GaussianNB, MultinomialNB
# Gaussian Naive Bayes (pour features continues)
gnb = GaussianNB()
gnb.fit(X_train, y_train)
print(f"Gaussian NB Accuracy: {gnb.score(X_test, y_test):.2f}")
# Multinomial NB (pour comptages, ex: mots dans un texte)
# mnb = MultinomialNB()
# mnb.fit(X_train_counts, y_train)Avantages
- Très rapide (entraînement et prédiction)
- Fonctionne bien avec peu de données
- Excellent pour la classification de texte
Inconvénients
- Hypothèse d’indépendance rarement vraie
- Performance limitée si hypothèse violée
3.5 Régression Logistique
Attention: Malgré son nom, c’est un algorithme de classification !
Principe
Modèle linéaire qui utilise la fonction sigmoïde pour produire des probabilités.
Fonction sigmoïde: \[\sigma(z) = \frac{1}{1 + e^{-z}}\]
Modèle: \[P(y=1|X) = \sigma(w^T X + b) = \frac{1}{1 + e^{-(w^T X + b)}}\]
Interprétation Probabiliste
- Sortie \(\in [0, 1]\) : probabilité d’appartenance à la classe positive
- Si \(P(y=1|X) \geq 0.5\) → prédiction = classe 1
- Si \(P(y=1|X) < 0.5\) → prédiction = classe 0
from sklearn.linear_model import LogisticRegression
# Entraînement
log_reg = LogisticRegression(max_iter=1000)
log_reg.fit(X_train, y_train)
# Prédiction de classes
y_pred = log_reg.predict(X_test)
# Prédiction de probabilités
y_proba = log_reg.predict_proba(X_test)
print(f"Accuracy: {log_reg.score(X_test, y_test):.2f}")
print(f"\nPremière prédiction:")
print(f" Probabilités: {y_proba[0]}")
print(f" Classe prédite: {y_pred[0]}")Avantages
- Simple et interprétable
- Donne des probabilités (utile pour la prise de décision)
- Peu de paramètres à ajuster
- Fonctionne bien sur données linéairement séparables
Inconvénients
- Assume une relation linéaire
- Sensible aux outliers
- Nécessite feature engineering pour les relations non linéaires
3.6 k-Nearest Neighbors (k-NN)
Classification basée sur la proximité avec les voisins.
Principe
- Calculer la distance entre le nouveau point et tous les points d’entraînement
- Sélectionner les k points les plus proches
- Vote majoritaire parmi ces k voisins
from sklearn.neighbors import KNeighborsClassifier
# k=5 voisins
knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(X_train, y_train)
print(f"k-NN Accuracy: {knn.score(X_test, y_test):.2f}")Avantages
- Simple et intuitif
- Pas d’entraînement (lazy learning)
- Fonctionne bien pour des frontières complexes
Inconvénients
- Lent pour la prédiction (calcule toutes les distances)
- Sensible à l’échelle des features (nécessite normalisation)
- Curse of dimensionality (mauvais en haute dimension)
4. Critères d’Évaluation (Aperçu)
4.1 Métriques Principales
- Accuracy: Proportion de prédictions correctes
- Precision: Proportion de vrais positifs parmi les prédictions positives
- Recall: Proportion de vrais positifs parmi les cas réellement positifs
- F1-Score: Moyenne harmonique de Precision et Recall
Ces métriques seront détaillées en profondeur dans la Séance 5 - TD2
4.2 Exemple Simple
from sklearn.metrics import accuracy_score, classification_report
# Calcul de l'accuracy
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy:.2f}")
# Rapport complet
print("\nClassification Report:")
print(classification_report(y_test, y_pred, target_names=iris.target_names))5. Exemple Complet: Comparaison d’Algorithmes
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
# Création d'un dataset synthétique
X, y = make_classification(
n_samples=1000,
n_features=2,
n_redundant=0,
n_clusters_per_class=1,
random_state=42
)
# Split et normalisation
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# Entraînement de plusieurs modèles
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC
from sklearn.linear_model import LogisticRegression
from sklearn.naive_bayes import GaussianNB
from sklearn.neighbors import KNeighborsClassifier
models = {
'Decision Tree': DecisionTreeClassifier(max_depth=5, random_state=42),
'Random Forest': RandomForestClassifier(n_estimators=100, random_state=42),
'SVM': SVC(kernel='rbf', random_state=42),
'Logistic Regression': LogisticRegression(max_iter=1000),
'Naive Bayes': GaussianNB(),
'k-NN': KNeighborsClassifier(n_neighbors=5)
}
# Comparaison des performances
results = {}
for name, model in models.items():
model.fit(X_train_scaled, y_train)
score = model.score(X_test_scaled, y_test)
results[name] = score
print(f"{name:20s}: {score:.4f}")
# Visualisation
plt.figure(figsize=(10, 6))
plt.barh(list(results.keys()), list(results.values()))
plt.xlabel('Accuracy')
plt.title('Comparaison des Algorithmes de Classification')
plt.xlim([0, 1])
plt.grid(axis='x', alpha=0.3)
plt.tight_layout()
plt.show()Résumé de la Séance
Exercices
Code d’implémentation :
from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
# Chargement et entraînement
iris = load_iris()
X, y = iris.data, iris.target
log_reg = LogisticRegression(max_iter=1000)
log_reg.fit(X, y)
# Analyse des coefficients
print(f"Coefficients (W): \n{log_reg.coef_}")
print(f"Intercept (b): {log_reg.intercept_}")Explication des coefficients :
- Signification : Chaque coefficient représente l’importance d’une caractéristique (feature) pour prédire une classe donnée.
- Direction : Un coefficient positif augmente la probabilité que l’instance appartienne à la classe, tandis qu’un coefficient négatif la diminue.
- Ampleur : Plus la valeur absolue du coefficient est élevée, plus la caractéristique a un impact déterminant sur la décision du modèle.
Comparaison théorique et pratique :
- Performance : Le Random Forest obtient généralement une meilleure précision (accuracy) que l’arbre seul car il combine les prédictions de nombreux arbres, réduisant ainsi les erreurs aléatoires.
- Stabilité : Un Decision Tree est très sensible aux petites variations des données (variance élevée). Le Random Forest stabilise cela par échantillonnage (bagging).
- Sur-apprentissage (Overfitting) : L’arbre de décision a tendance à mémoriser le bruit des données s’il n’est pas limité en profondeur. Le Random Forest limite ce risque en moyennant les résultats de plusieurs arbres entraînés sur des sous-ensembles différents.
Pour la détection de fraude, je recommanderais le Random Forest ou le XGBoost (méthodes d’ensemble), pour les raisons suivantes :
- Interprétabilité : Bien que moins direct qu’un arbre unique, le Random Forest permet d’extraire l’importance des variables, ce qui est crucial pour comprendre quels facteurs (montant, lieu, heure) déclenchent une alerte de fraude.
- Déséquilibre des classes : La fraude est rare (classe minoritaire). Ces algorithmes gèrent mieux les données déséquilibrées grâce à des techniques de pondération des classes.
- Temps réel : Une fois entraîné, la prédiction d’un Random Forest est très rapide, permettant de valider ou bloquer une transaction en quelques millisecondes.
- Robustesse : Ces modèles sont moins sensibles aux valeurs aberrantes (outliers) souvent présentes dans les données financières.
Lectures Complémentaires
- Géron, A. (2019) - Chapitre 3: Classification
- Scikit-learn Documentation: Supervised Learning
- StatQuest: Logistic Regression