blackboxopt.utils
filter_pareto_efficient(evaluations, objectives)
Filter pareto efficient evaluations with respect to given objectives.
Source code in blackboxopt/utils.py
def filter_pareto_efficient(
evaluations: List[Evaluation], objectives: List[Objective]
) -> List[Evaluation]:
"""Filter pareto efficient evaluations with respect to given objectives."""
losses = np.array(
[
get_loss_vector(
known_objectives=objectives, reported_objectives=e.objectives
)
for e in evaluations
]
)
pareto_efficient_mask = mask_pareto_efficient(losses)
return list(compress(evaluations, pareto_efficient_mask))
get_loss_vector(known_objectives, reported_objectives, none_replacement=nan)
Convert reported objectives into a vector of known objectives.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
known_objectives |
Sequence[blackboxopt.base.Objective] |
A sequence of objectives with names and directions (whether greate is better). The order of the objectives dictates the order of the returned loss values. |
required |
reported_objectives |
Dict[str, Optional[float]] |
A dictionary with the objective value for each of the known objectives' names. |
required |
none_replacement |
float |
The value to use for missing objective values that are |
nan |
Returns:
Type | Description |
---|---|
List[float] |
A list of loss values. |
Source code in blackboxopt/utils.py
def get_loss_vector(
known_objectives: Sequence[Objective],
reported_objectives: Dict[str, Optional[float]],
none_replacement: float = float("NaN"),
) -> List[float]:
"""Convert reported objectives into a vector of known objectives.
Args:
known_objectives: A sequence of objectives with names and directions
(whether greate is better). The order of the objectives dictates the order
of the returned loss values.
reported_objectives: A dictionary with the objective value for each of the known
objectives' names.
none_replacement: The value to use for missing objective values that are `None`
Returns:
A list of loss values.
"""
losses = []
for objective in known_objectives:
objective_value = reported_objectives[objective.name]
if objective_value is None:
losses.append(none_replacement)
elif objective.greater_is_better:
losses.append(-1.0 * objective_value)
else:
losses.append(objective_value)
return losses
init_logger(level=None)
Initialize the default blackboxopt.logger
as a nicely formatted stdout logger.
Should no log level be given, the environment variable BBO_LOG_LEVEL
is used
and if that is not present, the default is logging.DEBUG
.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
level |
int |
the log level to set |
None |
Returns:
Type | Description |
---|---|
Logger |
The logger instance (equivalent to |
Source code in blackboxopt/utils.py
def init_logger(level: int = None) -> logging.Logger: # pragma: no cover
"""Initialize the default `blackboxopt.logger` as a nicely formatted stdout logger.
Should no log level be given, the environment variable `BBO_LOG_LEVEL` is used
and if that is not present, the default is `logging.DEBUG`.
Args:
level: the log level to set
Returns:
The logger instance (equivalent to `blackboxopt.logger`)
"""
if level is None:
level_name = os.environ.get("BBO_LOG_LEVEL", "DEBUG")
level = getattr(logging, level_name)
logger.setLevel(level)
handler = logging.StreamHandler(sys.stdout)
handler.setLevel(level)
formatter = logging.Formatter(
"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger
mask_pareto_efficient(losses)
For a given array of objective values where lower values are considered better
and the dimensions are samples x objectives, return a mask that is True
for all
pareto efficient values.
NOTE: The result marks multiple occurrences of the same point all as pareto efficient.
Source code in blackboxopt/utils.py
def mask_pareto_efficient(losses: np.ndarray):
"""For a given array of objective values where lower values are considered better
and the dimensions are samples x objectives, return a mask that is `True` for all
pareto efficient values.
NOTE: The result marks multiple occurrences of the same point all as pareto
efficient.
"""
is_efficient = np.ones(losses.shape[0], dtype=bool)
for i, c in enumerate(losses):
if not is_efficient[i]:
continue
# Keep any point with a lower cost or when they are the same
efficient = np.any(losses[is_efficient] < c, axis=1)
duplicates = np.all(losses[is_efficient] == c, axis=1)
is_efficient[is_efficient] = np.logical_or(efficient, duplicates)
return is_efficient