diff --git a/pimp/evaluator/fanova.py b/pimp/evaluator/fanova.py index eb71ddb..42ec23b 100644 --- a/pimp/evaluator/fanova.py +++ b/pimp/evaluator/fanova.py @@ -14,6 +14,7 @@ from ConfigSpace.configuration_space import ConfigurationSpace, Configuration from ConfigSpace.util import impute_inactive_values from ConfigSpace.hyperparameters import CategoricalHyperparameter, Constant +from ConfigSpace.exceptions import ForbiddenValueError try: from fanova import fANOVA as fanova_pyrfr @@ -92,14 +93,20 @@ def _preprocess(self, runhistory): if self.cs_contained_constant: configs = [Configuration(self.cs, vector=c.get_array()) for c in configs] X_non_hyper, X_prime = [], [] + skipped_forbidden = 0 for config in configs: - config = impute_inactive_values(config).get_array() + try: + config = impute_inactive_values(config).get_array() + except ForbiddenValueError: + skipped_forbidden += 1 + continue X_prime.append(config) X_non_hyper.append(config) for idx, param in enumerate(self.cs.get_hyperparameters()): if not (isinstance(param, CategoricalHyperparameter) or isinstance(param, Constant)): X_non_hyper[-1][idx] = param._transform(X_non_hyper[-1][idx]) + self.logger.debug("Skipped %d forbidden configurations", skipped_forbidden) X_non_hyper = np.array(X_non_hyper) X_prime = np.array(X_prime) y_prime = np.array(self.model.predict_marginalized_over_instances(X_prime)[0]) diff --git a/pimp/evaluator/local_parameter_importance.py b/pimp/evaluator/local_parameter_importance.py index fc28f0f..60a15d3 100644 --- a/pimp/evaluator/local_parameter_importance.py +++ b/pimp/evaluator/local_parameter_importance.py @@ -193,6 +193,7 @@ def run(self) -> OrderedDict: added_inc = False inc_at = 0 # Iterate over neighbors + skipped_forbidden_neighbors = 0 for unit_neighbor, neighbor in zip(neighborhood_dict[param][0], neighborhood_dict[param][1]): if not added_inc: if unit_neighbor > incumbent_array[index]: @@ -207,13 +208,22 @@ def run(self) -> OrderedDict: new_array = incumbent_array.copy() new_array = change_hp_value(self.incumbent.configuration_space, new_array, param, unit_neighbor, index) - new_configuration = impute_inactive_values(Configuration(self.incumbent.configuration_space, - vector=new_array)) + try: + new_configuration = impute_inactive_values(Configuration(self.incumbent.configuration_space, + vector=new_array)) + except ForbiddenValueError: + skipped_forbidden_neighbors += 1 + continue mean, var = self._predict_over_instance_set(new_configuration) performance_dict[param].append(mean) overall_var[param].append(mean) variance_dict[param].append(var) pbar.update(1) + self.logger.debug("Skipped %d (of %d) forbidden neighbors", skipped_forbidden_neighbors, + len(neighborhood_dict[param][0])) + if skipped_forbidden_neighbors == len(neighborhood_dict[param][0]): + self.logger.debug("No valid neighbors found for %s, skipping.", param) + continue if len(neighborhood_dict[param][0]) > 0: neighborhood_dict[param][0] = np.insert(neighborhood_dict[param][0], inc_at, incumbent_array[index]) neighborhood_dict[param][1] = np.insert(neighborhood_dict[param][1], inc_at, self.incumbent[param])