Skip to content

Refactor recommendation mechanics#838

Merged
AdrianSosic merged 8 commits into
dev/candidatesfrom
refactor/recommendation_mechanics
Jun 25, 2026
Merged

Refactor recommendation mechanics#838
AdrianSosic merged 8 commits into
dev/candidatesfrom
refactor/recommendation_mechanics

Conversation

@AdrianSosic

@AdrianSosic AdrianSosic commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

This is a pure internal refactor — no behavior change.

Background

The consistency of the attribute structure of SubspaceDiscrete was historically enforced only by convention, not by the type system, meaning that mutating a subspace instance could produce an inconsistent state. Creating filtered copies of a subspace was therefore not safe. On top of that, doing so could have been potentially costly, since it might have involved materializing (parts of) the Cartesian product — another reason to avoid it.

As a workaround, the codebase avoided modifying subspace objects for filtered candidate sets altogether and instead computed candidates externally, threading them as a separate candidates_exp dataframe argument down through multiple layers of the recommender call stack. The FilteredSubspaceDiscrete subclass existed for the same reason: to apply a Boolean mask at call time without touching the subspace itself.

Previous preparatory PRs resolved issue #794 by making the consistency of the attribute structure of SubspaceDiscrete an enforced invariant, which now enables safe creation of filtered subspace copies. The cost problem — to be avoided by lazy materialization of the Cartesian product (see #796) — has not yet been addressed but will be resolved in a subsequent PR on the same development branch. This PR capitalizes on the invariant enforcement to simplify the recommender internals.

Changes

Drop FilteredSubspaceDiscrete (baybe/searchspace/_filtered.py deleted)
The subclass existed solely to override get_candidates() with a Boolean mask applied at call time. Now that creating a filtered copy of a subspace is safe, the class is unnecessary. Campaign is updated to create filtered subspace copies directly.

Drop dead pending_experiments argument
The pending_experiments parameter had been used in PureRecommender._recommend_with_discrete_parts to filter pending experiments from the candidate set, but became dead code when that filtering responsibility was moved to Campaign in an earlier refactor. It is now removed.

Drop redundant candidates_exp argument
The filtered set of discrete candidates was fetched once and then passed as a parallel candidates_exp dataframe through several layers of the recommender stack (_recommend_recommend_discrete/hybrid → BoTorch-specific helpers). With safe subspace mutation now available, subset-constrained paths are updated to create filtered copies of the subspace instead of propagating a separate dataframe. The argument is removed from all affected signatures across:

  • PureRecommender._recommend_discrete / _recommend_hybrid
  • BotorchRecommender._recommend_discrete / _recommend_hybrid
  • recommend_discrete_with_subsets / recommend_discrete_without_subsets
  • recommend_hybrid_with_subsets / recommend_hybrid_without_subsets
  • SKLearnClusteringRecommender._recommend_discrete
  • FPSRecommender._recommend_discrete
  • RandomRecommender._recommend_hybrid
  • NaiveHybridSpaceRecommender

@AdrianSosic AdrianSosic added this to the 0.16.0 milestone Jun 23, 2026
@AdrianSosic AdrianSosic self-assigned this Jun 23, 2026
@AdrianSosic AdrianSosic changed the base branch from main to dev/candidates June 23, 2026 20:16
@AdrianSosic AdrianSosic marked this pull request as ready for review June 23, 2026 20:22
Copilot AI review requested due to automatic review settings June 23, 2026 20:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Refactors internal recommendation plumbing to remove redundant discrete-candidate threading now that SubspaceDiscrete can be safely copied in a filtered form, simplifying the recommender call stack.

Changes:

  • Removes FilteredSubspaceDiscrete and switches Campaign to create filtered subspace copies directly.
  • Drops dead pending_experiments plumbing into _recommend_with_discrete_parts and removes redundant candidates_exp parameters across multiple recommenders/helpers.
  • Updates BoTorch/non-predictive recommenders to consume candidates via subspace_discrete.exp_rep / .comp_rep directly.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
CHANGELOG.md Notes the internal simplification/refactor.
baybe/searchspace/_filtered.py Deletes FilteredSubspaceDiscrete (no longer needed).
baybe/campaign.py Builds filtered discrete subspaces via attrs.evolve(..., exp_rep=...) instead of a special subclass.
baybe/recommenders/pure/base.py Removes unused pending_experiments arg and stops threading candidates_exp.
baybe/recommenders/pure/bayesian/botorch/core.py Updates dispatch to new helper signatures without candidates_exp.
baybe/recommenders/pure/bayesian/botorch/discrete.py Switches subset handling to evolve-created filtered subspaces.
baybe/recommenders/pure/bayesian/botorch/hybrid.py Removes candidates_exp plumbing and relies on the (possibly filtered) discrete subspace.
baybe/recommenders/pure/nonpredictive/sampling.py Uses searchspace.discrete.exp_rep / subspace_discrete.exp_rep directly.
baybe/recommenders/pure/nonpredictive/clustering.py Uses subspace_discrete.exp_rep / .comp_rep directly.
baybe/recommenders/naive.py Stops building/passing separate discrete candidate frames into _recommend_discrete.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread baybe/recommenders/pure/bayesian/botorch/hybrid.py Outdated
@AdrianSosic AdrianSosic mentioned this pull request Jun 23, 2026
5 tasks
Comment thread baybe/recommenders/pure/base.py
Comment thread baybe/recommenders/pure/base.py
Comment thread baybe/recommenders/pure/base.py
Comment thread baybe/campaign.py
Comment thread baybe/recommenders/pure/base.py

@AVHopp AVHopp left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Two minor comments, but LGTM

Comment thread baybe/recommenders/pure/bayesian/botorch/hybrid.py Outdated
Comment thread baybe/recommenders/pure/nonpredictive/sampling.py
@AdrianSosic AdrianSosic merged commit 7ad1cec into dev/candidates Jun 25, 2026
9 of 13 checks passed
@AdrianSosic AdrianSosic deleted the refactor/recommendation_mechanics branch June 25, 2026 10:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants