Skip to content

Commit

Permalink
Merge pull request #167 from automl/upgrade-configspace
Browse files Browse the repository at this point in the history
Upgrade ConfigCpace to v1.2.0
  • Loading branch information
sarah-segel authored Aug 8, 2024
2 parents e6f417f + b5170f1 commit c2bcc1b
Show file tree
Hide file tree
Showing 73 changed files with 175 additions and 4,689 deletions.
10 changes: 7 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,15 @@ repos:
'absl-py>=1.0.0',
'jsonlines>=3.0.0',
'pandas>=1.3.4',
'numpy==1.26.4',
'matplotlib>=3.5.1',
'numpy>=2.0.1',
'matplotlib==3.9.0',
'seaborn>=0.13.0',
'pyyaml>=6.0.1',
'kaleido>=0.2.1',
'gplearn>=0.4.2',
'sympy>=1.12',
'ConfigSpace==0.6.1',
'requests>=2.31.0',
'ConfigSpace==1.2.0',
'pyrfr>=0.9.0',
'hpbandster==0.7.4',
'dash==2.0.0',
Expand All @@ -63,6 +65,8 @@ repos:
'redis>=4.1.4',
'rq>=1.10.1',
'werkzeug==2.0.3',
'pyarrow==16.1.0',
'fastparquet==2024.5.0',
'pyPDPPartitioner>=0.1.8'
] # Needed for mypy, so that it knows the types to check

Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
## Converters
- Add support for AMLTK.

## Version-Updates
- ConfigSpace from 0.6.1 to 1.2.0
- Numpy from 1.26.4 to 2.0.1

## Ablation Paths
- Added ablation paths as a plugin.
- Added ablation as a evaluator to use for the plugin.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ from deepcave import Recorder, Objective
configspace = CS.ConfigurationSpace(seed=0)
alpha = CS.hyperparameters.UniformFloatHyperparameter(
name='alpha', lower=0, upper=1)
configspace.add_hyperparameter(alpha)
configspace.add(alpha)

