Skip to content

Commit

Permalink
Refactoring of DoEStrategy data model class (#448)
Browse files Browse the repository at this point in the history
* add draft of restrucuted doe class

* refactoring doe

* add formulaic to be installed always

* add formulaic to be installed always

* add formulaic to be installed always

* add formulaic to be installed always

* check style

* check style

* check style

* remove enumns

* remove enumns

* remove enumns

* fix branch and bound

* move delta into criterion

* move delta into criterion

* move delta into criterion

* move delta into criterion

* move default criterion

* move default criterion

* move default criterion

* move default criterion

* refactor formulas and number of experiments

* pyright

* fix test

* fix test

* fix test

* fix tutorial

* fix tutorial

* fix tutorial

* fix test

* fix test

* fix getting started

* aarons review

* rmv unneded tests

* formulaic version fixed bc of breaking changes

* add explanatory text to doe basic examples

* typo in basic_examples.ipynb

* format basic doe example

* consolidate spac_filling with doe

* Add categoricals for `FractionalFactorialStrategy` (#480)

* integrate factorial in fractional factorial

* fix tests

* merge main

* Multiplicative additive sobo objectives (#481)

* added MultiplicativeAdditive data model

* added actual multiplicative model (callable is missing)

* added torch functions

* added test for objective

* added test for sobo stategy: multiplicative_additive

* changed additive/multiplicative calculations:
- Removed scaling by x**(1/(....)) to avoid numerical errors, if x<0
- included weight transformation for multiplicative objectives from (0, 1] to [1, inf) scale to avoid numerical errors at weights != 1.0
- added tests for weights != 1.0

* added notebook for comparison of merging objectives

* after hooks

* addet .idea/ folder (pycharm) to gitignore

* after hooks

* Apply pre-commit fixes

* Delete .idea directory

* corrected tests for multiplicative_additive_botorch_objective

* after pre-commit

* lint specifications

* corrected weightings calc in test for multiplicative objective

* after hooks

* changed docstrings to google docstring format

* easy fixes, spelling errors

* forgot linting

* easy fixes, spelling errors

* removed denominator additive from multiplicative_additive_sobo strategy

* after hooks

* fixed typing

* tensor initialization of objectives

* after hooks

* avoiding torch size error

* avoid linting error

* after hooks

* reverting test-renaming

* revert isinstance list comprehension to tuple.... solution

* testing copilot suggestions for linting errors

* reverting wrong copilot suggestions

* added test for _callables_and_weights

* after hooks

* added test for SOBO strategy data model

* added test for SOBO strategy data model

* added new sobo strategy to a mysterious list

* after hooks

* still trying to get rid of the linting error, expecting tuple(types)

* WIP

* WIP

* WIP

* WIP

* WIP

* minor corrections

* add pbar support for hyperopt (#494)

* Make the BoFire Data Models OpenAI compatible (#495)

* tuples to lists

* fix tests

* fix linting issues

* Group split kfold (#484)

* add group kfold option in cross_validate of any traainable surrogate

* changed to GroupShuffleSplit, added test case

* improve docstring & add some inline comments in test

* refactor cross_validate & add tests

* imrpve tests, remove unnecessary case while checking group split col

* add push

* formatting

---------

Co-authored-by: Jim Boelrijk Valcon <jimboelrijk1@MacBook-Pro-van-Jim.local>

* fix strict candidate enforcement (#492)

* Drop support for Python 3.9 (#493)

* update tests and pyproject.toml

* update lint workflow

* update test

* bump pyright

* different pyright version

* change linting

* Update pyproject.toml (#501)

BoTorch is slowed down massively by scipy 1.15: pytorch/botorch#2668. We should fix it.

* kernels working on a given set of features (#476)

* kernels working on a given set of features

* pre-commit

* test map singletaskgp with additive kernel

* test active_dims of mapped kernels

* add features_to_idx_mapper to outlier detection tutorial

* correctly handling categorical mol features

* validating mol features transforms

* verifying proper type

* custom hamming kernel enabling single task gp on categorical features

* removed unnecessary parameter from data model

* testing equivalence of mixed gp and single gp with custom kernel

* (temporary) running on all py versions

* (temporary) debug github actions by printing

* more printing

* Revert "testing equivalence of mixed gp and single gp with custom kernel"

This reverts commit 4a2a547.

* Revert "removed unnecessary parameter from data model"

This reverts commit 6ad1dfd.

* Revert "custom hamming kernel enabling single task gp on categorical features"

This reverts commit 17d8350.

* Revert "Revert "custom hamming kernel enabling single task gp on categorical features""

This reverts commit 2e29852.

* Revert "Revert "testing equivalence of mixed gp and single gp with custom kernel""

This reverts commit 1cd2776.

* removed test debug and restored to latest implemented features

* pinning compatible version of formulaic

* pinning compatible version of formulaic

* removed old code

* lint

* removed scratch file

* removed old code again

* silencing pyright false positive

* compatibility with py39

* pin compatible version of formulaic

* restored old code

* pinning sklearn

* pinning sklearn

* pinning scikit everywhere

* not testing for prediction quality

* matching lengthscale constraints in hamming kernel

* removed equivalence test

* testing hamming kernel

* added test for mol features in single task gp

* categorical onehot kernel uses the right lengthscale for multiple features

* removed redundant check

* more descriptive name for base kernel

* updated docstring

* improved tests and comments

---------

Co-authored-by: Robert Lee <84771576+R-M-Lee@users.noreply.github.com>

* Fix mapper tests (#502)

* fix kernel mapper tests

* bump botorch dependency

* rmv unused import in staregies.api

* rmv unused import in space filling

* rmv unused import in space filling

* fix data models tets

* fix data models tets

* fix data models tets

* fix data models tets

* fix data models tets

* no more bnb in test

* add fixtures for criteria

* add fixtures for criteria

---------

Co-authored-by: LinzneDD_basf <dominik.linzner@basf.com>
Co-authored-by: Dominik Linzner <44400328+dlinzner-bcs@users.noreply.github.com>
Co-authored-by: linznedd <linznedd@basfad.basf.net>
Co-authored-by: Robert Lee <84771576+R-M-Lee@users.noreply.github.com>
Co-authored-by: Lukas Hebing <92095234+LukasHebing@users.noreply.github.com>
Co-authored-by: Julian Keupp <28810427+jkeupp@users.noreply.github.com>
Co-authored-by: Jim Boelrijk Valcon <jimboelrijk1@MacBook-Pro-van-Jim.local>
Co-authored-by: Emilio Dorigatti <emilio.dorigatti@gmail.com>
  • Loading branch information
9 people authored Jan 28, 2025
1 parent 4d6d6c6 commit ac38bcc
Show file tree
Hide file tree
Showing 25 changed files with 1,685 additions and 962 deletions.
2 changes: 0 additions & 2 deletions bofire/data_models/strategies/actual_strategy_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
)
from bofire.data_models.strategies.random import RandomStrategy
from bofire.data_models.strategies.shortest_path import ShortestPathStrategy
from bofire.data_models.strategies.space_filling import SpaceFillingStrategy


ActualStrategy = Union[
Expand All @@ -40,7 +39,6 @@
QnehviStrategy,
QparegoStrategy,
EntingStrategy,
SpaceFillingStrategy,
RandomStrategy,
DoEStrategy,
FactorialStrategy,
Expand Down
13 changes: 11 additions & 2 deletions bofire/data_models/strategies/api.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
from typing import Union

from bofire.data_models.strategies.actual_strategy_type import ActualStrategy
from bofire.data_models.strategies.doe import DoEStrategy
from bofire.data_models.strategies.doe import (
AnyDoEOptimalityCriterion,
AnyOptimalityCriterion,
AOptimalityCriterion,
DoEStrategy,
DOptimalityCriterion,
EOptimalityCriterion,
GOptimalityCriterion,
KOptimalityCriterion,
SpaceFillingCriterion,
)
from bofire.data_models.strategies.factorial import FactorialStrategy
from bofire.data_models.strategies.fractional_factorial import (
FractionalFactorialStrategy,
Expand Down Expand Up @@ -32,7 +42,6 @@
)
from bofire.data_models.strategies.random import RandomStrategy
from bofire.data_models.strategies.shortest_path import ShortestPathStrategy
from bofire.data_models.strategies.space_filling import SpaceFillingStrategy
from bofire.data_models.strategies.stepwise.conditions import (
AlwaysTrueCondition,
AnyCondition,
Expand Down
102 changes: 87 additions & 15 deletions bofire/data_models/strategies/doe.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,99 @@
from typing import Literal, Optional, Type, Union
from typing import Annotated, Dict, Literal, Optional, Type, Union

from formulaic import Formula
from formulaic.errors import FormulaSyntaxError
from pydantic import Field, field_validator

from bofire.data_models.base import BaseModel
from bofire.data_models.constraints.api import Constraint
from bofire.data_models.features.api import Feature, MolecularInput
from bofire.data_models.objectives.api import Objective
from bofire.data_models.strategies.strategy import Strategy
from bofire.data_models.types import Bounds
from bofire.strategies.enum import OptimalityCriterionEnum


class DoEStrategy(Strategy):
type: Literal["DoEStrategy"] = "DoEStrategy"
PREDEFINED_MODEL_TYPES = Literal[
"linear",
"linear-and-quadratic",
"linear-and-interactions",
"fully-quadratic",
]


class OptimalityCriterion(BaseModel):
type: str
delta: float = 1e-6
transform_range: Optional[Bounds] = None


class SpaceFillingCriterion(OptimalityCriterion):
type: Literal["SpaceFillingCriterion"] = "SpaceFillingCriterion" # type: ignore
sampling_fraction: Annotated[float, Field(gt=0, lt=1)] = 0.3


class DoEOptimalityCriterion(OptimalityCriterion):
type: str
formula: Union[
Literal[
"linear",
"linear-and-quadratic",
"linear-and-interactions",
"fully-quadratic",
],
PREDEFINED_MODEL_TYPES,
str,
]
"""
model_type (str, Formula): keyword or formulaic Formula describing the model. Known keywords
are "linear", "linear-and-interactions", "linear-and-quadratic", "fully-quadratic".
"""

@field_validator("formula")
@classmethod
def validate_formula(cls, formula: str) -> str:
if formula not in PREDEFINED_MODEL_TYPES.__args__: # type: ignore
# check that it is a valid formula
try:
Formula(formula)
except FormulaSyntaxError:
raise ValueError(f"Invalid formula: {formula}")
return formula


class DOptimalityCriterion(DoEOptimalityCriterion):
type: Literal["DOptimalityCriterion"] = "DOptimalityCriterion" # type: ignore


class EOptimalityCriterion(DoEOptimalityCriterion):
type: Literal["EOptimalityCriterion"] = "EOptimalityCriterion" # type: ignore


class AOptimalityCriterion(DoEOptimalityCriterion):
type: Literal["AOptimalityCriterion"] = "AOptimalityCriterion" # type: ignore


class GOptimalityCriterion(DoEOptimalityCriterion):
type: Literal["GOptimalityCriterion"] = "GOptimalityCriterion" # type: ignore


class KOptimalityCriterion(DoEOptimalityCriterion):
type: Literal["KOptimalityCriterion"] = "KOptimalityCriterion" # type: ignore


AnyDoEOptimalityCriterion = Union[
KOptimalityCriterion,
GOptimalityCriterion,
AOptimalityCriterion,
EOptimalityCriterion,
DOptimalityCriterion,
]

AnyOptimalityCriterion = Union[
AnyDoEOptimalityCriterion,
SpaceFillingCriterion,
]


class DoEStrategy(Strategy):
type: Literal["DoEStrategy"] = "DoEStrategy" # type: ignore

criterion: AnyOptimalityCriterion = Field(
default_factory=lambda: DOptimalityCriterion(formula="fully-quadratic")
)
optimization_strategy: Literal[
"default",
"exhaustive",
Expand All @@ -28,11 +103,8 @@ class DoEStrategy(Strategy):
"iterative",
] = "default"

verbose: bool = False

objective: OptimalityCriterionEnum = OptimalityCriterionEnum.D_OPTIMALITY

transform_range: Optional[Bounds] = None
verbose: bool = False # get rid of this at a later stage
ipopt_options: Optional[Dict] = None

@classmethod
def is_constraint_implemented(cls, my_type: Type[Constraint]) -> bool:
Expand Down
52 changes: 0 additions & 52 deletions bofire/data_models/strategies/space_filling.py

This file was deleted.

1 change: 0 additions & 1 deletion bofire/strategies/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,5 @@
)
from bofire.strategies.random import RandomStrategy
from bofire.strategies.shortest_path import ShortestPathStrategy
from bofire.strategies.space_filling import SpaceFillingStrategy
from bofire.strategies.stepwise.stepwise import StepwiseStrategy
from bofire.strategies.strategy import Strategy
Loading

0 comments on commit ac38bcc

Please sign in to comment.