R/SMBO.R

Defines functions finalizeSMBO updateSMBO initSMBO

Documented in finalizeSMBO initSMBO updateSMBO

#' @title Initialize a manual sequential MBO run.
#' @description When you want to run a human-in-the-loop MBO run you need to initialize it first.
#'
#' @inheritParams mbo
#' @template arg_parset
#' @param minimize [\code{logical}]\cr
#'   Should objective values of the target functions be minimized? One value par objective.
#'   Default is \code{TRUE} for every objective.
#' @param noisy [\code{logical(1)}]\cr
#'   Is the target function noisy?
#'   Default is \code{FALSE}.
#'
#' @return [\code{\link{OptState}}]
#' @export
initSMBO = function(par.set, design, learner = NULL, control, minimize = rep(TRUE, control$n.objectives), noisy = FALSE, show.info = getOption("mlrMBO.show.info", TRUE)) {

  assertClass(par.set, "ParamSet")
  assertDataFrame(design)
  assertSetEqual(names(design), c(getParamIds(par.set, repeated = TRUE, with.nr = TRUE), control$y.name))
  assertFlag(noisy)
  assertLogical(minimize, any.missing = FALSE)

  control$minimize = minimize
  control$noisy = noisy
  if (control$n.objectives == 1) {
    dummy.fun = makeSingleObjectiveFunction(name = "human in the loop", fn = function(...) return(NA), par.set = par.set, minimize = control$minimize, noisy = control$noisy)
  } else {
    dummy.fun = makeMultiObjectiveFunction(name = "human in the loop", fn = function(...) NA, par.set = par.set, n.objectives = control$n.objectives, minimize = control$minimize, noisy = control$noisy)
  }

  if (control$final.evals > 0) {
    stop("Number of 'final.evals' has to be zero for SMBO.")
  }

  # assertions are done here:
  opt.problem = initOptProblem(fun = dummy.fun, design = design, learner = learner, control = control, show.info = show.info, more.args = list())
  opt.state = makeOptState(opt.problem)
  evalMBODesign.OptState(opt.state)
  finalizeMboLoop(opt.state)
  return(opt.state)
}

#' @title Updates SMBO with the new observations
#' @description After a function evaluation you want to update the \code{\link{OptState}} to get new proposals.
#'
#' @param opt.state [\code{\link{OptState}}]
#'   The optimization state.
#'   Generated by \code{\link{initSMBO}}, this function or an \code{\link{mbo}} run.
#' @param x [\code{data.frame}]
#'   Named x values.
#'   One row per set of x values.
#' @param y [\code{numeric|list}]
#'   Outcome of the optimization.
#'   For multiple results use a list.
#'   For a result of a multi-objective function use a numeric vector.
#'
#' @return [\code{\link{OptState}}]
#' @export
updateSMBO = function(opt.state, x, y) {
  opt.problem = getOptStateOptProblem(opt.state)
  opt.path = getOptStateOptPath(opt.state)
  control = getOptProblemControl(opt.problem)


  assertDataFrame(x)
  if (nrow(x) > 1 && !is.list(y)) {
    stopf("For a multi-point update y has to be a list.")
  }
  if (!is.list(y)) {
    y = list(y)
  }
  assertList(y, "numeric", len = nrow(x))
  assertNumeric(y[[1]], len = control$n.objectives)


  infill.values = control$infill.crit$fun(points = x, models = getOptStateModels(opt.state)[[1]], control = control, designs = getOptStateDesigns(opt.state), attributes = TRUE, iter = getOptStateLoop(opt.state), progress = getOptStateProgress(opt.state))

  prop = makeProposal(
    control = control,
    prop.points = x,
    prop.type = "manual",
    crit.vals = matrix(infill.values, ncol = 1L),
    crit.components = attr(infill.values, "crit.components"))

  extras = getExtras(n = nrow(prop$prop.points), prop = prop, train.time = 0, control = control)
  xs = dfRowsToList(prop$prop.points, getOptProblemParSet(getOptStateOptProblem(opt.state)))

  for (i in seq_along(xs)) {
    if (hasAttributes(y[[i]], "extras")) {
      user.extras = attr(y[[i]], "extras")
      y[[i]] = setAttribute(y[[i]], "extras", NULL)
      extras[[i]] = insert(extras[[i]], user.extras)
    }
    addOptPathEl(op = opt.path, x = xs[[i]], y = y[[i]], extra = extras[[i]], dob = opt.state$loop)
  }
  finalizeMboLoop(opt.state)
  invisible(opt.state)
}

#' @title Finalizes the SMBO Optimization
#' @description Returns the common mlrMBO result object.
#'
#' @param opt.state [\code{\link{OptState}}]
#'   The optimization state.
#'
#' @return [\code{\link{MBOSingleObjResult}} | \code{\link{MBOMultiObjResult}}]
#' @export
finalizeSMBO = function(opt.state) {
  mboFinalize2(opt.state)
}
mlr-org/mlrMBO documentation built on Oct. 13, 2022, 2:39 p.m.