Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plot_contour doesn't work with a Choice parameter #1624

Closed
LaureAcin opened this issue May 22, 2023 · 1 comment
Closed

Plot_contour doesn't work with a Choice parameter #1624

LaureAcin opened this issue May 22, 2023 · 1 comment
Labels
enhancement New feature or request

Comments

@LaureAcin
Copy link

Hello,

I optimize my model with two parameters, one is RangeParameter and the other is ChoiceParameter.
parameters = [ {"name": "radius", "type": "range", "value_type": "int", "bounds": [1, 7]}, {"name": "nb_filter", "type": "choice", "is_ordered": True, "value_type": "int", "values": [2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32]}, {"name": "dilatation", "type":"range", "value_type": "int", "bounds": [1,3]}, ],
Optimization worked and I can plot the response surface between radius and dilatation parameters which are interger RangeParameters.

Now, I try to plot the response surface between the RangeParameter radius and the Choice parameter nb_filter but when I run code there is an error with Choice parameter because it is not a RangeParameter. Then, I modified code to use a ChoiceParameter as y_param. I modified _get_contour_predictions as:

`def _get_contour_predictions(
model: ModelBridge,
x_param_name: str,
y_param_name: str,
metric: str,
generator_runs_dict: TNullableGeneratorRunsDict,
density: int,
slice_values: Optional[Dict[str, Any]] = None,
fixed_features: Optional[ObservationFeatures] = None,
) -> ContourPredictions:
"""
slice_values is a dictionary {param_name: value} for the parameters that
are being sliced on.
"""
x_param = get_range_parameter(model, x_param_name)
y_param = get_choice_parameter(model, y_param_name) # modified

plot_data, _, _ = get_plot_data(
    model, generator_runs_dict or {}, {metric}, fixed_features=fixed_features
)

grid_x = get_grid_for_parameter(x_param, density)
grid_y = get_grid_for_choice_parameter(y_param, density)
scales = {"x": x_param.log_scale, "y": False}                            # modified

grid2_x, grid2_y = np.meshgrid(grid_x, grid_y)

grid2_x = grid2_x.flatten()
grid2_y = grid2_y.flatten()

if fixed_features is not None:
    slice_values = fixed_features.parameters
else:
    fixed_features = ObservationFeatures(parameters={})

fixed_values = get_fixed_values(model, slice_values)

param_grid_obsf = []
for i in range(density**2):
    predf = deepcopy(fixed_features)
    predf.parameters = fixed_values.copy()
    predf.parameters[x_param_name] = grid2_x[i]
    predf.parameters[y_param_name] = grid2_y[i]
    param_grid_obsf.append(predf)

mu, cov = model.predict(param_grid_obsf)

f_plt = mu[metric]
sd_plt = np.sqrt(cov[metric][metric])
# pyre-fixme[7]: Expected `Tuple[PlotData, np.ndarray, np.ndarray, np.ndarray,
#  np.ndarray, Dict[str, bool]]` but got `Tuple[PlotData, typing.List[float],
#  typing.Any, np.ndarray, np.ndarray, Dict[str, bool]]`.
return plot_data, f_plt, sd_plt, grid_x, grid_y, scales`

In helper.py I modified get_grid_for_parameter and get_range_parameter as:

def get_choice_parameter(model: ModelBridge, param_name:str) -> ChoiceParameter: """ Get the choice parameter with the given name from the model. Throws if parameter doesn't exist or is not a choice parameter. Args: model: The model. param_name: The name of the ChoiceParameter to be found. Returns: The ChoiceParameter named param_name`.
"""

choice_param = model.model_space.parameters.get(param_name)
if choice_param is None:
    raise ValueError(f"Parameter `{param_name}` does not exist.")
if not isinstance(choice_param, ChoiceParameter):
    raise ValueError(f"{param_name} is not a ChoiceParameter")

return choice_param`

and

def get_grid_for_choice_parameter(parameter: RangeParameter, density: int) -> np.ndarray: """Get a grid of points along the range of the parameter. Will be a log-scale grid if parameter is log scale. Args: parameter: Parameter for which to generate grid. density: Number of points in the grid. """ grid = np.linspace(start = 2, stop = 32, num = density) return grid

When I run code, I obtain this error:
error_obsf.pdf

And when I look at Obsf I have this:
Obsf
I see that the KeyError occurs the first time that my ChoiceParameter nb_filter is different from two, but all my parameters are integer and there is no problem when in Obsf there are equal to float numbers for other parameters, so I don't know what is the problem.

Please, can you help me ?

Thank you in advance!

@lena-kashtelyan
Copy link
Contributor

Hello! This is a known issue and we are looking to resolve soon, I'll mark this as a feature request for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants