Permalink
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
250 lines (230 sloc) 8.44 KB
#' @title
#' Make a Parameter Configuration
#'
#' @description
#' Defines a Parameter Configuration consisting of a \code{ParamSet} that defines the search range for the Hyperparameter Optimization.
#' Additionally you might want to specify some hard Parameters that are not supposed to be optimized but are necessary to be specified.
#' You might want to pass a Learner to associate the \code{ParConfig} to a special Learner.
#'
#' @param par.set [\code{ParamSet}]
#' The Parameter Set.
#' @param learner [\code{Learner}|\code{character(1)}]
#' mlr Learner or string that identifies the Learner.
#' @param par.vals [\code{list}]
#' Specific constant parameter settings.
#' If the learner also has defined hyperparameters they will be combined using \code{link[BBmisc]{insert}} and a warning will be issued.
#' @param learner.name [\code{character(1)}]
#' Will be overwritten if \code{learner} is passed.
#' Can be used to associate the Parameter Configuration to a Learner without specifying if it belongs to e.g. classification or regression.
#' @param note [\code{character(1)}]
#' The note you want to attach to the Parameter Configuration.
#'
#' @return [\code{ParConfig}]
#' @family ParConfig
#' @aliases ParConfig
#' @export
makeParConfig = function(par.set, learner = NULL, par.vals = NULL, learner.name = NULL, note = character(1L)) {
assertClass(par.set, "ParamSet")
assertString(note)
# check that par.vals do not conflict with par.set
if (!is.null(par.vals)) {
assertList(par.vals, unique = TRUE, names = "named")
conflict.ids = intersect(names(par.vals), getParamIds(par.set))
if (length(conflict.ids) > 0) {
stopf("Following par.vals are set to a specific value and conflict with the tuning par.set: %s", listToShortString(par.vals[conflict.ids]))
}
}
if (!is.null(learner)) {
learner = checkLearner(learner)
checkLearnerParSet(learner = learner, par.set = par.set)
learner.class = getLearnerClass(learner)
learner.type = getLearnerType(learner)
learner.name = getLearnerName(learner)
learner.par.vals = getLearnerParVals(learner)
# remove default par.vals from the learner if they are in the par.set
learner.par.vals = dropNamed(learner.par.vals, getParamIds(par.set))
# if par.vals are given, overwrite the ones from the learner itself
if (!is.null(par.vals) && isParValUpdate(par.vals, learner.par.vals)) {
new.par.vals = insert(learner.par.vals, par.vals)
overwritten.par.vals = intersect(names(par.vals), names(learner.par.vals))
if (length(overwritten.par.vals) > 0) {
warningf("The learners default par.vals %s were overwritten by the users par.vals %s", convertToShortString(learner.par.vals[overwritten.par.vals]), convertToShortString(par.vals[overwritten.par.vals]))
}
par.vals = new.par.vals
}
} else {
learner.class = NULL
learner.type = NULL
}
makeS3Obj(
classes = "ParConfig",
par.set = par.set,
par.vals = par.vals,
associated.learner.class = learner.class,
associated.learner.type = learner.type,
associated.learner.name = learner.name,
note = note
)
}
## Printer ####
#' @export
print.ParConfig = function(x, ...) {
catf("Parameter Configuration")
if (!is.null({par.vals = getParConfigParVals(x)})) {
catf(" Parameter Values: %s", convertToShortString(par.vals, clip.len = 32))
}
if (!is.null({learner.name = getParConfigLearnerName(x)})) {
catf(" Associated Learner: %s", getParConfigLearnerClass(x) %??% learner.name)
}
if (nzchar(getParConfigNote(x))) {
catf(" Note: %s", getParConfigNote(x))
}
catf(" Parameter Set:")
print(getParConfigParSet(x))
}
## Getter ####
#' @title Get the ParamSet of the configuration
#' @description Get the \code{ParamSet} of the configuration. If a task is supplied the expressions will be evaluated.
#' @template arg_parconfig
#' @template arg_task
#' @return [\code{ParamSet}].
#' @export
#' @family ParConfig
getParConfigParSet = function(par.config, task = NULL) {
if (!is.null(task)) {
evaluateParamExpressions(par.config$par.set, dict = getTaskDictionary(task))
} else {
par.config$par.set
}
}
#' @title Get the constant parameter settings of the configuration
#' @description Get the constant parameter settings of the configuration
#' @template arg_parconfig
#' @return [\code{list}].
#' @export
#' @family ParConfig
getParConfigParVals = function(par.config) par.config$par.vals %??% list()
#' @title Get the class of the associated learner
#' @description
#' Get the class of the associated learner
#' Can be \code{NULL} when no concrete learner is specified
#' @template arg_parconfig
#' @return [\code{character(1)}|NULL].
#' @export
#' @family ParConfig
getParConfigLearnerClass = function(par.config) par.config$associated.learner.class
#' @title Get the type of the associated learner
#' @description
#' Get the type of the associated learner.
#' Can be \code{NULL} when no type is specified
#' @template arg_parconfig
#' @return [\code{character(1)}|NULL].
#' @export
#' @family ParConfig
getParConfigLearnerType = function(par.config) par.config$associated.learner.type
#' @title Get the name of the associated learner
#' @description
#' Get the name of the associated learner.
#' Can be \code{NULL} when no learner is specified
#' @template arg_parconfig
#' @return [\code{character(1)}|NULL].
#' @export
#' @family ParConfig
getParConfigLearnerName = function(par.config) par.config$associated.learner.name
#' @title Get the note
#' @description
#' Get the note attached to a Parameter Configuration.
#' @template arg_parconfig
#' @return [\code{ParConfig}].
#' @export
#' @family ParConfig
getParConfigNote = function(par.config) {par.config$note}
## Setter ####
#' @title Set the type of the associated learner
#' @description
#' Can be useful when you want to use Parameter Configuration on a different type of task.
#' @template arg_parconfig
#' @param type [\code{character(1)}]
#' @return [\code{ParConfig}].
#' @export
#' @family ParConfig
setParConfigLearnerType = function(par.config, type) {
assertString(type)
# just change the type if it is different
old.type = getParConfigLearnerType(par.config)
if (is.null(old.type) || old.type != type) {
par.config$associated.learner.type = type
# change the learner class if we can
if (!is.null(getParConfigLearnerName(par.config))) {
learner = makeLearner(paste0(type,".",getParConfigLearnerName(par.config)))
checkLearnerParSet(learner, getParConfigParSet(par.config))
par.config$associated.learner.class = getLearnerClass(learner)
par.config$associated.learner.name = getLearnerName(learner)
}
}
par.config
}
#' @title Set an associated Learner
#' @description
#' Associate the Param Configuration with a specific learner
#' @template arg_parconfig
#' @param learner [\code{Learner}]
#' @return [\code{ParConfig}].
#' @export
#' @family ParConfig
setParConfigLearner = function(par.config, learner) {
learner = checkLearner(learner)
checkLearnerParSet(learner, getParConfigParSet(par.config))
par.config$associated.learner.class = getLearnerClass(learner)
par.config$associated.learner.name = getLearnerName(learner)
par.config$associated.learner.type = getLearnerType(learner)
par.config
}
#' @title Set a new Parameter Set
#' @description
#' Set a new Parameter Set
#' @template arg_parconfig
#' @param par.set [\code{ParamSet}]
#' The Parameter Set.
#' @return [\code{ParConfig}].
#' @export
#' @family ParConfig
setParConfigParSet = function(par.config, par.set) {
assertClass(par.set, "ParamSet")
learner.class = getParConfigLearnerClass(par.config)
if (!is.null(learner.class)) {
checkLearnerParSet(
learner = makeLearner(getParConfigLearnerClass(par.config)),
par.set = par.set)
}
par.config$par.set = par.set
par.config
}
#' @title Set Parameter Values
#' @description
#' Set Parameter Values
#' @template arg_parconfig
#' @param par.vals [\code{list}]
#' Specific constant parameter settings.
#' @return [\code{ParConfig}].
#' @export
#' @family ParConfig
setParConfigParVals = function(par.config, par.vals) {
assertList(par.vals, names = "named", any.missing = FALSE)
par.config$par.vals = par.vals
par.config
}
#' @title Set a note
#' @description
#' Attach note to the Parameter Configuration
#' @template arg_parconfig
#' @param note [\code{character(1)}]
#' The note.
#' @return [\code{ParConfig}].
#' @export
#' @family ParConfig
setParConfigNote = function(par.config, note) {
assertString(note)
par.config$note = note
par.config
}