Skip to content

Commit 4f503e8

Browse files
committed
cleanup; added test
1 parent 49bd0d3 commit 4f503e8

File tree

13 files changed

+88
-108
lines changed

13 files changed

+88
-108
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Depends:
3232
R (>= 3.0.2),
3333
BBmisc (>= 1.10),
3434
ggplot2,
35-
ParamHelpers (>= 1.8),
35+
ParamHelpers (>= 1.9),
3636
stats,
3737
stringi
3838
Imports:

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ S3method(getTaskTargetNames,TaskDescUnsupervised)
6565
S3method(getTaskTargets,CostSensTask)
6666
S3method(getTaskTargets,SupervisedTask)
6767
S3method(getTaskTargets,UnsupervisedTask)
68+
S3method(hasExpression,Learner)
6869
S3method(impute,Task)
6970
S3method(impute,data.frame)
7071
S3method(isFailureModel,BaseWrapperModel)

R/Learner_properties.R

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,7 @@ getSupportedLearnerProperties = function(type = NA_character_) {
7575
p[[type]]
7676
}
7777

78+
#' @export
79+
hasExpression.Learner = function(par) {
80+
any(hasExpression(par$par.set)) || any(vlapply(par$par.vals, is.expression))
81+
}

R/Task_operators.R

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ getTaskData = function(task, subset, features, target.extra = FALSE, recode.targ
254254
checkTask(task, "Task")
255255

256256
if (missing(subset)) {
257-
subset = NULL
257+
subset = NULL
258258
} else {
259259
assert(checkIntegerish(subset), checkLogical(subset))
260260
if (is.logical(subset))
@@ -266,7 +266,7 @@ getTaskData = function(task, subset, features, target.extra = FALSE, recode.targ
266266
assertLogical(target.extra)
267267

268268
task.features = getTaskFeatureNames(task)
269-
269+
270270
# if supplied check if the input is right and always convert 'features'
271271
# to character vec
272272
if (!missing(features)) {
@@ -459,13 +459,13 @@ getTaskWeights = function(task) {
459459
# features (p), the number of observations (n), the task type (type) and in
460460
# case of classification tasks the number of class levels (k)
461461
makeTaskDictionary = function(task) {
462-
dict = list()
463-
dict$task = task
464-
dict$p = getTaskNFeats(task)
465-
dict$n = getTaskSize(task)
466-
dict$type = getTaskType(task)
462+
dict = list(
463+
task = task,
464+
p = getTaskNFeats(task),
465+
n = getTaskSize(task),
466+
type = getTaskType(task)
467+
)
467468
if (dict$type == "classif")
468469
dict$k = length(getTaskClassLevels(task))
469-
# dict$keys = setdiff(c(names(task$task.desc), names(task), "data", names(task$env$data)), names(dict))
470470
return(dict)
471471
}

R/evaluateLearner.R

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,22 @@
11
#' @title Evaluates expressions within a learner or parameter set according to the task.
22
#'
3-
#' @description Updates learners and/or parameter sets by evaluating their expressions
4-
#' based on a specific task. An overview of the possible expressions can be found in the details.
3+
#' @description
4+
#' A \code{\link{Learner}} or \code{\link[ParamHelpers]{ParamSet}} can contain an unevaluated \code{\link[base]{expression}}
5+
#' as value for a hyperparameter.
6+
#' E.g., these expressions are used if the default value dependents on the task size or an upper limit for a parameter
7+
#' is given by the number of features in a task.
8+
#' The provided functions evaluate such expressions in an environment (dictionary) which holds the following information:
9+
#' \itemize{
10+
#' \item{\code{task}:} the task itself, allowing to access any of its elements.
11+
#' \item{\code{p}:} the number of features in the task
12+
#' \item{\code{n}:} the number of observations in the task
13+
#' \item{\code{type}:} the task type, i.e. "classif", "regr", "surv", "cluster", "costcens" or "multilabel"
14+
#' \item{\code{k}:} the number of classes of the target variable (only available for classification tasks)
15+
#' }
16+
#' Usually the evaluation of the expression is performed automatically, e.g. in \code{\link{train}} or
17+
#' \code{\link{tuneParams}}.
18+
#' Therefore calling \code{evaluateParamSet} or \code{evaluateLearner} manually should not be necessary.
19+
#'
520
#' @template arg_learner
621
#' @param par.set [\code{\link[ParamHelpers]{ParamSet}}]\cr
722
#' Parameter set of (hyper)parameters and their constraints.
@@ -11,64 +26,52 @@
1126
#' @return [\code{\link{Learner}} | \code{\link[ParamHelpers]{ParamSet}}].
1227
#' @name evaluateLearner
1328
#' @rdname evaluateLearner
14-
#' @details The expressions can be based on any information provided by the task. For convenience,
15-
#' the most often used keys are available directly
16-
#' \itemize{
17-
#' \item{\code{task}:} the task itself, allowing to access any of its elements
18-
#' \item{\code{p}:} the number of features in the task
19-
#' \item{\code{n}:} the number of observations in the task
20-
#' \item{\code{type}:} the task type, i.e. "classif", "regr", "surv", "cluster", "costcens" or "multilabel"
21-
#' \item{\code{k}:} the number of classes of the target variable (only available for classification tasks)
22-
#' }
23-
#' However, if one wants to access any other parts of the \code{task}, one can do so. For instance, one could
24-
#' access the "blocking" via \code{task$task.desc$has.blocking}.
29+
#' @export
2530
#' @examples
2631
#' ## (1) evaluation of a learner's hyperparameters
2732
#' task = makeClassifTask(data = iris, target = "Species")
2833
#' lrn1 = makeLearner("classif.rpart", minsplit = expression(k * p),
2934
#' minbucket = expression(3L + 4L * task$task.desc$has.blocking))
3035
#' lrn2 = evaluateLearner(learner = lrn1, task = task)
31-
#'
32-
#' lrn1$par.vals
33-
#' lrn2$par.vals
34-
#'
36+
#'
37+
#' getHyperPars(lrn1)
38+
#' getHyperPars(lrn2)
39+
#'
3540
#' ## (2) evaluation of a learner's entire parameter set
3641
#' task = makeClassifTask(data = iris, target = "Species")
3742
#' lrn1 = makeLearner("classif.randomForest")
3843
#' lrn2 = evaluateLearner(learner = lrn1, task = task)
39-
#'
40-
#' ## focus on the parameters 'mtry', 'classwt' and 'cutoff'
41-
#' lrn1$par.set
42-
#' lrn2$par.set
43-
#'
44+
#'
45+
#' ## Note the values for parameters 'mtry', 'classwt' and 'cutoff'
46+
#' getParamSet(lrn1)
47+
#' getParamSet(lrn2)
48+
#'
4449
#' ## (3) evaluation of a parameter set
4550
#' task = makeClassifTask(data = iris, target = "Species")
4651
#' ps1 = makeParamSet(
4752
#' makeNumericParam("C", lower = expression(k), upper = expression(n), trafo = function(x) 2^x),
4853
#' makeDiscreteParam("sigma", values = expression(list(k, p)))
4954
#' )
50-
#' ps2 = evaluateParset(par.set = ps1, task = task)
51-
#' @export
55+
#' evaluateParset(par.set = ps1, task = task)
5256
evaluateLearner = function(learner, task) {
5357
dict = makeTaskDictionary(task = task)
5458
learner$par.set = evaluateParset(learner$par.set, task = task)
55-
if (length(learner$par.vals) > 0 && any(vlapply(learner$par.vals, is.expression)))
59+
if (any(vlapply(learner$par.vals, is.expression)))
5660
learner$par.vals = lapply(learner$par.vals, function(expr) eval(expr, envir = dict))
5761
return(learner)
5862
}
5963

6064
#' @rdname evaluateLearner
6165
#' @export
6266
evaluateParset = function(par.set, task) {
63-
dict = makeTaskDictionary(task = task)
6467
if (hasExpression(par = par.set)) {
68+
dict = makeTaskDictionary(task = task)
6569
checkParamSet(par.set = par.set, dict = dict)
6670
par.set = evaluateParamSet(par.set = par.set, dict = dict)
6771
## assure that the value names are also shown if the values list was unnamed
6872
par.set$pars = lapply(par.set$pars, function(x) {
69-
if (is.null(x$values) || !is.null(names(x$values)))
70-
return(x)
71-
names(x$values) = unlist(lapply(x$values, function(vals) vals))
73+
if (!is.null(x$values) && is.null(names(x$values)))
74+
names(x$values) = unlist(x$values)
7275
return(x)
7376
})
7477
}

R/makeLearner.R

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,7 @@
4343
#' @return [\code{\link{Learner}}].
4444
#' @family learner
4545
#' @export
46-
#' @details Note that learners can also contain task dependent expressions, which can be based on any
47-
#' information provided by the task. For convenience, the most often used keys are available directly
48-
#' \itemize{
49-
#' \item{\code{task}:} the task itself, allowing to access any of its elements
50-
#' \item{\code{p}:} the number of features in the task
51-
#' \item{\code{n}:} the number of observations in the task
52-
#' \item{\code{type}:} the task type, i.e. "classif", "regr", "surv", "cluster", "costcens" or "multilabel"
53-
#' \item{\code{k}:} the number of classes of the target variable (only available for classification tasks)
54-
#' }
55-
#' However, if one wants to access any other parts of the \code{task}, one can do so. For instance, one could
56-
#' access the "blocking" via \code{task$task.desc$has.blocking}.
46+
#' @note Learners can contain task dependent expressions, see \code{\link{evaluateLearner}} for more information.
5747
#' @aliases Learner
5848
#' @seealso [\code{\link{resample}}], [\code{\link{predict.WrappedModel}}]
5949
#' @examples

R/setHyperPars.R

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,7 @@
1111
#' @note If a named (hyper)parameter can't be found for the given learner, the 3
1212
#' closest (hyper)parameter names will be output in case the user mistyped.
1313
#' @export
14-
#' @details Note that learners can also contain task dependent expressions, which can be based on any
15-
#' information provided by the task. For convenience, the most often used keys are available directly
16-
#' \itemize{
17-
#' \item{\code{task}:} the task itself, allowing to access any of its elements
18-
#' \item{\code{p}:} the number of features in the task
19-
#' \item{\code{n}:} the number of observations in the task
20-
#' \item{\code{type}:} the task type, i.e. "classif", "regr", "surv", "cluster", "costcens" or "multilabel"
21-
#' \item{\code{k}:} the number of classes of the target variable (only available for classification tasks)
22-
#' }
23-
#' However, if one wants to access any other parts of the \code{task}, one can do so. For instance, one could
24-
#' access the "blocking" via \code{task$task.desc$has.blocking}.
14+
#' @note Learners can contain task dependent expressions, see \code{\link{evaluateLearner}} for more information.
2515
#' @family learner
2616
#' @importFrom utils adist
2717
#' @examples
@@ -70,14 +60,14 @@ setHyperPars2.Learner = function(learner, par.vals) {
7060
indices = order(adist(n, parnames))[1:3]
7161
possibles = na.omit(parnames[indices])
7262
if (length(possibles) > 0) {
73-
messagef("%s: couldn't find hyperparameter '%s'\nDid you mean one of these hyperparameters instead: %s",
63+
messagef("%s: couldn't find hyperparameter '%s'\nDid you mean one of these hyperparameters instead: %s",
7464
learner$id, n, stri_flatten(possibles, collapse = " "))
7565
}
76-
66+
7767
# no description: stop warn or quiet
78-
msg = sprintf("%s: Setting parameter %s without available description object!\nYou can switch off this check by using configureMlr!",
68+
msg = sprintf("%s: Setting parameter %s without available description object!\nYou can switch off this check by using configureMlr!",
7969
learner$id, n)
80-
70+
8171
if (on.par.without.desc == "stop") {
8272
stop(msg)
8373
} else if (on.par.without.desc == "warn") {

R/train.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
#' print(mod)
3131
train = function(learner, task, subset, weights = NULL) {
3232
learner = checkLearner(learner)
33-
if (hasExpression(learner$par.set) || any(vlapply(learner$par.vals, is.expression)))
33+
if (hasExpression(learner))
3434
learner = evaluateLearner(learner = learner, task = task)
3535
assertClass(task, classes = "Task")
3636
if (missing(subset)) {

R/tuneParams.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@
7979
tuneParams = function(learner, task, resampling, measures, par.set, control, show.info = getMlrOption("show.info")) {
8080
learner = checkLearner(learner)
8181
assertClass(task, classes = "Task")
82-
if (hasExpression(learner$par.set) || any(vlapply(learner$par.vals, is.expression)))
82+
if (hasExpression(learner))
8383
learner = evaluateLearner(learner = learner, task = task)
8484
measures = checkMeasures(measures, learner)
8585
assertClass(par.set, classes = "ParamSet")

man/evaluateLearner.Rd

Lines changed: 15 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)