Améliorez Votre Précision de Modélisation en 15 Minutes avec NVIDIA cuML et l'Optimisation des Hyperparamètres
Stacking Generalization avec HPO : Maximiser la Précision en 15 Minutes grâce à NVIDIA cuML La combinaison de multiples modèles, connue sous le nom de stacking generalization, est une technique largement utilisée dans le domaine de l'apprentissage automatique (Machine Learning, ML) pour améliorer les performances prédictives. Parallèlement, l'optimisation des hyperparamètres (Hyperparameter Optimization, HPO) consiste à rechercher systématiquement le meilleur ensemble d'hyperparamètres pour maximiser les performances d'un algorithme ML donné. Cependant, le principal défi de l'utilisation de ces deux techniques réside dans leur importante demande de ressources informatiques et de temps, surtout pour de grands ensembles de données. Dans ce résumé, nous expliquons comment optimiser ce pipeline en utilisant le calcul accéléré par GPU avec la bibliothèque cuML, permettant d'exécuter le workflow en seulement 15 minutes. Cette approche combine la puissance de l'ensemble des modèles avec une recherche optimisée des hyperparamètres, tout en facilitant l'intégration sans modification de code dans les workflows existants. Technique de Stacking Generalization Le stacking generalization est une méthode d'ensemble établie et efficace, souvent utilisée dans des compétitions comme celles de Kaggle. Il consiste à combiner plusieurs modèles pour améliorer la précision des prédictions, mais l'underexploitation dans les applications pratiques est due à son coût en termes de calcul. Notre architecture de stacking, illustrée dans la Figure 1, se compose de trois modèles de base : Random Forest, K-Nearest Neighbors (KNN), et Logistic Regression. Les prédictions de ces modèles de base sont ensuite transmises à un modèle métamodèle (KNN) qui réalise la classification finale basée sur les sorties combinées. Figure 1. Architecture du stacking generalization utilisant différents algorithmes. Pour notre ensemble de données expérimental contenant 1 million d'échantillons et neuf caractéristiques, cette méthode a permis d'exploiter le meilleur des trois modèles de base, améliorant globalement la précision des prédictions. La précision a été évaluée à l'aide d'une validation croisée stratifiée à 5 plis. Le code suivant montre comment nous avons configuré notre pipeline de stacking. Pour tester cette configuration, vous pouvez consulter l'accompagnant Jupyter Notebook. ```python %load_ext cuml.accel Charger les bibliothèques cuML from sklearn.linear_model import LogisticRegression from sklearn.ensemble import RandomForestClassifier from sklearn.neighbors import KNeighborsClassifier Définir les modèles de base (niveau 0) base_models = [ ("logistic_regression", LogisticRegression(max_iter=20000, tol=1e-3)), ("random_forest", RandomForestClassifier(random_state=42)), ("k_nearest_neighbors", KNeighborsClassifier()) ] Fonction pour générer les caractéristiques métas pour le stacking def generate_meta_features_for_stacking(base_models, X, y, X_meta): kfold = StratifiedKFold(n_splits=5, shuffle=True, random_state=42) meta_features = cp.zeros((X_meta.shape[0], len(base_models))) for i, (name, model) in enumerate(base_models): # Initialiser un tableau pour stocker les prédictions hors-pli (uniquement pour les données d'entraînement) meta_predictions = cp.zeros((X.shape[0],)) print("Nom du modèle : ", name) # Prédictions hors-pli (utilisées uniquement si X_meta == X) for train_idx, val_idx in kfold.split(X, y): model.fit(cp.array(X.iloc[train_idx]), cp.array(y.iloc[train_idx])) predictions = model.predict(cp.array(X.iloc[val_idx])) meta_predictions[val_idx] = predictions.ravel() # Réentraîner le modèle sur l'ensemble des données d'entraînement pour la prédiction finale sur X_meta model.fit(cp.array(X), cp.array(y)) # Prédire les caractéristiques métas pour les données de test predictions = model.predict(cp.array(X_meta)) meta_features[:, i] = cp.array(predictions).ravel() return meta_features meta_train utilise les prédictions hors-pli pour éviter la fuite d'informations meta_train = generate_meta_features_for_stacking(base_models, X_train_scaled, y_train_df, X_train_scaled) meta_valid utilise les prédictions des modèles de base entraînés sur l'ensemble des données d'entraînement meta_valid = generate_meta_features_for_stacking(base_models, X_train_scaled, y_train_df, X_valid_scaled) ``` Le stacking generalization a conduit à une amélioration de 0.28% de la précision prédictive, comme le montre la Figure 2. Figure 2. Amélioration de la précision obtenue en utilisant le modèle métamodèle KNN dans le stacking generalization. Optimisation des Hyperparamètres Pour optimiser davantage le pipeline, nous avons appliqué l'optimisation des hyperparamètres (HPO) à chaque modèle de base ainsi qu'au modèle métamodèle. Nous avons choisi le meilleur modèle de base pour générer des prédictions hors-pli, qui ont été empilées pour créer un nouveau métadataset. Ce dernière a été utilisé pour exécuter la HPO sur le modèle métamodèle KNN, afin de raffiner encore plus ses performances. Nous avons utilisé la bibliothèque Optuna pour la HPO, en optimisant les hyperparamètres en fonction de la précision de classification. Le processus HPO a également bénéficié de l'accélération GPU grâce à la commande %load_ext cuml.accel. Cela signifie que la syntaxe reste la même que celle de scikit-learn. Le code suivant illustre comment la HPO a été mise en place pour le modèle de régression logistique. La même approche a été appliquée aux modèles Random Forest, KNN et au métamodèle KNN. ```python %load_ext cuml.accel Charger les bibliothèques cuML from sklearn.linear_model import LogisticRegression from sklearn.ensemble import RandomForestClassifier from sklearn.neighbors import KNeighborsClassifier Définir la fonction d'entraînement et d'évaluation du modèle def train_and_eval(C=1, penalty='l2'): lr = LogisticRegression(C=C, penalty=penalty, max_iter=20000, tol=1e-3) lr.fit(X_train_scaled, y_train_df) y_proba = lr.predict_proba(X_valid_scaled)[:, 1] # Calculer le score de précision score = cp.round(lr.score(cp.asnumpy(X_valid_scaled), cp.asnumpy(y_valid_df)) * 100, 2) return score Définir la fonction objectif pour l'optimisation des hyperparamètres def objective(trial): C = trial.suggest_float("C", 1e-2, 1e2, log=True) penalty = trial.suggest_categorical("penalty", ["l1", "l2"]) return train_and_eval(C, penalty) Créer une étude Optuna pour maximiser le score de précision lr_study = optuna.create_study( direction="maximize", study_name="optuna_logistic_acc_score", sampler=optuna.samplers.RandomSampler(seed=142), ) Lancer l'optimisation des hyperparamètres avec l'objectif défini lr_study.optimize(objective, n_trials=40) Afficher l'ensemble d'hyperparamètres optimal et son score d'évaluation correspondant print(f"Meilleurs paramètres : {lr_study.best_params}") print(f"Meilleur score de précision : {lr_study.best_value}") ``` L'application de la HPO aux modèles de base et au métamodèle a entraîné une amélioration supplémentaire de 1.44% de la précision prédictive, comme indiqué dans la Figure 3. Figure 3. Amélioration de la précision en utilisant la HPO. Avantages de l'Utilisation de l'Accélération GPU avec cuML L'accélération GPU via cuML offre un avantage majeur en termes de rapidité d'exécution, notamment pendant la HPO des quatre modèles distincts. Elle permet de réaliser plusieurs itérations dans le laps de temps où une exécution CPU effectuerait une seule itération. Dans notre cas, nous avons réussi à effectuer environ 40 itérations pour chaque modèle, chaque itération prenant environ 5 secondes. Sur un CPU, une itération unique prendrait typiquement environ 5 minutes. De plus, l'activation de l'accélération GPU est très simple, il suffit d'inclure la commande %load_ext cuml.accel dans votre code, sans avoir à modifier le reste de la syntaxe scikit-learn. Évaluation et Profil de l'Entreprise Les professionnels de l'industrie saluent cette approche combinée, soulignant qu'elle transforme les techniques d'ensemble et d'optimisation des hyperparamètres en outils praticables pour les applications réelles. NVIDIA, leader dans le domaine du calcul parallèle et de l'intelligence artificielle, met l'accent sur la simplicité et l'efficacité de cuML, rendant ces méthodes accessibles à un large public de chercheurs et de développeurs. cuML, intégré à scikit-learn, propose une accélération GPU transparente, permettant aux développeurs de conserver leurs workflows existants tout en bénéficiant d'une exécution plus rapide. Cette intégrité syntaxique facilite grandement l'adoption et l'intégration en production, tout en offrant une amélioration significative des performances des modèles. Pour explorer les possibilités offertes par cuML, téléchargez la dernière version de la bibliothèque NVIDIA cuML. Vous pouvez fournir vos retours sur Slack dans le canal #RAPIDS-GoAi. Pour plus de détails sur l'accélération sans modification de code cuML, consultez l'article "NVIDIA cuML Brings Zero Code Change Acceleration to scikit-learn". Des exemples supplémentaires sont disponibles dans un notebook Google Colab. La dernière version de cuML, dotée de capacités d'accélération sans modification de code, est préinstallée sur Google Colab. Pour ceux qui souhaitent approfondir leurs connaissances, des formations autonomes et encadrées sont proposées via le DLI Learning Path for Data Science. Cette approche intégrant le stacking generalization et la HPO, boostée par l'accélération GPU de NVIDIA cuML, offre un excellent compromis entre la précision des modèles et la rapidité de développement, ce qui est crucial pour des applications scientifiques et technologiques modernes.