Source code for smac.epm.gaussian_process

from typing import List, Optional, Tuple, Union

import numpy as np
import sklearn.gaussian_process
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import Kernel, KernelOperator

import smac.epm.gaussian_process.utils.prior
from smac.configspace import ConfigurationSpace
from smac.epm.base_epm import BaseEPM
from smac.epm.gaussian_process.utils.prior import Prior

__copyright__ = "Copyright 2021, AutoML.org Freiburg-Hannover"
__license__ = "3-clause BSD"


[docs]class BaseModel(BaseEPM): def __init__( self, configspace: ConfigurationSpace, types: List[int], bounds: List[Tuple[float, float]], seed: int, kernel: Kernel, instance_features: Optional[np.ndarray] = None, pca_components: Optional[int] = None, ): """Abstract base class for all Gaussian process models.""" super().__init__( configspace=configspace, types=types, bounds=bounds, seed=seed, instance_features=instance_features, pca_components=pca_components, ) self.rng = np.random.RandomState(seed) self.kernel = kernel self.gp = self._get_gp() def _get_gp(self) -> GaussianProcessRegressor: """Returns the Gaussian process.""" raise NotImplementedError() def _normalize_y(self, y: np.ndarray) -> np.ndarray: """Normalize data to zero mean unit standard deviation. Parameters ---------- y : np.ndarray Targets for the Gaussian process Returns ------- np.ndarray """ self.mean_y_ = np.mean(y) self.std_y_ = np.std(y) if self.std_y_ == 0: self.std_y_ = 1 return (y - self.mean_y_) / self.std_y_ def _untransform_y( self, y: np.ndarray, var: Optional[np.ndarray] = None, ) -> Union[np.ndarray, Tuple[np.ndarray, np.ndarray]]: """Transform zeromean unit standard deviation data into the regular space. This function should be used after a prediction with the Gaussian process which was trained on normalized data. Parameters ---------- y : np.ndarray Normalized data. var : np.ndarray (optional) Normalized variance Returns ------- np.ndarray on Tuple[np.ndarray, np.ndarray] """ y = y * self.std_y_ + self.mean_y_ if var is not None: var = var * self.std_y_**2 return y, var # type: ignore return y def _get_all_priors( self, add_bound_priors: bool = True, add_soft_bounds: bool = False, ) -> List[List[Prior]]: """Returns all priors.""" # Obtain a list of all priors for each tunable hyperparameter of the kernel all_priors = [] to_visit = [] to_visit.append(self.gp.kernel.k1) to_visit.append(self.gp.kernel.k2) while len(to_visit) > 0: current_param = to_visit.pop(0) if isinstance(current_param, KernelOperator): to_visit.insert(0, current_param.k1) to_visit.insert(1, current_param.k2) continue elif isinstance(current_param, Kernel): hps = current_param.hyperparameters assert len(hps) == 1 hp = hps[0] if hp.fixed: continue bounds = hps[0].bounds for i in range(hps[0].n_elements): priors_for_hp = [] if current_param.prior is not None: priors_for_hp.append(current_param.prior) if add_bound_priors: if add_soft_bounds: priors_for_hp.append( smac.epm.gaussian_process.utils.prior.SoftTopHatPrior( lower_bound=bounds[i][0], upper_bound=bounds[i][1], rng=self.rng, exponent=2, ) ) else: priors_for_hp.append( smac.epm.gaussian_process.utils.prior.TophatPrior( lower_bound=bounds[i][0], upper_bound=bounds[i][1], rng=self.rng, ) ) all_priors.append(priors_for_hp) return all_priors def _set_has_conditions(self) -> None: """Sets `has_conditions` on `current_param`.""" has_conditions = len(self.configspace.get_conditions()) > 0 to_visit = [] to_visit.append(self.kernel) while len(to_visit) > 0: current_param = to_visit.pop(0) if isinstance(current_param, sklearn.gaussian_process.kernels.KernelOperator): to_visit.insert(0, current_param.k1) to_visit.insert(1, current_param.k2) current_param.has_conditions = has_conditions elif isinstance(current_param, sklearn.gaussian_process.kernels.Kernel): current_param.has_conditions = has_conditions else: raise ValueError(current_param) def _impute_inactive(self, X: np.ndarray) -> np.ndarray: """Imputes inactives.""" X = X.copy() X[~np.isfinite(X)] = -1 return X
from smac.epm.gaussian_process.gp import GaussianProcess # noqa __all__ = ["BaseModel", "GaussianProcess"]