def _sample_mo_categorical_index( self, study: "multi_objective.study.MultiObjectiveStudy", trial: "multi_objective.trial.FrozenMultiObjectiveTrial", distribution: distributions.CategoricalDistribution, below: np.ndarray, above: np.ndarray, ) -> int: choices = distribution.choices below = list(map(int, below)) above = list(map(int, above)) upper = len(choices) size = (self._n_ehvi_candidates, ) if self._weights is _default_weights_above: weights_below = study._storage.get_trial( trial._trial_id).system_attrs[_WEIGHTS_BELOW_KEY] else: weights_below = self._weights(len(below)) counts_below = np.bincount(below, minlength=upper, weights=weights_below) weighted_below = counts_below + self._prior_weight weighted_below /= weighted_below.sum() samples_below = self._sample_from_categorical_dist( weighted_below, size) log_likelihoods_below = TPESampler._categorical_log_pdf( samples_below, weighted_below) weights_above = self._weights(len(above)) counts_above = np.bincount(above, minlength=upper, weights=weights_above) weighted_above = counts_above + self._prior_weight weighted_above /= weighted_above.sum() log_likelihoods_above = TPESampler._categorical_log_pdf( samples_below, weighted_above) return int( TPESampler._compare(samples=samples_below, log_l=log_likelihoods_below, log_g=log_likelihoods_above)[0])
def _sample_mo_numerical( self, study: "multi_objective.study.MultiObjectiveStudy", trial: "multi_objective.trial.FrozenMultiObjectiveTrial", low: float, high: float, below: np.ndarray, above: np.ndarray, q: Optional[float] = None, is_log: bool = False, ) -> float: if is_log: low = np.log(low) high = np.log(high) below = np.log(below) above = np.log(above) size = (self._n_ehvi_candidates, ) weights_below: Callable[[int], np.ndarray] if self._weights is _default_weights_above: weights_below = lambda _: np.asarray( # NOQA study._storage.get_trial(trial._trial_id).system_attrs[ _WEIGHTS_BELOW_KEY], dtype=float, ) else: weights_below = self._weights parzen_estimator_parameters_below = _ParzenEstimatorParameters( self._parzen_estimator_parameters.consider_prior, self._parzen_estimator_parameters.prior_weight, self._parzen_estimator_parameters.consider_magic_clip, self._parzen_estimator_parameters.consider_endpoints, weights_below, ) parzen_estimator_below = _ParzenEstimator( mus=below, low=low, high=high, parameters=parzen_estimator_parameters_below) samples_below = self._sample_from_gmm( parzen_estimator=parzen_estimator_below, low=low, high=high, q=q, size=size, ) log_likelihoods_below = self._gmm_log_pdf( samples=samples_below, parzen_estimator=parzen_estimator_below, low=low, high=high, q=q, ) weights_above = self._weights parzen_estimator_parameters_above = _ParzenEstimatorParameters( self._parzen_estimator_parameters.consider_prior, self._parzen_estimator_parameters.prior_weight, self._parzen_estimator_parameters.consider_magic_clip, self._parzen_estimator_parameters.consider_endpoints, weights_above, ) parzen_estimator_above = _ParzenEstimator( mus=above, low=low, high=high, parameters=parzen_estimator_parameters_above) log_likelihoods_above = self._gmm_log_pdf( samples=samples_below, parzen_estimator=parzen_estimator_above, low=low, high=high, q=q, ) ret = float( TPESampler._compare(samples=samples_below, log_l=log_likelihoods_below, log_g=log_likelihoods_above)[0]) return math.exp(ret) if is_log else ret