Sélection des Noyaux pour l'Optimisation BoTorch
Introduction
Le choix du noyau (kernel) est crucial dans les processus gaussiens et l'optimisation bayésienne. Le noyau définit la fonction de similarité entre les points d'entrée et influence directement la qualité de la modélisation et de l'optimisation.
Types de Noyaux Disponibles
1. Noyau Mixte ("mixed") - Recommandé par défaut
Principe : Combine automatiquement des noyaux adaptés aux variables discrètes et continues.
Avantages : - Adapté automatiquement au type de variables - Bon compromis entre performance et robustesse - Gère intelligemment les variables discrètes et continues
Utilisation :
results = botorch_multi_objective_optimizer_kernel(
# ... autres paramètres ...
kernel_type="mixed"
)
Comportement : - Variables discrètes : RBF avec lengthscale court - Variables continues : Matern 5/2 avec ARD - Combinaison multiplicative des noyaux
2. Noyau Matern ("matern")
Principe : Noyau Matern 5/2 avec détermination automatique de la pertinence (ARD).
Avantages : - Excellent pour les variables continues - Moins lisse que RBF, capture mieux les variations locales - ARD permet d'apprendre l'importance relative de chaque variable
Utilisation :
results = botorch_multi_objective_optimizer_kernel(
# ... autres paramètres ...
kernel_type="matern"
)
Caractéristiques :
- Paramètre nu=2.5 (Matern 5/2)
- ARD activé pour toutes les dimensions
- Bon pour les fonctions avec des dérivées continues
3. Noyau RBF ("rbf")
Principe : Noyau à base radiale (Radial Basis Function) avec ARD.
Avantages : - Très lisse, bon pour beaucoup de types de fonctions - Robuste et stable - Convergence souvent plus rapide
Utilisation :
Caractéristiques : - Fonction exponentielle quadratique - ARD activé pour toutes les dimensions - Excellent pour les fonctions lisses
4. Noyau Catégorique ("categorical")
Principe : Noyau spécialisé pour les variables discrètes avec lengthscales courts.
Avantages : - Optimisé pour les variables discrètes - Traite les catégories comme des points distincts - Sensible aux différences entre catégories
Utilisation :
results = botorch_multi_objective_optimizer_kernel(
# ... autres paramètres ...
kernel_type="categorical"
)
Caractéristiques : - RBF avec lengthscale court (0.1) - Rend les catégories "éloignées" dans l'espace du noyau - Idéal pour les variables avec peu de valeurs possibles
Recommandations par Type de Problème
Problèmes avec Variables Discrètes Dominantes
# Beaucoup de variables discrètes (matériaux, systèmes, etc.)
kernel_type = "categorical" # ou "mixed"
Problèmes avec Variables Continues Dominantes
Problèmes Mixtes (Recommandé)
Problèmes de Convergence Lente
Comparaison des Performances
| Critère | Mixed | Matern | RBF | Categorical |
|---|---|---|---|---|
| Variables Discrètes | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐⭐ |
| Variables Continues | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐ |
| Convergence | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| Robustesse | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| Facilité d'utilisation | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
Exemple de Comparaison
#!/usr/bin/env python3
"""
Exemple de comparaison des noyaux
"""
from oreni.optim.botorch_optimization import botorch_multi_objective_optimizer_kernel
# Configuration de base
config = {
"function": Simuls.compute_cost_functions,
"decision_space": decision_space,
"uncertain_space": uncertain_space,
"function_labels": ["Cost", "Emissions", "Comfort"],
"n_initial_points": 10,
"n_optimization_iterations": 20,
"n_uncs": 5
}
# Test de différents noyaux
kernels = ["mixed", "matern", "rbf", "categorical"]
results = {}
for kernel in kernels:
print(f"Testing kernel: {kernel}")
results[kernel] = botorch_multi_objective_optimizer_kernel(
**config,
kernel_type=kernel
)
Paramètres Avancés
Ajustement des Lengthscales
Pour un contrôle plus fin, vous pouvez modifier les lengthscales dans le code :
# Dans _create_categorical_kernel
kernel.base_kernel.lengthscale = torch.ones_like(kernel.base_kernel.lengthscale) * 0.1
# Pour des variables discrètes avec plus de valeurs
kernel.base_kernel.lengthscale = torch.ones_like(kernel.base_kernel.lengthscale) * 0.05
Combinaison de Noyaux
Pour des problèmes complexes, vous pouvez créer des noyaux personnalisés :
# Exemple de noyau personnalisé
from gpytorch.kernels import MaternKernel, RBFKernel, ScaleKernel
# Noyau pour variables continues
continuous_kernel = ScaleKernel(MaternKernel(nu=2.5, ard_num_dims=3))
# Noyau pour variables discrètes
discrete_kernel = ScaleKernel(RBFKernel(ard_num_dims=2))
# Combinaison multiplicative
combined_kernel = continuous_kernel * discrete_kernel
Diagnostic et Dépannage
Problèmes de Convergence
# Si l'optimisation ne converge pas
kernel_type = "rbf" # Plus stable
raw_samples = 1024 # Plus d'échantillons
num_restarts = 20 # Plus de redémarrages
Overfitting
Underfitting
Bonnes Pratiques
1. Commencez par le Noyau Mixte
2. Testez Plusieurs Noyaux
# Pour des problèmes critiques
kernels_to_test = ["mixed", "matern", "rbf"]
# Comparez les résultats
3. Adaptez selon les Variables
# Analysez vos variables
if mostly_discrete:
kernel_type = "categorical"
elif mostly_continuous:
kernel_type = "matern"
else:
kernel_type = "mixed"
4. Surveillez les Logs
import logging
logging.basicConfig(level=logging.INFO)
# Les logs affichent le type de noyau utilisé
# et les informations sur les variables discrètes
Exemple Complet
#!/usr/bin/env python3
"""
Exemple complet d'optimisation avec sélection de noyau
"""
import logging
from oreni.optim.botorch_optimization import botorch_multi_objective_optimizer_kernel
# Configuration du logging
logging.basicConfig(level=logging.INFO)
# Configuration de l'optimisation
def optimize_with_kernel_selection(kernel_type="mixed"):
"""Optimisation avec sélection de noyau."""
results = botorch_multi_objective_optimizer_kernel(
function=Simuls.compute_cost_functions,
decision_space=decision_space,
uncertain_space=uncertain_space,
function_labels=["Life_Cycle_Cost", "Life_Cycle_Assessment", "Thermal_Comfort"],
n_initial_points=10,
n_optimization_iterations=20,
n_uncs=5,
kernel_type=kernel_type, # Sélection du noyau
batch_size=2,
raw_samples=512,
num_restarts=10
)
return results
# Test de différents noyaux
kernels = ["mixed", "matern", "rbf", "categorical"]
for kernel in kernels:
print(f"\n🔬 Test du noyau: {kernel}")
try:
results = optimize_with_kernel_selection(kernel)
print(f"✅ Succès avec le noyau {kernel}")
except Exception as e:
print(f"❌ Erreur avec le noyau {kernel}: {e}")
Conclusion
Le choix du noyau dépend de la nature de vos variables et de vos objectifs :
mixed: Recommandé par défaut, adaptatifmatern: Excellent pour les variables continuesrbf: Robuste et lisse, bon pour la convergencecategorical: Spécialisé pour les variables discrètes
Testez plusieurs noyaux pour trouver celui qui convient le mieux à votre problème spécifique !