-
-
Notifications
You must be signed in to change notification settings - Fork 47
/
Copy pathcheckStuff.R
143 lines (125 loc) · 6.92 KB
/
checkStuff.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# Helper to check whether the user selected valid options and combinations of options.
#
# @param fun [\code{function}]
# Objective fun
# @param par.set [\code{\link[ParamHelpers]{ParamSet}}]
# Collection of parameters and their constraints for optimization.
# @param design
# Sampling plan.
# @param learner [\code{\link[mlr]{Learner}}]
# Learner object.
# @param control [\code{\link{MBOControl}}]
# MBO control object.
checkStuff = function(fun, design, learner, control) {
assertFunction(fun)
if (!is.null(design))
assertClass(design, "data.frame")
assertClass(control, "MBOControl")
assertClass(learner, "Learner")
par.set = getParamSet(fun)
if (getNumberOfObjectives(fun) != control$n.objectives) {
stopf("Objective function has %i objectives, but the control object assumes %i.",
getNumberOfObjectives(fun), control$n.objectives)
}
# at the moment we do not support noisy multi-objective optimization
if (getNumberOfObjectives(fun) > 1L && isNoisy(fun)) {
stopf("Optimization of noisy multi-objective functions not supported in the moment.")
}
# final.method and final.evals have no effect on multi-objective optimization
if (getNumberOfObjectives(fun) > 1L &&
(control$final.method != "best.true.y" || control$final.evals > 0L)) {
stop("Setting of final.method and final.evals for multi-objective optimization not supported at the moment.")
}
# general parameter and learner checks
if (any(vlapply(par.set$pars, inherits, what = "LearnerParam")))
stop("No parameter can be of class 'LearnerParam'! Use basic parameters instead to describe your region of interest!")
if (!hasFiniteBoxConstraints(par.set))
stop("mbo requires finite box constraints!")
if (hasOtherConstraints(fun))
stop("mbo only can handle box-constraints defined in the par.set!")
if (hasDiscrete(par.set) && !hasLearnerProperties(learner, "factors"))
stop("Provided learner does not support factor parameters.")
if (learner$type != "regr")
stop("mbo requires regression learner!")
if (hasRequires(par.set) && !hasLearnerProperties(learner, "missings"))
stopf("The 'par.set' has dependent parameters, which will lead to missing values in X-space during modeling, but learner '%s' does not support handling of missing values (property 'missing')!", learner$id)
# general infill stuff (relavant for single objective and parEGO)
infill.crit = control$infill.crit
infill.crit.id = getMBOInfillCritId(infill.crit)
if (hasRequiresInfillCritStandardError(infill.crit) && learner$predict.type != "se") {
stopf("For infill criterion '%s' predict.type of learner %s must be set to 'se'!%s",
infill.crit.id, learner$id,
ifelse(hasLearnerProperties(learner, "se"), "",
"\nBut this learner does not seem to support prediction of standard errors! You could use the mlr wrapper makeBaggingWrapper to bootstrap the standard error estimator."))
}
# If nugget estimation should be used, make sure learner is a km model with activated nugget estim
if (infill.crit.id == "aei" && getMBOInfillCritParam(infill.crit, "aei.use.nugget")) {
if (getLeafLearner(learner)$short.name != "km" || !(isTRUE(getHyperPars(learner)$nugget.estim) || !is.null(getHyperPars(learner)$nugget))) {
stop("You have to turn on nugget estimation in your Kriging Model, if you want to use nugget estimation in the aei!")
}
}
# compatibility of optimizers and parameters
if (control$infill.opt %in% c("cmaes", "ea") && !isNumeric(par.set))
stopf("Optimizer '%s' can only be applied to numeric, integer, numericvector, integervector parameters!", control$infill.opt)
# set default mu parameter for ea infill optimizer
if (control$infill.opt == "ea") {
control$infill.opt.ea.mu = coalesce(control$infill.opt.ea.mu, getNumberOfParameters(fun) * 10L)
assertNumber(control$infill.opt.ea.mu, na.ok = FALSE, lower = 0)
}
if (is.null(control$target.fun.value)) {
# If we minimize, target is -Inf, for maximize it is Inf
control$target.fun.value = ifelse(shouldBeMinimized(fun), -Inf, Inf)
} else {
assertNumber(control$target.fun.value, na.ok = FALSE)
}
if (length(control$save.on.disk.at) > 0L && (control$iters + 1) %nin% control$save.on.disk.at)
warningf("You turned off the final saving of the optimization result at (iter + 1)! Do you really want this?")
if (length(control$save.on.disk.at) > 0 || is.finite(control$save.on.disk.at.time)) {
control$save.on.disk.at = asInteger(control$save.on.disk.at, any.missing = FALSE, lower = 0)
assertPathForOutput(control$save.file.path)
}
control$store.model.at = coalesce(control$store.model.at, control$iters + 1)
control$resample.at = coalesce(control$resample.at, integer(0))
# single-objective
if (control$n.objectives == 1L) {
if (control$propose.points == 1L) { # single point
} else { # multi point
if ((control$multipoint.method %in% c("cb", "cl", "cb") ||
control$multipoint.method == "moimbo" && control$multipoint.moimbo.objective != "mean.dist" )
&& learner$predict.type != "se") {
stopf("For multipoint method '%s'%s, predict.type of learner %s must be set to 'se'!%s",
control$multipoint.method,
ifelse(control$multipoint.method == "moimbo",
sprintf(" with objective '%s'", control$multipoint.moimbo.obj), ""),
learner$id,
ifelse(hasLearnerProperties(learner, "se"), "",
"\nBut this learner does not support prediction of standard errors!"))
}
if (control$multipoint.method == "cl" && infill.crit.id %nin% c("ei", "aei", "cb")) {
stopf("Multi-point proposal using constant liar needs the infill criterion 'ei' or 'aei', but you used '%s'!", infill.crit.id)
} else if (control$multipoint.method == "cl" && infill.crit.id == c("cb")) {
warningf("You are using multi-point proposal with constant liar and infill criterion 'cb'. Are you sure you don't want to use 'cb' as multi-point method?")
}
if (control$multipoint.method == "cb" && infill.crit.id != "cb") {
stopf("Multi-point proposal using parallel cb needs the infill criterion 'cb' (confidence bound), but you used '%s'!", infill.crit.id)
}
}
}
# multi-objective stuff
if (control$n.objectives > 1L) {
if (control$multiobj.method == "dib") {
if (infill.crit.id != "dib")
stopf("For multicrit 'dib' infil.crit must be set to 'dib'!")
} else {
if (infill.crit.id == "dib")
stopf("For infill.crit 'dib', multicrit method 'dib' is needed!")
}
if (control$multiobj.method == "mspot" && control$infill.opt != "nsga2")
stopf("For multi-objective 'mspot' infil.opt must be set to 'nsga2'!")
}
# propose point filtering
# FIXME: implement something that works for integer and discrte params
if (control$filter.proposed.points && hasDiscrete(par.set))
stop("Filtering proposed points currently not implemented for discrete parameters!")
return(control)
}