import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import time
# Données et pré-traitement
from sklearn.datasets import fetch_covtype
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
import umap.umap_ as umap
# Modèle et métriques
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report
from sklearn.pipeline import Pipeline
# Configuration
sns.set_theme(style="whitegrid")
plt.rcParams['figure.figsize'] = (12, 7)
# 1. Charger les données
# On prend un sous-échantillon stratifié pour que l'atelier soit rapide
X, y = fetch_covtype(return_X_y=True)
X_sample, _, y_sample, _ = train_test_split(X, y, train_size=20000, random_state=42, stratify=y)
# 2. Diviser les données
X_train, X_test, y_train, y_test = train_test_split(X_sample, y_sample, test_size=0.2, random_state=42, stratify=y)
print(f"Données prêtes. Dimensions de X_train: {X_train.shape}")
1 Introduction : Le Moment de Vérité
Au cours de cette série, nous avons exploré un arsenal de techniques pour réduire la dimensionnalité de nos données. Nous avons compris pourquoi c’est nécessaire (la malédiction de la dimensionnalité) et nous avons appris le comment avec des outils comme le PCA, le LDA, et les méthodes de visualisation non-linéaire.
Il est maintenant temps de mettre tout cela en pratique dans un projet de synthèse. L’objectif est de répondre à la question la plus importante pour un data scientist : concrètement, quel est l’impact de la réduction de dimensionnalité sur la performance et l’efficacité d’un modèle de Machine Learning ?
Nous allons suivre un workflow complet pour voir si, en simplifiant nos données, nous pouvons obtenir un modèle plus rapide, tout en maintenant (ou même en améliorant !) sa performance prédictive.
2 Le Défi : Classifier la Couverture Forestière
Pour ce projet, nous allons utiliser une version du jeu de données Covertype de l’UCI, qui consiste à prédire le type de couverture forestière (ex: “Épicéa”, “Pin Ponderosa”) à partir de données cartographiques.
- Objectif : Classifier le type de forêt (7 classes possibles).
- Données : 54 variables quantitatives (altitude, pente, distance à l’eau, etc.).
- Pourquoi ce jeu de données ? Avec 54 dimensions, il est un candidat parfait pour la réduction de dimensionnalité. Il est trop complexe pour être visualisé directement et l’entraînement d’un modèle peut être coûteux.
3 Le Plan de Match
Notre expérience se déroulera en quatre étapes : 1. Modèle de Référence : Entraîner un classifieur performant (Forêt Aléatoire) sur les 54 variables originales et mesurer sa performance et son temps d’entraînement. 2. Réduction avec PCA : Appliquer le PCA pour réduire le nombre de dimensions tout en conservant 95% de la variance expliquée. 3. Modèle sur Données Réduites : Entraîner le même classifieur sur les nouvelles composantes principales et mesurer sa performance et son temps d’entraînement. 4. Analyse et Visualisation : Comparer les résultats et utiliser UMAP pour visualiser la structure des données.
4 Préparation de l’Environnement
5 L’Atelier Pratique
5.1 Étape 1 : Le Modèle de Référence (sur Données Originales)
# Le pipeline met à l'échelle puis entraîne le classifieur
pipeline_baseline = Pipeline([
('scaler', StandardScaler()),
('classifier', RandomForestClassifier(n_estimators=100, random_state=42, n_jobs=-1))
])
print("--- Entraînement du modèle de référence sur 54 variables ---")
start_time = time.time()
pipeline_baseline.fit(X_train, y_train)
end_time = time.time()
# Évaluation
y_pred_baseline = pipeline_baseline.predict(X_test)
accuracy_baseline = accuracy_score(y_test, y_pred_baseline)
time_baseline = end_time - start_time
print(f"Temps d'entraînement: {time_baseline:.2f} secondes")
print(f"Accuracy sur le test: {accuracy_baseline:.4f}")5.2 Étape 2 & 3 : Le Modèle sur Données Réduites (avec PCA)
Nous allons maintenant créer un pipeline qui intègre le PCA.
# Le pipeline met à l'échelle, réduit la dimension, puis entraîne le classifieur
pipeline_pca = Pipeline([
('scaler', StandardScaler()),
('pca', PCA(n_components=0.95)), # Garder 95% de la variance
('classifier', RandomForestClassifier(n_estimators=100, random_state=42, n_jobs=-1))
])
print("\n--- Entraînement du modèle sur données réduites par PCA ---")
start_time_pca = time.time()
pipeline_pca.fit(X_train, y_train)
end_time_pca = time.time()
# Évaluation
y_pred_pca = pipeline_pca.predict(X_test)
accuracy_pca = accuracy_score(y_test, y_pred_pca)
time_pca = end_time_pca - start_time_pca
# Nombre de dimensions conservées par le PCA
n_components = pipeline_pca.named_steps['pca'].n_components_
print(f"Le PCA a conservé {n_components} composantes (au lieu de 54).")
print(f"Temps d'entraînement: {time_pca:.2f} secondes")
print(f"Accuracy sur le test: {accuracy_pca:.4f}")5.3 Étape 4 : Analyse des Résultats et Visualisation
Comparons nos deux approches.
# Création d'un DataFrame pour la comparaison
results = pd.DataFrame({
'Modèle': ['Référence (54 var.)', f'Avec PCA ({n_components} comp.)'],
'Accuracy': [accuracy_baseline, accuracy_pca],
'Temps Entraînement (s)': [time_baseline, time_pca]
})
print("\n--- Tableau Comparatif des Performances ---")
print(results)
# Bonus : Visualisation avec UMAP
print("\n--- Visualisation des données avec UMAP (2D) ---")
# On applique le scaler puis UMAP sur un sous-ensemble pour la rapidité
X_scaled_sample = StandardScaler().fit_transform(X_train[:5000])
reducer = umap.UMAP(n_neighbors=50, min_dist=0.1, random_state=42)
X_umap = reducer.fit_transform(X_scaled_sample)
plt.figure(figsize=(14, 10))
sns.scatterplot(x=X_umap[:, 0], y=X_umap[:, 1], hue=y_train[:5000], palette='Spectral', s=20)
plt.title("Visualisation UMAP des Types de Forêts (2D)")
plt.legend(title='Type de Forêt', bbox_to_anchor=(1.05, 1), loc=2)
plt.show()- Performance : La réduction de dimensionnalité avec PCA a entraîné une légère baisse de la performance (accuracy). C’est un compromis attendu : en compressant l’information, nous avons perdu quelques détails qui aidaient le modèle.
- Efficacité : Le gain en temps d’entraînement est significatif. Sur des jeux de données beaucoup plus grands, cette différence peut passer de quelques secondes à plusieurs heures !
- Visualisation : Le graphique UMAP est remarquable. Même en écrasant 54 dimensions en seulement 2, il a réussi à créer une “carte” où les différentes classes de forêts forment des groupes assez distincts. Cela confirme qu’il y a bien une structure séparable dans les données.
6 Conclusion de la Série
Ce projet de synthèse illustre parfaitement le rôle de la réduction de dimensionnalité dans le monde réel. Ce n’est pas une solution miracle, mais un outil de compromis.
- PCA est votre meilleur allié pour le pré-traitement lorsque vous voulez accélérer vos modèles ou combattre la multicolinéarité, en acceptant une potentielle petite perte de performance.
- t-SNE et UMAP sont des outils inégalés pour l’exploration visuelle, vous permettant de “voir” la structure de données autrement impénétrables.
Vous avez maintenant terminé ce voyage à travers l’art de la réduction de dimensionnalité. Vous êtes équipé pour aborder des données complexes, les simplifier de manière intelligente, et en extraire des connaissances et des modèles performants.