accuracy = Objective("accuracy", lower=0, upper=1, optimize="upper")
mse = Objective("mse", lower=0)
Expand Down
2 changes: 1 addition & 1 deletion deepcave/evaluators/epm/random_forest.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ def _predict(self, X: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:
# Transform list of 2d arrays into a 3d array
num_trees = self._model.options.num_trees
shape = (X.shape[0], num_trees, third_dimension)
preds_as_array = np.zeros(shape) * np.NaN
preds_as_array = np.zeros(shape) * np.nan
for i, preds_per_tree in enumerate(all_preds):
for j, pred in enumerate(preds_per_tree):
preds_as_array[i, j, : len(pred)] = pred
Expand Down
16 changes: 8 additions & 8 deletions deepcave/evaluators/epm/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
as well as the bounds of the Hyperparameters.
"""

import typing
from typing import List, Optional, Tuple

import numpy as np
from ConfigSpace import ConfigurationSpace
Expand All @@ -25,8 +25,8 @@

def get_types(
config_space: ConfigurationSpace,
instance_features: typing.Optional[np.ndarray] = None,
) -> typing.Tuple[typing.List[int], typing.List[typing.Tuple[float, float]]]:
instance_features: Optional[np.ndarray] = None,
) -> Tuple[List[int], List[Tuple[float, float]]]:
"""
Return the types of the Hyperparameters.
Expand All @@ -42,7 +42,7 @@ def get_types(
Returns
-------
Tuple[typing.List[int], List[Tuple[float, float]]]
Tuple[List[int], List[Tuple[float, float]]]
The types of the Hyperparameters, as well as the bounds and instance features.
Raises
Expand Down Expand Up @@ -104,28 +104,28 @@ def get_types(
"Inactive parameters not supported for Beta and Normal Hyperparameters"
)

bounds[i] = (param._lower, param._upper)
bounds[i] = (param.lower_vectorized, param.upper_vectorized) # type: ignore
elif isinstance(param, NormalIntegerHyperparameter):
if can_be_inactive:
raise ValueError(
"Inactive parameters not supported for Beta and Normal Hyperparameters"
)

bounds[i] = (param.nfhp._lower, param.nfhp._upper)
bounds[i] = (param.lower_vectorized, param.upper_vectorized) # type: ignore
elif isinstance(param, BetaFloatHyperparameter):
if can_be_inactive:
raise ValueError(
"Inactive parameters not supported for Beta and Normal Hyperparameters"
)

bounds[i] = (param._lower, param._upper)
bounds[i] = (param.lower_vectorized, param.upper_vectorized) # type: ignore
elif isinstance(param, BetaIntegerHyperparameter):
if can_be_inactive:
raise ValueError(
"Inactive parameters not supported for Beta and Normal Hyperparameters"
)

bounds[i] = (param.bfhp._lower, param.bfhp._upper)
bounds[i] = (param.lower_vectorized, param.upper_vectorized) # type: ignore
elif not isinstance(
param,
(
Expand Down
2 changes: 1 addition & 1 deletion deepcave/evaluators/fanova.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def __init__(self, run: AbstractRun):
self.run = run
self.cs = run.configspace
self.hps = self.cs.get_hyperparameters()
self.hp_names = self.cs.get_hyperparameter_names()
self.hp_names = list(self.cs.keys())
self.logger = get_logger(self.__class__.__name__)

def calculate(
Expand Down
2 changes: 1 addition & 1 deletion deepcave/evaluators/footprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def calculate(
data = self.run.get_encoded_data(
objective, budget, statuses=Status.SUCCESS, specific=False, include_config_ids=True
)
hp_names = self.run.configspace.get_hyperparameter_names()
hp_names = list(self.run.configspace.keys())

# Make numpy arrays
X = data[hp_names].to_numpy()
Expand Down
21 changes: 15 additions & 6 deletions deepcave/evaluators/lpi.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@
from ConfigSpace import Configuration
from ConfigSpace.c_util import change_hp_value, check_forbidden
from ConfigSpace.exceptions import ForbiddenValueError
from ConfigSpace.hyperparameters import CategoricalHyperparameter
from ConfigSpace.hyperparameters import (
CategoricalHyperparameter,
NumericalHyperparameter,
)
from ConfigSpace.types import Array, f64
from ConfigSpace.util import impute_inactive_values

from deepcave.constants import COMBINED_COST_NAME
Expand Down Expand Up @@ -157,7 +161,9 @@ def calculate(

# Create the neighbor-Configuration object
new_array = self.incumbent_array.copy()
new_array = change_hp_value(self.cs, new_array, hp_name, unit_neighbor, hp_idx)
new_array = change_hp_value(
self.cs, new_array, hp_name, unit_neighbor, self.cs.index_of[hp_name]
)
new_config = impute_inactive_values(Configuration(self.cs, vector=new_array))

# Get the leaf values
Expand Down Expand Up @@ -296,12 +302,15 @@ def _get_neighborhood(self) -> Dict[str, List[Union[np.ndarray, List[np.ndarray]
hp_neighborhood = []
checked_neighbors = [] # On unit cube
checked_neighbors_non_unit_cube = [] # Not on unit cube
hp = self.cs.get_hyperparameter(hp_name)
hp = self.cs[hp_name]
num_neighbors = hp.get_num_neighbors(self.incumbent[hp_name])

neighbors: Union[List[Union[f64]], Array[Union[f64]]]

if num_neighbors == 0:
continue
elif np.isinf(num_neighbors):
assert isinstance(hp, NumericalHyperparameter)
if hp.log:
base = np.e
log_lower = np.log(hp.lower) / np.log(base)
Expand All @@ -315,7 +324,7 @@ def _get_neighborhood(self) -> Dict[str, List[Union[np.ndarray, List[np.ndarray]
)
else:
neighbors_range = np.linspace(hp.lower, hp.upper, self.continous_neighbors)
neighbors = list(map(lambda x: hp._inverse_transform(x), neighbors_range))
neighbors = list(map(lambda x: hp.to_vector(x), neighbors_range))
else:
neighbors = hp.get_neighbors(self.incumbent_array[hp_idx], self.rs)

Expand All @@ -329,7 +338,7 @@ def _get_neighborhood(self) -> Dict[str, List[Union[np.ndarray, List[np.ndarray]
try:
new_config = Configuration(self.cs, vector=new_array)
hp_neighborhood.append(new_config)
new_config.is_valid_configuration()
new_config.check_valid_configuration()
check_forbidden(self.cs.forbidden_clauses, new_array)

checked_neighbors.append(neighbor)
Expand All @@ -340,7 +349,7 @@ def _get_neighborhood(self) -> Dict[str, List[Union[np.ndarray, List[np.ndarray]
sort_idx = list(
map(lambda x: x[0], sorted(enumerate(checked_neighbors), key=lambda y: y[1]))
)
if isinstance(self.cs.get_hyperparameter(hp_name), CategoricalHyperparameter):
if isinstance(self.cs[hp_name], CategoricalHyperparameter):
checked_neighbors_non_unit_cube_categorical = list(
np.array(checked_neighbors_non_unit_cube)[sort_idx]
)
Expand Down
8 changes: 4 additions & 4 deletions deepcave/plugins/hyperparameter/importances.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ def load_dependency_inputs(self, run, _: Any, inputs: Dict[str, Any]) -> Dict[st
budget_options = get_checklist_options(budgets, budget_ids)
budget_value = inputs["budget_ids"]["value"]

hp_names = run.configspace.get_hyperparameter_names()
hp_names = list(run.configspace.keys())
hp_options = get_checklist_options(hp_names)
hp_value = inputs["hyperparameter_names"]["value"]
n_hps = inputs["n_hps"]["value"]
Expand Down Expand Up @@ -315,8 +315,8 @@ def process(run: AbstractRun, inputs: Dict[str, Any]) -> Dict[str, Any]:
configspace_wo_const = ConfigurationSpace()
for k in hp_dict_wo_const.keys():
configspace_wo_const.add_hyperparameter(hp_dict_wo_const[k])
configspace_wo_const.add_conditions(run.configspace.get_conditions())
configspace_wo_const.add_forbidden_clauses(run.configspace.get_forbiddens())
configspace_wo_const.add(run.configspace.conditions)
configspace_wo_const.add(run.configspace.forbidden_clauses)
run.configspace = configspace_wo_const

configs_wo_const = []
Expand All @@ -326,7 +326,7 @@ def process(run: AbstractRun, inputs: Dict[str, Any]) -> Dict[str, Any]:
)
run.configs = dict(enumerate(configs_wo_const))

hp_names = run.configspace.get_hyperparameter_names()
hp_names = list(run.configspace.keys())
budgets = run.get_budgets(include_combined=True)

evaluator: Optional[Union[LocalEvaluator, GlobalEvaluator]] = None
Expand Down
10 changes: 5 additions & 5 deletions deepcave/plugins/hyperparameter/pdp.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ def load_dependency_inputs(self, run, previous_inputs, inputs) -> Dict[str, Any]
budget_ids = run.get_budget_ids()
budget_options = get_checklist_options(budgets, budget_ids)

hp_names = run.configspace.get_hyperparameter_names()
hp_names = list(run.configspace.keys())

# Get selected values
objective_value = inputs["objective_id"]["value"]
Expand Down Expand Up @@ -288,7 +288,7 @@ def process(run, inputs) -> Dict[str, Any]: # type: ignore
If the objective is None.
"""
# Surrogate
hp_names = run.configspace.get_hyperparameter_names()
hp_names = list(run.configspace.keys())
objective = run.get_objective(inputs["objective_id"])
budget = run.get_budget(inputs["budget_id"])
hp1 = inputs["hyperparameter_name_1"]
Expand Down Expand Up @@ -404,14 +404,14 @@ def get_pdp_figure( # type: ignore
# Parse inputs
hp1_name = inputs["hyperparameter_name_1"]
hp1_idx = run.configspace.get_idx_by_hyperparameter_name(hp1_name)
hp1 = run.configspace.get_hyperparameter(hp1_name)
hp1 = run.configspace[hp1_name]

hp2_name = inputs["hyperparameter_name_2"]
hp2_idx = None
hp2 = None
if hp2_name is not None and hp2_name != "":
hp2_idx = run.configspace.get_idx_by_hyperparameter_name(hp2_name)
hp2 = run.configspace.get_hyperparameter(hp2_name)
hp2 = run.configspace[hp2_name]

objective = run.get_objective(inputs["objective_id"])
objective_name = objective.name
Expand All @@ -425,7 +425,7 @@ def get_pdp_figure( # type: ignore
y_ice = np.asarray(outputs["y_ice"])

traces = []
if hp2_idx is None: # 1D
if hp2 is None: # 1D
# Add ICE curves
if show_ice:
for x_, y_ in zip(x_ice, y_ice):
Expand Down
8 changes: 4 additions & 4 deletions deepcave/plugins/hyperparameter/symbolic_explanations.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ def process(run, inputs) -> Dict[str, Any]: # type: ignore
RuntimeError
If the objective is None.
"""
hp_names = run.configspace.get_hyperparameter_names()
hp_names = list(run.configspace.keys())
objective = run.get_objective(inputs["objective_id"])
budget = run.get_budget(inputs["budget_id"])
hp1 = inputs["hyperparameter_name_1"]
Expand Down Expand Up @@ -533,18 +533,18 @@ def load_outputs(run, inputs, outputs) -> List[go.Figure]: # type: ignore
"""
hp1_name = inputs["hyperparameter_name_1"]
hp1_idx = run.configspace.get_idx_by_hyperparameter_name(hp1_name)
hp1 = run.configspace.get_hyperparameter(hp1_name)
hp1 = run.configspace[hp1_name]
selected_hyperparameters = [hp1]

hp2_name = inputs["hyperparameter_name_2"]
hp2_idx = None
hp2 = None
if hp2_name is not None and hp2_name != "":
hp2_idx = run.configspace.get_idx_by_hyperparameter_name(hp2_name)
hp2 = run.configspace.get_hyperparameter(hp2_name)
hp2 = run.configspace[hp2_name]
selected_hyperparameters += [hp2]

hp_names = run.configspace.get_hyperparameter_names()
hp_names = list(run.configspace.keys())
objective = run.get_objective(inputs["objective_id"])
objective_name = objective.name

Expand Down
4 changes: 2 additions & 2 deletions deepcave/plugins/objective/configuration_cube.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ def load_dependency_inputs(self, run, _, inputs) -> Dict[str, Any]: # type: ign
budget_value = inputs["budget_id"]["value"]

# Prepare others
hp_names = run.configspace.get_hyperparameter_names()
hp_names = list(run.configspace.keys())

# Get selected values
n_configs_value = inputs["n_configs"]["value"]
Expand Down Expand Up @@ -348,7 +348,7 @@ def load_outputs(run, inputs, outputs) -> go.Figure: # type: ignore
layout_kwargs = {}
if n_configs > 0 and len(hp_names) > 0:
for i, (hp_name, axis_name) in enumerate(zip(hp_names, ["xaxis", "yaxis", "zaxis"])):
hp = run.configspace.get_hyperparameter(hp_name)
hp = run.configspace[hp_name]
values = df[hp_name].values.tolist()

tickvals, ticktext = get_hyperparameter_ticks(hp, ticks=4, include_nan=True)
Expand Down
4 changes: 2 additions & 2 deletions deepcave/plugins/objective/parallel_coordinates.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ def load_dependency_inputs(self, run, _, inputs) -> Dict[str, Any]: # type: ign

# Prepare others
n_hps = inputs["n_hps"]["value"]
hp_names = run.configspace.get_hyperparameter_names()
hp_names = list(run.configspace.keys())

if inputs["show_important_only"]["value"] == "true":
hp_options = []
Expand Down Expand Up @@ -398,7 +398,7 @@ def load_outputs(run, inputs, outputs) -> go.Figure: # type: ignore
data[hp_name]["label"] = hp_name
data[hp_name]["range"] = VALUE_RANGE

hp = run.configspace.get_hyperparameter(hp_name)
hp = run.configspace[hp_name]
tickvals, ticktext = get_hyperparameter_ticks(hp, ticks=4, include_nan=True)

data[hp_name]["tickvals"] = tickvals
Expand Down
6 changes: 3 additions & 3 deletions deepcave/plugins/summary/configurations.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ def process(run, inputs) -> Dict[str, Any]: # type: ignore
# And add it to the lists
X.append(x)

columns = run.configspace.get_hyperparameter_names()
columns = list(run.configspace.keys())
columns += ["highlighted"]

cs_df = pd.DataFrame(data=X, columns=columns)
Expand Down Expand Up @@ -449,7 +449,7 @@ def _get_configspace_figure(
df = deserialize(outputs["cs_df"], dtype=pd.DataFrame)

highlighted = df["highlighted"].values
hp_names = run.configspace.get_hyperparameter_names()
hp_names = list(run.configspace.keys())

# Get highlighted column
highlighted_df = df[df["highlighted"] == 1]
Expand All @@ -460,7 +460,7 @@ def _get_configspace_figure(
data[hp_name]["label"] = hp_name
data[hp_name]["range"] = VALUE_RANGE

hp = run.configspace.get_hyperparameter(hp_name)
hp = run.configspace[hp_name]
tickvals, ticktext = get_hyperparameter_ticks(
hp, additional_values=highlighted_df[hp_name].values, ticks=4, include_nan=True
)
Expand Down
Loading

0 comments on commit c2bcc1b

Please sign in to comment.