From ebb4c3fc318dc225f22dfac1d79636d0dba552e4 Mon Sep 17 00:00:00 2001 From: Jakob Richter Date: Tue, 23 Oct 2018 10:42:43 +0200 Subject: [PATCH 1/8] add probability of improvement --- R/infill_crits.R | 41 ++++++++++++++++++++++++++----- R/zzz.R | 7 ++++++ tests/testthat/test_infillcrits.R | 2 +- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/R/infill_crits.R b/R/infill_crits.R index 593ff2d23..217997e4f 100644 --- a/R/infill_crits.R +++ b/R/infill_crits.R @@ -81,7 +81,6 @@ makeMBOInfillCritStandardError = function() { #' @rdname infillcrits makeMBOInfillCritEI = function(se.threshold = 1e-6) { assertNumber(se.threshold, lower = 1e-20) - force(se.threshold) makeMBOInfillCrit( fun = function(points, models, control, par.set, designs, iter, progress, attributes = FALSE) { model = models[[1L]] @@ -93,12 +92,9 @@ makeMBOInfillCritEI = function(se.threshold = 1e-6) { p = predict(model, newdata = points)$data p.mu = maximize.mult * p$response p.se = p$se - y.min = min(y) - d = y.min - p.mu + d = min(y) - p.mu xcr = d / p.se - xcr.prob = pnorm(xcr) - xcr.dens = dnorm(xcr) - ei = d * xcr.prob + p.se * xcr.dens + ei = d * pnorm(xcr) + p.se * dnorm(xcr) res = ifelse(p.se < se.threshold, 0, -ei) if (attributes) { res = setAttribute(res, "crit.components", data.frame(se = p$se, mean = p$response)) @@ -114,6 +110,39 @@ makeMBOInfillCritEI = function(se.threshold = 1e-6) { ) } +#' @export +#' @rdname infillcrits +makeMBOInfillCritPOI = function(se.threshold = 1e-6, epsilon = 0) { + assertNumber(se.threshold, lower = 1e-20) + makeMBOInfillCrit( + fun = function(points, models, control, par.set, designs, iter, progress, attributes = FALSE) { + model = models[[1L]] + design = designs[[1]] + maximize.mult = if (control$minimize) 1 else -1 + assertString(control$y.name) + y = maximize.mult * design[, control$y.name] + assertNumeric(y, any.missing = FALSE) + p = predict(model, newdata = points)$data + p.mu = maximize.mult * p$response + p.se = p$se + d = min(y) - p.mu + xcr = d / p.se + poi = pnorm(xcr) + res = ifelse(p.se < se.threshold, 0, -poi) + if (attributes) { + res = setAttribute(res, "crit.components", data.frame(se = p$se, mean = p$response)) + } + return(res) + }, + name = "Probability of improvement", + id = "poi", + components = c("se", "mean"), + params = list(se.threshold = se.threshold), + opt.direction = "maximize", + requires.se = TRUE + ) +} + #' @export #' @rdname infillcrits makeMBOInfillCritCB = function(cb.lambda = NULL) { diff --git a/R/zzz.R b/R/zzz.R index 117fe1039..108aa9367 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -96,3 +96,10 @@ crit.eqi = makeMBOInfillCritEQI() #' @format NULL #' @keywords NULL crit.dib1 = makeMBOInfillCritDIB(cb.lambda = 1) +#' @rdname MBOInfillCrit +#' @export +#' @usage NULL +#' @docType NULL +#' @format NULL +#' @keywords NULL +crit.ei = makeMBOInfillCritPOI() diff --git a/tests/testthat/test_infillcrits.R b/tests/testthat/test_infillcrits.R index 99531250b..485e0cf7a 100644 --- a/tests/testthat/test_infillcrits.R +++ b/tests/testthat/test_infillcrits.R @@ -65,7 +65,7 @@ test_that("infill crits", { # we have converged and just waste time. we need to detect this somehow, or cope with it for (noisy in c(TRUE, FALSE)) { for (minimize in c(TRUE, FALSE)) { - crits = if (noisy) list(crit.aei, crit.eqi) else list(crit.mr, crit.se, crit.ei, crit.cb2) + crits = if (noisy) list(crit.aei, crit.eqi) else list(crit.mr, crit.se, crit.ei, crit.cb2, crit.poi) for (lrn in learners) { if (inherits(lrn, "regr.km")) lrn = setHyperPars(lrn, nugget.estim = noisy) From 562824e09b48b3fef2973f6d9de56438d0f0f627 Mon Sep 17 00:00:00 2001 From: Jakob Richter Date: Mon, 5 Nov 2018 15:40:18 +0100 Subject: [PATCH 2/8] fix --- NAMESPACE | 62 ------------------------------- R/zzz.R | 2 +- man/infillcrits.Rd | 3 ++ man/makeMBOControl.Rd | 9 +++-- man/plotMBOResult.Rd | 8 ++-- man/renderExampleRunPlot.Rd | 4 +- man/setMBOControlInfill.Rd | 11 ++++-- man/setMBOControlMultiObj.Rd | 1 + man/setMBOControlMultiPoint.Rd | 8 ++-- man/setMBOControlTermination.Rd | 1 + tests/testthat/test_infillcrits.R | 2 + 11 files changed, 31 insertions(+), 80 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 390bc12d5..fb2d58063 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,67 +1,5 @@ # Generated by roxygen2: do not edit by hand -S3method(initCrit,InfillCritAdaCB) -S3method(initCrit,InfillCritCB) -S3method(initCrit,default) -S3method(plot,MBOMultiObjResult) -S3method(plot,MBOSingleObjResult) -S3method(plot,OptState) -S3method(print,MBOControl) -S3method(print,MBOExampleRun) -S3method(print,MBOExampleRunMultiObj) -S3method(print,MBOInfillCrit) -S3method(print,MBOMultiObjResult) -S3method(print,MBOResult) -S3method(renderExampleRunPlot,MBOExampleRun) -S3method(renderExampleRunPlot,MBOExampleRunMultiObj) -export(crit.aei) -export(crit.cb) -export(crit.cb1) -export(crit.cb2) -export(crit.dib1) -export(crit.ei) -export(crit.eqi) -export(crit.mr) -export(crit.se) -export(exampleRun) -export(exampleRunMultiObj) -export(finalizeSMBO) -export(getGlobalOpt) -export(getMBOInfillCritComponents) -export(getMBOInfillCritId) -export(getMBOInfillCritName) -export(getMBOInfillCritParam) -export(getMBOInfillCritParams) -export(getSupportedInfillOptFunctions) -export(getSupportedMultipointInfillOptFunctions) -export(hasRequiresInfillCritStandardError) -export(initCrit) -export(initSMBO) -export(makeMBOControl) -export(makeMBOInfillCrit) -export(makeMBOInfillCritAEI) -export(makeMBOInfillCritAdaCB) -export(makeMBOInfillCritCB) -export(makeMBOInfillCritDIB) -export(makeMBOInfillCritEI) -export(makeMBOInfillCritEQI) -export(makeMBOInfillCritMeanResponse) -export(makeMBOInfillCritStandardError) -export(makeMBOLearner) -export(makeMBOTrafoFunction) -export(mbo) -export(mboContinue) -export(mboFinalize) -export(plotExampleRun) -export(proposePoints) -export(renderExampleRunPlot) -export(setMBOControlInfill) -export(setMBOControlMultiObj) -export(setMBOControlMultiPoint) -export(setMBOControlTermination) -export(trafoLog) -export(trafoSqrt) -export(updateSMBO) import(BBmisc) import(ParamHelpers) import(checkmate) diff --git a/R/zzz.R b/R/zzz.R index 108aa9367..ced68f219 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -102,4 +102,4 @@ crit.dib1 = makeMBOInfillCritDIB(cb.lambda = 1) #' @docType NULL #' @format NULL #' @keywords NULL -crit.ei = makeMBOInfillCritPOI() +crit.poi = makeMBOInfillCritPOI() diff --git a/man/infillcrits.Rd b/man/infillcrits.Rd index e2e7e3f83..c2a4a41fd 100644 --- a/man/infillcrits.Rd +++ b/man/infillcrits.Rd @@ -5,6 +5,7 @@ \alias{makeMBOInfillCritMeanResponse} \alias{makeMBOInfillCritStandardError} \alias{makeMBOInfillCritEI} +\alias{makeMBOInfillCritPOI} \alias{makeMBOInfillCritCB} \alias{makeMBOInfillCritAEI} \alias{makeMBOInfillCritEQI} @@ -18,6 +19,8 @@ makeMBOInfillCritStandardError() makeMBOInfillCritEI(se.threshold = 1e-06) +makeMBOInfillCritPOI(se.threshold = 1e-06, epsilon = 0) + makeMBOInfillCritCB(cb.lambda = NULL) makeMBOInfillCritAEI(aei.use.nugget = FALSE, se.threshold = 1e-06) diff --git a/man/makeMBOControl.Rd b/man/makeMBOControl.Rd index 55847a818..fba5d9e2f 100644 --- a/man/makeMBOControl.Rd +++ b/man/makeMBOControl.Rd @@ -7,10 +7,10 @@ \usage{ makeMBOControl(n.objectives = 1L, propose.points = 1L, final.method = "best.true.y", final.evals = 0L, y.name = "y", - impute.y.fun = NULL, trafo.y.fun = NULL, suppress.eval.errors = TRUE, - save.on.disk.at = integer(0L), save.on.disk.at.time = Inf, - save.file.path = file.path(getwd(), "mlr_run.RData"), - store.model.at = NULL, resample.at = integer(0), + impute.y.fun = NULL, trafo.y.fun = NULL, + suppress.eval.errors = TRUE, save.on.disk.at = integer(0L), + save.on.disk.at.time = Inf, save.file.path = file.path(getwd(), + "mlr_run.RData"), store.model.at = NULL, resample.at = integer(0), resample.desc = makeResampleDesc("CV", iter = 10), resample.measures = list(mse), output.num.format = "\%.3g", on.surrogate.error = "stop") @@ -122,3 +122,4 @@ Other MBOControl: \code{\link{setMBOControlInfill}}, \code{\link{setMBOControlMultiPoint}}, \code{\link{setMBOControlTermination}} } +\concept{MBOControl} diff --git a/man/plotMBOResult.Rd b/man/plotMBOResult.Rd index 54d88ea4b..30c679486 100644 --- a/man/plotMBOResult.Rd +++ b/man/plotMBOResult.Rd @@ -6,11 +6,11 @@ \alias{plot.MBOMultiObjResult} \title{MBO Result Plotting} \usage{ -\method{plot}{MBOSingleObjResult}(x, iters = NULL, pause = interactive(), - ...) +\method{plot}{MBOSingleObjResult}(x, iters = NULL, + pause = interactive(), ...) -\method{plot}{MBOMultiObjResult}(x, iters = NULL, pause = interactive(), - ...) +\method{plot}{MBOMultiObjResult}(x, iters = NULL, + pause = interactive(), ...) } \arguments{ \item{x}{[\code{MBOResult}]\cr diff --git a/man/renderExampleRunPlot.Rd b/man/renderExampleRunPlot.Rd index de888f594..c368bf75f 100644 --- a/man/renderExampleRunPlot.Rd +++ b/man/renderExampleRunPlot.Rd @@ -7,8 +7,8 @@ exampleRunMultiObj objects.} \usage{ renderExampleRunPlot(object, iter, densregion = TRUE, se.factor = 1, single.prop.point.plots = FALSE, xlim = NULL, ylim = NULL, - point.size = 3, line.size = 1, trafo = NULL, colors = c("red", "blue", - "green"), ...) + point.size = 3, line.size = 1, trafo = NULL, colors = c("red", + "blue", "green"), ...) } \arguments{ \item{object}{[\code{function}]\cr diff --git a/man/setMBOControlInfill.Rd b/man/setMBOControlInfill.Rd index b6ccc585a..fd2cab721 100644 --- a/man/setMBOControlInfill.Rd +++ b/man/setMBOControlInfill.Rd @@ -4,15 +4,17 @@ \alias{setMBOControlInfill} \title{Extends mbo control object with infill criteria and infill optimizer options.} \usage{ -setMBOControlInfill(control, crit = NULL, interleave.random.points = 0L, - filter.proposed.points = NULL, filter.proposed.points.tol = NULL, - opt = "focussearch", opt.restarts = NULL, opt.focussearch.maxit = NULL, +setMBOControlInfill(control, crit = NULL, + interleave.random.points = 0L, filter.proposed.points = NULL, + filter.proposed.points.tol = NULL, opt = "focussearch", + opt.restarts = NULL, opt.focussearch.maxit = NULL, opt.focussearch.points = NULL, opt.cmaes.control = NULL, opt.ea.maxit = NULL, opt.ea.mu = NULL, opt.ea.sbx.eta = NULL, opt.ea.sbx.p = NULL, opt.ea.pm.eta = NULL, opt.ea.pm.p = NULL, opt.ea.lambda = NULL, opt.nsga2.popsize = NULL, opt.nsga2.generations = NULL, opt.nsga2.cprob = NULL, - opt.nsga2.cdist = NULL, opt.nsga2.mprob = NULL, opt.nsga2.mdist = NULL) + opt.nsga2.cdist = NULL, opt.nsga2.mprob = NULL, + opt.nsga2.mdist = NULL) } \arguments{ \item{control}{[\code{\link{MBOControl}}]\cr @@ -158,3 +160,4 @@ Other MBOControl: \code{\link{makeMBOControl}}, \code{\link{setMBOControlMultiPoint}}, \code{\link{setMBOControlTermination}} } +\concept{MBOControl} diff --git a/man/setMBOControlMultiObj.Rd b/man/setMBOControlMultiObj.Rd index 4dfba869b..dd2514f69 100644 --- a/man/setMBOControlMultiObj.Rd +++ b/man/setMBOControlMultiObj.Rd @@ -121,3 +121,4 @@ Other MBOControl: \code{\link{makeMBOControl}}, \code{\link{setMBOControlMultiPoint}}, \code{\link{setMBOControlTermination}} } +\concept{MBOControl} diff --git a/man/setMBOControlMultiPoint.Rd b/man/setMBOControlMultiPoint.Rd index d939eb10f..82620f61f 100644 --- a/man/setMBOControlMultiPoint.Rd +++ b/man/setMBOControlMultiPoint.Rd @@ -5,9 +5,10 @@ \title{Set multipoint proposal options.} \usage{ setMBOControlMultiPoint(control, method = NULL, cl.lie = NULL, - moimbo.objective = NULL, moimbo.dist = NULL, moimbo.selection = NULL, - moimbo.maxit = NULL, moimbo.sbx.eta = NULL, moimbo.sbx.p = NULL, - moimbo.pm.eta = NULL, moimbo.pm.p = NULL) + moimbo.objective = NULL, moimbo.dist = NULL, + moimbo.selection = NULL, moimbo.maxit = NULL, + moimbo.sbx.eta = NULL, moimbo.sbx.p = NULL, moimbo.pm.eta = NULL, + moimbo.pm.p = NULL) } \arguments{ \item{control}{[\code{\link{MBOControl}}]\cr @@ -90,3 +91,4 @@ Other MBOControl: \code{\link{makeMBOControl}}, \code{\link{setMBOControlMultiObj}}, \code{\link{setMBOControlTermination}} } +\concept{MBOControl} diff --git a/man/setMBOControlTermination.Rd b/man/setMBOControlTermination.Rd index 1774144ae..9d31c4c30 100644 --- a/man/setMBOControlTermination.Rd +++ b/man/setMBOControlTermination.Rd @@ -85,3 +85,4 @@ Other MBOControl: \code{\link{makeMBOControl}}, \code{\link{setMBOControlMultiObj}}, \code{\link{setMBOControlMultiPoint}} } +\concept{MBOControl} diff --git a/tests/testthat/test_infillcrits.R b/tests/testthat/test_infillcrits.R index 485e0cf7a..78d3b4711 100644 --- a/tests/testthat/test_infillcrits.R +++ b/tests/testthat/test_infillcrits.R @@ -43,6 +43,8 @@ test_that("infill crits", { if (!is.null(opdf$infill_ei)) expect_true(!anyMissing(opdf$infill_ei[, c("ei","se","mean")])) + if (!is.null(opdf$infill_ei)) + expect_true(!anyMissing(opdf$infill_poi[, c("poi","se","mean")])) if (!is.null(opdf$infill_cb)) { expect_true(!anyMissing(opdf$infill_cb[, c("se","mean","lambda")])) expect_true(all(opdf$infill_cb$lambda == 2)) From e72beee5e7385d49ac9fe7347237ae8e0e70e64b Mon Sep 17 00:00:00 2001 From: Jakob Richter Date: Mon, 5 Nov 2018 16:25:18 +0100 Subject: [PATCH 3/8] mini fix --- R/infill_crits.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/infill_crits.R b/R/infill_crits.R index 217997e4f..ec5c732b5 100644 --- a/R/infill_crits.R +++ b/R/infill_crits.R @@ -112,7 +112,7 @@ makeMBOInfillCritEI = function(se.threshold = 1e-6) { #' @export #' @rdname infillcrits -makeMBOInfillCritPOI = function(se.threshold = 1e-6, epsilon = 0) { +makeMBOInfillCritPOI = function(se.threshold = 1e-6) { assertNumber(se.threshold, lower = 1e-20) makeMBOInfillCrit( fun = function(points, models, control, par.set, designs, iter, progress, attributes = FALSE) { From 2419d2af96e6716fd1e77dff9179413b2cf58085 Mon Sep 17 00:00:00 2001 From: Jakob Richter Date: Mon, 5 Nov 2018 16:59:41 +0100 Subject: [PATCH 4/8] update NAMESPACE --- NAMESPACE | 64 ++++++++++++++++++++++++++++++++++++++++++++ man/MBOInfillCrit.Rd | 1 + man/infillcrits.Rd | 2 +- 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/NAMESPACE b/NAMESPACE index fb2d58063..167a91621 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,5 +1,69 @@ # Generated by roxygen2: do not edit by hand +S3method(initCrit,InfillCritAdaCB) +S3method(initCrit,InfillCritCB) +S3method(initCrit,default) +S3method(plot,MBOMultiObjResult) +S3method(plot,MBOSingleObjResult) +S3method(plot,OptState) +S3method(print,MBOControl) +S3method(print,MBOExampleRun) +S3method(print,MBOExampleRunMultiObj) +S3method(print,MBOInfillCrit) +S3method(print,MBOMultiObjResult) +S3method(print,MBOResult) +S3method(renderExampleRunPlot,MBOExampleRun) +S3method(renderExampleRunPlot,MBOExampleRunMultiObj) +export(crit.aei) +export(crit.cb) +export(crit.cb1) +export(crit.cb2) +export(crit.dib1) +export(crit.ei) +export(crit.eqi) +export(crit.mr) +export(crit.poi) +export(crit.se) +export(exampleRun) +export(exampleRunMultiObj) +export(finalizeSMBO) +export(getGlobalOpt) +export(getMBOInfillCritComponents) +export(getMBOInfillCritId) +export(getMBOInfillCritName) +export(getMBOInfillCritParam) +export(getMBOInfillCritParams) +export(getSupportedInfillOptFunctions) +export(getSupportedMultipointInfillOptFunctions) +export(hasRequiresInfillCritStandardError) +export(initCrit) +export(initSMBO) +export(makeMBOControl) +export(makeMBOInfillCrit) +export(makeMBOInfillCritAEI) +export(makeMBOInfillCritAdaCB) +export(makeMBOInfillCritCB) +export(makeMBOInfillCritDIB) +export(makeMBOInfillCritEI) +export(makeMBOInfillCritEQI) +export(makeMBOInfillCritMeanResponse) +export(makeMBOInfillCritPOI) +export(makeMBOInfillCritStandardError) +export(makeMBOLearner) +export(makeMBOTrafoFunction) +export(mbo) +export(mboContinue) +export(mboFinalize) +export(plotExampleRun) +export(proposePoints) +export(renderExampleRunPlot) +export(setMBOControlInfill) +export(setMBOControlMultiObj) +export(setMBOControlMultiPoint) +export(setMBOControlTermination) +export(trafoLog) +export(trafoSqrt) +export(updateSMBO) import(BBmisc) import(ParamHelpers) import(checkmate) diff --git a/man/MBOInfillCrit.Rd b/man/MBOInfillCrit.Rd index b7b5dde1b..832924701 100644 --- a/man/MBOInfillCrit.Rd +++ b/man/MBOInfillCrit.Rd @@ -12,6 +12,7 @@ \alias{crit.aei} \alias{crit.eqi} \alias{crit.dib1} +\alias{crit.poi} \title{Create an infill criterion.} \usage{ makeMBOInfillCrit(fun, name, id, opt.direction = "minimize", diff --git a/man/infillcrits.Rd b/man/infillcrits.Rd index c2a4a41fd..fb76b34ba 100644 --- a/man/infillcrits.Rd +++ b/man/infillcrits.Rd @@ -19,7 +19,7 @@ makeMBOInfillCritStandardError() makeMBOInfillCritEI(se.threshold = 1e-06) -makeMBOInfillCritPOI(se.threshold = 1e-06, epsilon = 0) +makeMBOInfillCritPOI(se.threshold = 1e-06) makeMBOInfillCritCB(cb.lambda = NULL) From 93895c70bb806d0de076944eb44a92b9581b6e98 Mon Sep 17 00:00:00 2001 From: Jakob Richter Date: Tue, 26 Mar 2019 12:12:01 +0100 Subject: [PATCH 5/8] fix test --- tests/testthat/test_infillcrits.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test_infillcrits.R b/tests/testthat/test_infillcrits.R index 78d3b4711..e159641f3 100644 --- a/tests/testthat/test_infillcrits.R +++ b/tests/testthat/test_infillcrits.R @@ -43,7 +43,7 @@ test_that("infill crits", { if (!is.null(opdf$infill_ei)) expect_true(!anyMissing(opdf$infill_ei[, c("ei","se","mean")])) - if (!is.null(opdf$infill_ei)) + if (!is.null(opdf$infill_poi)) expect_true(!anyMissing(opdf$infill_poi[, c("poi","se","mean")])) if (!is.null(opdf$infill_cb)) { expect_true(!anyMissing(opdf$infill_cb[, c("se","mean","lambda")])) From c9094caba09ab69a4c11de2a4414ef3dc5b28ba1 Mon Sep 17 00:00:00 2001 From: Jakob Richter Date: Tue, 26 Mar 2019 14:12:59 +0100 Subject: [PATCH 6/8] add scaled expected improvement --- NAMESPACE | 2 ++ R/infill_crits.R | 48 +++++++++++++++++++++++++++---- R/zzz.R | 7 +++++ man/MBOInfillCrit.Rd | 1 + man/infillcrits.Rd | 3 ++ tests/testthat/test_infillcrits.R | 2 +- 6 files changed, 57 insertions(+), 6 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 167a91621..0bd8ca297 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -24,6 +24,7 @@ export(crit.eqi) export(crit.mr) export(crit.poi) export(crit.se) +export(crit.sei) export(exampleRun) export(exampleRunMultiObj) export(finalizeSMBO) @@ -48,6 +49,7 @@ export(makeMBOInfillCritEI) export(makeMBOInfillCritEQI) export(makeMBOInfillCritMeanResponse) export(makeMBOInfillCritPOI) +export(makeMBOInfillCritSEI) export(makeMBOInfillCritStandardError) export(makeMBOLearner) export(makeMBOTrafoFunction) diff --git a/R/infill_crits.R b/R/infill_crits.R index ec5c732b5..98f8da792 100644 --- a/R/infill_crits.R +++ b/R/infill_crits.R @@ -112,7 +112,11 @@ makeMBOInfillCritEI = function(se.threshold = 1e-6) { #' @export #' @rdname infillcrits -makeMBOInfillCritPOI = function(se.threshold = 1e-6) { +makeMBOInfillCritSEI = function(se.threshold = 1e-6) { + # On a New Improvement-Based Acquisition Function for Bayesian Optimization + # Noè et.al. 2018 + # http://arxiv.org/abs/1808.06918 + assertNumber(se.threshold, lower = 1e-20) makeMBOInfillCrit( fun = function(points, models, control, par.set, designs, iter, progress, attributes = FALSE) { @@ -124,11 +128,45 @@ makeMBOInfillCritPOI = function(se.threshold = 1e-6) { assertNumeric(y, any.missing = FALSE) p = predict(model, newdata = points)$data p.mu = maximize.mult * p$response - p.se = p$se + p.se = p$se #s(x) d = min(y) - p.mu - xcr = d / p.se - poi = pnorm(xcr) - res = ifelse(p.se < se.threshold, 0, -poi) + xcr = d / p.se #u(x) in paper + p.xcr = pnorm(xcr) + d.xcr = dnorm(xcr) + ei = d * p.xcr + p.se * d.xcr + vi = p.se^2 * ((xcr^2 + 1) * p.xcr + xcr * d.xcr) - ei^2 + sei = ei / sqrt(vi) + res = ifelse(p.se < se.threshold, 0, -sei) + if (attributes) { + res = setAttribute(res, "crit.components", data.frame(se = p$se, mean = p$response)) + } + return(res) + }, + name = "Scaled expected improvement", + id = "sei", + components = c("se", "mean"), + params = list(se.threshold = se.threshold), + opt.direction = "maximize", + requires.se = TRUE + ) +} + +#' @export +#' @rdname infillcrits +makeMBOInfillCritPOI = function(se.threshold = 1e-6) { + # https://www.cse.wustl.edu/~garnett/cse515t/spring_2015/files/lecture_notes/12.pdf + assertNumber(se.threshold, lower = 1e-20) + makeMBOInfillCrit( + fun = function(points, models, control, par.set, designs, iter, progress, attributes = FALSE) { + model = models[[1L]] + design = designs[[1]] + maximize.mult = if (control$minimize) 1 else -1 + assertString(control$y.name) + y = maximize.mult * design[, control$y.name] + assertNumeric(y, any.missing = FALSE) + p = predict(model, newdata = points)$data + poi = pnorm(min(y) , mean = maximize.mult * p$response, sd = p$se) + res = ifelse(p$se < se.threshold, 0, -poi) if (attributes) { res = setAttribute(res, "crit.components", data.frame(se = p$se, mean = p$response)) } diff --git a/R/zzz.R b/R/zzz.R index ced68f219..a7fae569a 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -103,3 +103,10 @@ crit.dib1 = makeMBOInfillCritDIB(cb.lambda = 1) #' @format NULL #' @keywords NULL crit.poi = makeMBOInfillCritPOI() +#' @rdname MBOInfillCrit +#' @export +#' @usage NULL +#' @docType NULL +#' @format NULL +#' @keywords NULL +crit.sei = makeMBOInfillCritSEI() diff --git a/man/MBOInfillCrit.Rd b/man/MBOInfillCrit.Rd index 832924701..a8931ecd4 100644 --- a/man/MBOInfillCrit.Rd +++ b/man/MBOInfillCrit.Rd @@ -13,6 +13,7 @@ \alias{crit.eqi} \alias{crit.dib1} \alias{crit.poi} +\alias{crit.sei} \title{Create an infill criterion.} \usage{ makeMBOInfillCrit(fun, name, id, opt.direction = "minimize", diff --git a/man/infillcrits.Rd b/man/infillcrits.Rd index fb76b34ba..d60e2b112 100644 --- a/man/infillcrits.Rd +++ b/man/infillcrits.Rd @@ -5,6 +5,7 @@ \alias{makeMBOInfillCritMeanResponse} \alias{makeMBOInfillCritStandardError} \alias{makeMBOInfillCritEI} +\alias{makeMBOInfillCritSEI} \alias{makeMBOInfillCritPOI} \alias{makeMBOInfillCritCB} \alias{makeMBOInfillCritAEI} @@ -19,6 +20,8 @@ makeMBOInfillCritStandardError() makeMBOInfillCritEI(se.threshold = 1e-06) +makeMBOInfillCritSEI(se.threshold = 1e-06) + makeMBOInfillCritPOI(se.threshold = 1e-06) makeMBOInfillCritCB(cb.lambda = NULL) diff --git a/tests/testthat/test_infillcrits.R b/tests/testthat/test_infillcrits.R index e159641f3..ac6427c02 100644 --- a/tests/testthat/test_infillcrits.R +++ b/tests/testthat/test_infillcrits.R @@ -67,7 +67,7 @@ test_that("infill crits", { # we have converged and just waste time. we need to detect this somehow, or cope with it for (noisy in c(TRUE, FALSE)) { for (minimize in c(TRUE, FALSE)) { - crits = if (noisy) list(crit.aei, crit.eqi) else list(crit.mr, crit.se, crit.ei, crit.cb2, crit.poi) + crits = if (noisy) list(crit.aei, crit.eqi) else list(crit.mr, crit.se, crit.ei, crit.cb2, crit.poi, crit.sei) for (lrn in learners) { if (inherits(lrn, "regr.km")) lrn = setHyperPars(lrn, nugget.estim = noisy) From 70517b49b00fe0cd2fc523e77513ec268fd14864 Mon Sep 17 00:00:00 2001 From: Jakob Richter Date: Tue, 26 Mar 2019 14:31:14 +0100 Subject: [PATCH 7/8] fix numerical problems --- R/infill_crits.R | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/R/infill_crits.R b/R/infill_crits.R index 98f8da792..63631511b 100644 --- a/R/infill_crits.R +++ b/R/infill_crits.R @@ -135,8 +135,9 @@ makeMBOInfillCritSEI = function(se.threshold = 1e-6) { d.xcr = dnorm(xcr) ei = d * p.xcr + p.se * d.xcr vi = p.se^2 * ((xcr^2 + 1) * p.xcr + xcr * d.xcr) - ei^2 + vi = pmax(0, vi) sei = ei / sqrt(vi) - res = ifelse(p.se < se.threshold, 0, -sei) + res = ifelse(p.se < se.threshold | is.infinite(sei) | is.nan(sei), 0, -sei) if (attributes) { res = setAttribute(res, "crit.components", data.frame(se = p$se, mean = p$response)) } From ebc4c0e792354791e991aff2fec6fb17059563c9 Mon Sep 17 00:00:00 2001 From: Jakob Richter Date: Wed, 12 Jun 2019 13:54:57 +0200 Subject: [PATCH 8/8] improve tests --- tests/testthat/test_infillcrits.R | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/testthat/test_infillcrits.R b/tests/testthat/test_infillcrits.R index ac6427c02..7aaf61320 100644 --- a/tests/testthat/test_infillcrits.R +++ b/tests/testthat/test_infillcrits.R @@ -43,16 +43,22 @@ test_that("infill crits", { if (!is.null(opdf$infill_ei)) expect_true(!anyMissing(opdf$infill_ei[, c("ei","se","mean")])) - if (!is.null(opdf$infill_poi)) - expect_true(!anyMissing(opdf$infill_poi[, c("poi","se","mean")])) if (!is.null(opdf$infill_cb)) { expect_true(!anyMissing(opdf$infill_cb[, c("se","mean","lambda")])) expect_true(all(opdf$infill_cb$lambda == 2)) } - if (!is.null(opdf$infill_aei)) + if (!is.null(opdf$infill_aei)) { expect_true(!anyMissing(opdf$infill_aei[, c("se","mean","tau")])) - if (!is.null(opdf$infill_eqi)) + } + if (!is.null(opdf$infill_eqi)) { expect_true(!anyMissing(opdf$infill_eqi[, c("se","mean","tau")])) + } + if (!is.null(opdf$infill_poi)) { + expect_true(!anyMissing(opdf$infill_poi[, c("poi","se","mean")])) + } + if (!is.null(opdf$infill_sei)) { + expect_true(!anyMissing(opdf$infill_poi[, c("sei","se","mean")])) + } expect_true(nrow(opdf$final_eval) == 10L) }