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

Botorch with cardinality constraint via sampling #301

Open
wants to merge 109 commits into
base: main
Choose a base branch
from

Conversation

Waschenbacher
Copy link
Collaborator

@Waschenbacher Waschenbacher commented Jul 3, 2024

(edited by @AdrianSosic)

This PR adds support for cardinality constraints to BotorchRecommender. The core idea is to tackle the problem in an exhaustive search like manner, i.e. by

  • enumerating the possible combinations of in-/active parameters dictated by the cardinality constraints
  • optimizing the corresponding restricted subspaces, where the cardinality constraint can then be simply removed since the in-/active sets are fixed within these subspaces
  • aggregating the optimization results of the individual subspaces into a single recommendation batch.

The PR implements two mechanisms for determining the configuration of inactive parameters:

  • When the combinatorial list of possible inactive parameter configurations is not too large, we iterate the full list
  • otherwise, a fixed amount of inactive parameter configurations is randomly selected

The current aggregation step is to simply optimize all subspaces independently of each other and then return the batch from the subspace where the highest acquisition value is achieved. This has the side-effect that the set of inactive parameters is the same across the entire recommendation batch. This can be a desirable property in many use cases but potentially higher acquisition values can be obtained by altering the in-/activity sets across the batch. A simple way to achieve this (though out of scope for this PR) is by generalizing the sequential greedy principle to multiple subspaces.

Out of scope

  • Fulfilling cardinality constraints by passing them in suitable form as nonlinear constraints to the optimizer
  • Sequential greedy optimization to achieve varying in-/activity sets (see explanation above)

@Waschenbacher Waschenbacher added the new feature New functionality label Jul 3, 2024
@Waschenbacher Waschenbacher self-assigned this Jul 3, 2024
@Waschenbacher Waschenbacher marked this pull request as draft July 4, 2024 07:38
@Waschenbacher Waschenbacher force-pushed the feature/cardinality_constraint_to_botorch_via_sampling branch from 0be3285 to 1f7783d Compare July 4, 2024 09:21
@Waschenbacher Waschenbacher marked this pull request as ready for review July 4, 2024 09:35
AdrianSosic

This comment was marked as resolved.

@Waschenbacher Waschenbacher force-pushed the feature/cardinality_constraint_to_botorch_via_sampling branch from 1f7783d to 9d28b49 Compare July 12, 2024 07:38
@AdrianSosic AdrianSosic force-pushed the feature/cardinality_constraint_to_botorch_via_sampling branch from f68ce4f to fc52875 Compare August 15, 2024 12:52
AdrianSosic

This comment was marked as outdated.

@AdrianSosic AdrianSosic marked this pull request as ready for review February 12, 2025 13:07
@AdrianSosic
Copy link
Collaborator

@Scienfitz, this beast is finally ready for ready for review. Let's try to really merge it in this time. As already mentioned, the entire PR would be significantly smaller had we omitted the (potentially use case irrelevant?) option of setting a min_cardinality. But what shall I say ... now it's there 🙃

Happy to see your feedback

Copy link
Collaborator

@Scienfitz Scienfitz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

massive PR is massive


# Count the number of active values per dataframe row
cols = df[c.parameters]
is_inactive = is_between(cols, thresholds) | (cols == 0.0)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isnt the cols == 0.0 part of obsolete? its also checked by is_between since 0 is enforced to be inside the interval?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, not quite. There is a subtle issue because is_between gives False when the value is 0 and one of the bounds itself is zero (due to inequality check). Alternatively, we could resolve this by making is_between a true generalization of pandas.Series.is_between, which gives control on whether equality or inequality should be used. What do you prefer?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that would mak sene to me and would be prefereable, the current line here feels weird

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah no, my bad. The generalization does actually not solve the situation here. The special case was added for a different reason, namely to satisfy what is explained in the docstring of the cardinality constraint:
image
So is_between really needs to be invoked with < instead of <= to correctly count inactive parameters. Can you confirm that I'm not talking BS, @Waschenbacher?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Synced with @AdrianSosic. We decide to rework on this part that should solve this issue as well as the other open thread here.

Copy link
Collaborator

@Scienfitz Scienfitz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Besides the open comments I have nothing else other than the usual please add something to the userguides for both discrete and conti cardinality constraints

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

Successfully merging this pull request may close these issues.

4 participants