Recherche par Grille pour le Réglage des Hyperparamètres en Python
Apprenez à utiliser GridSearchCV et RandomizedSearchCV en Python pour régler les hyperparamètres de modèles ML avec des exemples scikit-learn.
Le réglage des hyperparamètres est le processus qui consiste à trouver les valeurs de configuration d'un modèle d'apprentissage automatique qui ne sont pas apprises à partir des données — des éléments tels que la profondeur d'un arbre de décision, la force de régularisation d'une régression logistique, ou le nombre de neurones dans un réseau de neurones. La recherche par grille est l'approche la plus directe : définir un ensemble discret de valeurs pour chaque hyperparamètre, tester toutes les combinaisons et conserver la meilleure.
Cette page couvre :
- Ce que sont les hyperparamètres et pourquoi ils sont importants
- Comment
GridSearchCVexplore exhaustivement une grille de paramètres - Comment lire
cv_results_et comprendre ce qui a été testé - L'utilisation de
n_jobs=-1pour paralléliser la recherche RandomizedSearchCVcomme alternative plus rapide pour les grandes grilles- La combinaison de la recherche par grille avec un
Pipelinepour éviter les fuites de données - Quand utiliser la recherche par grille plutôt que des alternatives plus rapides
Tous les exemples utilisent les jeux de données intégrés de scikit-learn, vous pouvez donc les exécuter immédiatement.
Que sont les Hyperparamètres ?
Chaque modèle d'apprentissage automatique possède deux types de paramètres :
- Les paramètres du modèle sont appris automatiquement pendant l'entraînement (par exemple, les poids dans un réseau de neurones, les seuils de division dans un arbre de décision).
- Les hyperparamètres sont définis par vous avant le début de l'entraînement. Ils contrôlent le processus d'apprentissage lui-même.
Choisir de mauvais hyperparamètres peut laisser un modèle capable bien en dessous de ses performances potentielles. Par exemple, un arbre de décision sans limite de profondeur va sur-apprendre les données d'entraînement ; un arbre avec une limite de profondeur de 1 va sous-apprendre. La limite correcte dépend de vos données, et la recherche par grille la trouve de manière systématique plutôt que par essais-erreurs.
Comment fonctionne GridSearchCV
GridSearchCV de scikit-learn combine deux idées :
- Énumération de la grille — il génère toutes les combinaisons de valeurs d'hyperparamètres que vous spécifiez.
- Validation croisée — pour chaque combinaison, il effectue une validation croisée k-fold (voir Validation Croisée en Python) et enregistre le score moyen.
Après la recherche, GridSearchCV stocke la meilleure combinaison et ré-entraîne automatiquement un modèle avec ces paramètres sur l'ensemble d'entraînement complet.
Le nombre d'ajustements est (combinaisons) × (plis de validation croisée). Une grille avec 3 × 3 × 3 = 27 combinaisons et cv=5 effectue 135 ajustements — gérable pour les modèles rapides, coûteux pour les modèles lents.
Exemple de Base avec GridSearchCV
L'exemple ci-dessous règle un Classifieur par Arbre de Décision sur le jeu de données Iris.
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.datasets import load_iris
X, y = load_iris(return_X_y=True)
# Model with no hyperparameters set yet
model = DecisionTreeClassifier(random_state=42)
# Define the grid of values to try
param_grid = {
'max_depth': [2, 3, 5, None],
'min_samples_split': [2, 5, 10],
'criterion': ['gini', 'entropy'],
}
# cv=5 means 5-fold cross-validation for each combination
grid_search = GridSearchCV(
estimator=model,
param_grid=param_grid,
cv=5,
scoring='accuracy',
n_jobs=-1, # use all CPU cores
verbose=0,
)
grid_search.fit(X, y)
print("Best parameters:", grid_search.best_params_)
print("Best CV accuracy: {:.3f}".format(grid_search.best_score_))Ce que fait chaque argument :
| Argument | Rôle |
|---|---|
estimator | Le modèle à régler. Tout estimateur scikit-learn fonctionne. |
param_grid | Dict associant les noms de paramètres à des listes de valeurs candidates. |
cv | Nombre de plis dans la validation croisée (5 est une valeur par défaut courante). |
scoring | Métrique à optimiser. Par défaut, la méthode .score() de l'estimateur. |
n_jobs | Nombre de tâches parallèles. -1 utilise tous les cœurs CPU disponibles. |
Sortie typique :
Best parameters: {'criterion': 'gini', 'max_depth': 3, 'min_samples_split': 2}
Best CV accuracy: 0.967Lecture de cv_results_
Après l'ajustement, grid_search.cv_results_ est un dictionnaire de tableaux — une entrée par combinaison testée. Les clés les plus utiles sont :
import pandas as pd
results = pd.DataFrame(grid_search.cv_results_)
# Show top 5 combinations by mean test score
cols = ['param_max_depth', 'param_min_samples_split', 'param_criterion',
'mean_test_score', 'std_test_score', 'rank_test_score']
print(results[cols].sort_values('rank_test_score').head(5).to_string(index=False))Colonnes clés :
mean_test_score— le score CV moyen sur tous les plis pour cette combinaison.std_test_score— l'écart-type ; une valeur élevée signifie que le score est instable selon les plis.rank_test_score— le rang 1 est le gagnant.
Options de Scoring
Par défaut, GridSearchCV optimise la métrique par défaut de l'estimateur. Vous pouvez spécifier n'importe quel scorer intégré ou personnalisé :
# Common scoring strings
scoring_options = [
'accuracy', # classification
'f1_weighted', # F1 for multi-class
'roc_auc', # binary classification
'neg_mean_squared_error', # regression (note: negative so higher = better)
'r2', # regression
]
# Evaluate multiple metrics at once (refit on the one you care most about)
grid_search = GridSearchCV(
estimator=DecisionTreeClassifier(random_state=42),
param_grid={'max_depth': [2, 3, 5]},
cv=5,
scoring={'acc': 'accuracy', 'f1': 'f1_weighted'},
refit='acc', # use accuracy to pick the best model
n_jobs=-1,
)Utiliser un Pipeline pour Éviter les Fuites de Données
Lorsque votre prétraitement dépend des données d'entraînement (mise à l'échelle, imputation, sélection de caractéristiques), vous devez ajuster le préprocesseur uniquement sur les plis d'entraînement — jamais sur l'ensemble de données complet avant la division. Un Pipeline gère cela automatiquement et fonctionne parfaitement avec GridSearchCV.
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import GridSearchCV
X, y = load_breast_cancer(return_X_y=True)
# Build a pipeline: scale then classify
pipe = Pipeline([
('scaler', StandardScaler()),
('svc', SVC()),
])
# Reference pipeline steps with double-underscore: step__param
param_grid = {
'svc__C': [0.1, 1, 10],
'svc__kernel': ['linear', 'rbf'],
'svc__gamma': ['scale', 'auto'],
}
grid_search = GridSearchCV(pipe, param_grid, cv=5, scoring='accuracy', n_jobs=-1)
grid_search.fit(X, y)
print("Best params:", grid_search.best_params_)
print("Best CV accuracy: {:.3f}".format(grid_search.best_score_))La syntaxe avec double tiret bas (svc__C) est la clé : elle indique à scikit-learn de passer C à l'étape svc à l'intérieur du pipeline. Sans pipeline, mettre à l'échelle l'ensemble de données complet avant la validation croisée ferait fuir des informations du pli de test dans le scaler, donnant un score trop optimiste.
RandomizedSearchCV : Plus Rapide pour les Grandes Grilles
La recherche par grille exhaustive devient impraticable lorsque chaque hyperparamètre a de nombreuses valeurs candidates. RandomizedSearchCV échantillonne un nombre fixe de combinaisons aléatoires au lieu de toutes les tester :
from sklearn.model_selection import RandomizedSearchCV
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris
from scipy.stats import randint
X, y = load_iris(return_X_y=True)
# Use distributions instead of discrete lists
param_dist = {
'n_estimators': randint(50, 500), # random integer in [50, 500)
'max_depth': [3, 5, 10, None],
'min_samples_split': randint(2, 20),
'max_features': ['sqrt', 'log2'],
}
rand_search = RandomizedSearchCV(
estimator=RandomForestClassifier(random_state=42),
param_distributions=param_dist,
n_iter=30, # try 30 random combinations instead of all
cv=5,
scoring='accuracy',
n_jobs=-1,
random_state=42,
)
rand_search.fit(X, y)
print("Best params:", rand_search.best_params_)
print("Best CV accuracy: {:.3f}".format(rand_search.best_score_))GridSearchCV vs RandomizedSearchCV :
GridSearchCV | RandomizedSearchCV | |
|---|---|---|
| Stratégie de recherche | Exhaustive (toutes les combinaisons) | Échantillonnage aléatoire |
| Reproductibilité | Entièrement déterministe | Définir random_state |
| Idéal pour | Grilles petites et bien définies | Grands espaces de recherche |
| Distributions continues | Non pris en charge | Pris en charge via scipy.stats |
| Garantit de trouver le meilleur | Oui (dans la grille) | Non, mais souvent proche |
Pour les grandes grilles, RandomizedSearchCV avec n_iter=50–100 trouve fréquemment une solution quasi-optimale en une fraction du temps de calcul.
Faire des Prédictions avec le Meilleur Modèle
Après l'ajustement, GridSearchCV se comporte comme un estimateur classique. Son attribut best_estimator_ contient le modèle ré-entraîné :
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.datasets import load_iris
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
param_grid = {'max_depth': [2, 3, 5], 'criterion': ['gini', 'entropy']}
grid_search = GridSearchCV(
DecisionTreeClassifier(random_state=42),
param_grid, cv=5, n_jobs=-1
)
grid_search.fit(X_train, y_train)
# Evaluate on the held-out test set
test_score = grid_search.score(X_test, y_test)
print("Test accuracy: {:.3f}".format(test_score))
# Access the best model directly
best_model = grid_search.best_estimator_
predictions = best_model.predict(X_test[:5])
print("Predictions for first 5 test samples:", predictions)Important : conservez toujours un ensemble de test distinct mis de côté qui n'est jamais consulté pendant la recherche par grille. Le score de validation croisée à l'intérieur de GridSearchCV estime la généralisation, mais l'évaluation finale réelle doit porter sur des données que la recherche n'a jamais touchées.
Quand Utiliser la Recherche par Grille
La recherche par grille est un choix solide par défaut lorsque :
- Vous avez un modèle de taille petite à moyenne qui s'entraîne rapidement (quelques secondes à quelques minutes par ajustement).
- Vous savez approximativement quels hyperparamètres comptent le plus et vous disposez d'un ensemble raisonnable de valeurs candidates.
- La reproductibilité et l'exhaustivité sont importantes.
Envisagez des alternatives lorsque :
- La grille est grande (de nombreux paramètres avec de nombreuses valeurs) — utilisez d'abord
RandomizedSearchCVpour réduire l'espace, puis affinez avecGridSearchCV. - L'entraînement est coûteux (apprentissage profond, grands ensembles) — les bibliothèques d'optimisation bayésienne comme
scikit-optimizeouOptunafont des choix plus intelligents que l'échantillonnage aléatoire. - Vous souhaitez un arrêt automatique — les stratégies de réduction (
HalvingGridSearchCV) éliminent rapidement les candidats peu performants et nécessitent moins d'ajustements au total.
Conseils Pratiques
- Commencez grossièrement. Utilisez une petite grille avec des valeurs réparties sur des ordres de grandeur (par exemple,
C: [0.01, 0.1, 1, 10, 100]). Une fois que vous avez trouvé une région prometteuse, affinez avec une grille plus fine. - Surveillez les écarts-types. Si
std_test_scoreest grand, le modèle est sensible à la division particulière des données. Envisagez d'augmentercvou de collecter davantage de données. - Définissez
n_jobs=-1pour utiliser tous les cœurs CPU — cela ne coûte rien et offre souvent une accélération de 4 à 8× sur une machine moderne. - Associez à un Pipeline. Enveloppez toujours le prétraitement et le modèle ensemble dans un
Pipelineavant de les passer àGridSearchCV. C'est la pratique la plus importante pour obtenir des scores fiables. - Utilisez des plis stratifiés pour la classification.
GridSearchCVutilise automatiquementStratifiedKFoldpour les classifieurs, ce qui préserve les proportions de classes entre les plis.
Sujets Connexes
- Validation Croisée en Python — comprendre l'évaluation k-fold qui alimente
GridSearchCV - Classifieur par Arbre de Décision — un modèle courant à régler avec la recherche par grille
- Régression Logistique — un autre modèle rapide bien adapté à la recherche par grille
- K-Nearest Neighbors —
n_neighborsetmetricsont des cibles classiques pour la recherche par grille - Régression Linéaire — réglage des hyperparamètres pour les variantes de régression régularisée