Introduction
Ce laboratoire montre comment effectuer un réglage d'hyperparamètres avec validation croisée à l'aide de la bibliothèque scikit-learn. L'objectif est de classifier des images de chiffres manuscrits en utilisant une classification binaire pour faciliter la compréhension : identifier si un chiffre est un 8 ou non. L'ensemble de données utilisé est l'ensemble de données digits. Les performances des hyperparamètres sélectionnés et du modèle entraîné sont ensuite mesurées sur un ensemble d'évaluation dédié qui n'a pas été utilisé lors de l'étape de sélection du modèle.
Conseils sur la machine virtuelle
Une fois le démarrage de la machine virtuelle terminé, cliquez dans le coin supérieur gauche pour basculer vers l'onglet Notebook pour accéder à Jupyter Notebook pour la pratique.
Parfois, vous devrez peut-être attendre quelques secondes pour que Jupyter Notebook ait fini de charger. La validation des opérations ne peut pas être automatisée en raison des limitations de Jupyter Notebook.
Si vous rencontrez des problèmes pendant l'apprentissage, n'hésitez pas à demander à Labby. Donnez votre feedback après la session, et nous résoudrons rapidement le problème pour vous.
Charger les données
Nous allons charger l'ensemble de données digits et aplatir les images en vecteurs. Chaque image de 8 pixels sur 8 doit être transformée en un vecteur de 64 pixels. Ainsi, nous obtiendrons un tableau de données final de forme (n_images, n_pixels). Nous allons également diviser les données en un ensemble d'entraînement et un ensemble de test de taille égale.
from sklearn import datasets
from sklearn.model_selection import train_test_split
digits = datasets.load_digits()
n_samples = len(digits.images)
X = digits.images.reshape((n_samples, -1))
y = digits.target == 8
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=0)
Définir une stratégie de recherche sur grille
Nous allons définir une fonction à passer au paramètre refit de l'instance GridSearchCV. Elle implémentera la stratégie personnalisée pour sélectionner le meilleur candidat à partir de l'attribut cv_results_ de GridSearchCV. Une fois le candidat sélectionné, il est automatiquement réajusté par l'instance GridSearchCV.
Ici, la stratégie est de sélectionner les modèles qui sont les meilleurs en termes de précision et de rappel. Parmi les modèles sélectionnés, nous sélectionnons finalement le modèle le plus rapide à prédire. Remarquez que ces choix personnalisés sont entièrement arbitraires.
import pandas as pd
from sklearn.metrics import classification_report
def print_dataframe(filtered_cv_results):
"""Affiche joliment un DataFrame filtré"""
for mean_precision, std_precision, mean_recall, std_recall, params in zip(
filtered_cv_results["mean_test_precision"],
filtered_cv_results["std_test_precision"],
filtered_cv_results["mean_test_recall"],
filtered_cv_results["std_test_recall"],
filtered_cv_results["params"],
):
print(
f"précision: {mean_precision:0.3f} (±{std_precision:0.03f}),"
f" rappel: {mean_recall:0.3f} (±{std_recall:0.03f}),"
f" pour {params}"
)
print()
def refit_strategy(cv_results):
"""Définit la stratégie pour sélectionner le meilleur estimateur.
La stratégie définie ici est de filtrer tous les résultats inférieurs à un seuil de précision
de 0,98, de classer les résultats restants par rappel et de conserver tous les modèles
avec une écart-type de l'ordre du meilleur modèle en termes de rappel. Une fois ces modèles
sélectionnés, nous pouvons sélectionner le modèle le plus rapide à prédire.
Paramètres
----------
cv_results : dict de tableaux ndarray (masqués) de numpy
Résultats de la validation croisée renvoyés par `GridSearchCV`.
Retours
-------
best_index : int
L'index du meilleur estimateur tel qu'il apparaît dans `cv_results`.
"""
## Affiche les informations sur la recherche sur grille pour les différents scores
precision_threshold = 0,98
cv_results_ = pd.DataFrame(cv_results)
print("Tous les résultats de la recherche sur grille :")
print_dataframe(cv_results_)
## Filtre tous les résultats inférieurs au seuil
high_precision_cv_results = cv_results_[
cv_results_["mean_test_precision"] > precision_threshold
]
print(f"Modèles avec une précision supérieure à {precision_threshold} :")
print_dataframe(high_precision_cv_results)
high_precision_cv_results = high_precision_cv_results[
[
"mean_score_time",
"mean_test_recall",
"std_test_recall",
"mean_test_precision",
"std_test_precision",
"rank_test_recall",
"rank_test_precision",
"params",
]
]
## Sélectionne les modèles les plus performants en termes de rappel
## (à l'intérieur d'un écart-type du meilleur)
best_recall_std = high_precision_cv_results["mean_test_recall"].std()
best_recall = high_precision_cv_results["mean_test_recall"].max()
best_recall_threshold = best_recall - best_recall_std
high_recall_cv_results = high_precision_cv_results[
high_precision_cv_results["mean_test_recall"] > best_recall_threshold
]
print(
"Parmi les modèles à haute précision précédemment sélectionnés, nous conservons tous les\n"
"modèles à l'intérieur d'un écart-type du modèle à rappel le plus élevé : "
)
print_dataframe(high_recall_cv_results)
## Parmi les meilleurs candidats, sélectionne le modèle le plus rapide à prédire
fastest_top_recall_high_precision_index = high_recall_cv_results[
"mean_score_time"
].idxmin()
print(
"\nLe modèle final sélectionné est le plus rapide à prédire parmi les précédemment\n"
"sélectionnés dans le sous-ensemble de meilleurs modèles basé sur la précision et le rappel.\n"
"Son temps de scoring est :\n\n"
f"{high_recall_cv_results.loc[fastest_top_recall_high_precision_index]}"
)
return fastest_top_recall_high_precision_index
Définir les hyperparamètres
Nous allons définir les hyperparamètres et créer l'instance GridSearchCV.
from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC
tuned_parameters = [
{"kernel": ["rbf"], "gamma": [1e-3, 1e-4], "C": [1, 10, 100, 1000]},
{"kernel": ["linear"], "C": [1, 10, 100, 1000]},
]
grid_search = GridSearchCV(
SVC(), tuned_parameters, scoring=["precision", "recall"], refit=refit_strategy
)
Ajuster le modèle et effectuer des prédictions
Nous allons ajuster le modèle et effectuer des prédictions sur l'ensemble d'évaluation.
grid_search.fit(X_train, y_train)
## Les paramètres sélectionnés par la recherche sur grille avec notre stratégie personnalisée sont :
grid_search.best_params_
## Enfin, nous évaluons le modèle affiné sur l'ensemble d'évaluation non utilisé : l'objet
## `grid_search` **a été automatiquement réajusté** sur l'ensemble d'entraînement
## complet avec les paramètres sélectionnés par notre stratégie de réajustement personnalisée.
y_pred = grid_search.predict(X_test)
print(classification_report(y_test, y_pred))
Sommaire
Dans ce laboratoire, nous avons appris à effectuer un réglage d'hyperparamètres avec validation croisée à l'aide de la bibliothèque scikit - learn. Nous avons utilisé l'ensemble de données digits et défini une stratégie de réajustement personnalisée pour sélectionner le meilleur candidat à partir de l'attribut cv_results_ de l'instance GridSearchCV. Enfin, nous avons évalué le modèle affiné sur l'ensemble d'évaluation non utilisé.