Skip to content

Commit

Permalink
documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
mb706 committed Aug 3, 2020
1 parent e1ec16e commit 8e21fbb
Show file tree
Hide file tree
Showing 24 changed files with 420 additions and 49 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ Encoding: UTF-8
LazyData: true
NeedsCompilation: no
Roxygen: list(markdown = TRUE, r6 = FALSE)
RoxygenNote: 7.1.0.9000
RoxygenNote: 7.1.1
Collate:
'Graph.R'
'GraphLearner.R'
Expand Down
1 change: 1 addition & 0 deletions R/NO_OP.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#' and distinction from unintentional `NULL` returns.
#'
#' @family Path Branching
#' @family Special Graph Messages
#' @export
NO_OP = R6Class("NO_OP",
public = list(
Expand Down
12 changes: 10 additions & 2 deletions R/PipeOp.R
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,20 @@
#' `$train()` and `$predict()`. Column `train` is the (S3) class that an input object must conform to during
#' training, column `predict` is the (S3) class that an input object must conform to during prediction. Types
#' are checked by the [`PipeOp`] itself and do not need to be checked by `private$.train()` / `private$.predict()` code.\cr
#' A special name is `"..."`, which creates a *vararg* input channel that accepts a variable number of inputs.
#' A special name is `"..."`, which creates a *vararg* input channel that accepts a variable number of inputs.\cr
#' If a row has both `train` and `predict` values enclosed by square brackets ("`[`", "`]`), then this channel is
#' [`Multiplicity`]-aware. If the [`PipeOp`] receives a [`Multiplicity`] value on these channels, this [`Multiplicity`]
#' is given to the `.train()` and `.predict()` functions directly. Otherwise, the [`Multiplicity`] is transparently
#' unpacked and the `.train()` and `.predict()` functions are called multiple times, once for each [`Multiplicity`] element.
#' The type enclosed by square brackets indicates that only a [`Multiplicity`] containing values of this type are accepted.
#' See [`Multiplicity`] for more information.
#' * output :: [`data.table`] with columns `name` (`character`), `train` (`character`), `predict` (`character`)\cr
#' Output channels of [`PipeOp`], in the order in which they will be given in the list returned by `$train` and
#' `$predict` functions. Column `train` is the (S3) class that an output object must conform to during training,
#' column `predict` is the (S3) class that an output object must conform to during prediction. The [`PipeOp`] checks
#' values returned by `private$.train()` and `private$.predict()` against these types specifications.
#' values returned by `private$.train()` and `private$.predict()` against these types specifications.\cr
#' If a row has both `train` and `predict` values enclosed by square brackets ("`[`", "`]`), then this signals that the channel
#' emits a [`Multiplicity`] of the indicated type. See [`Multiplicity`] for more information.
#' * `innum` :: `numeric(1)` \cr
#' Number of input channels. This equals `nrow($input)`.
#' * `outnum` :: `numeric(1)` \cr
Expand Down
13 changes: 10 additions & 3 deletions R/PipeOpClassifAvg.R
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,19 @@
#' equal weights for each prediction.
#' Defaults to equal weights for each model.
#'
#' If `
#'
#' @section Construction:
#' ```
#' PipeOpClassifAvg$new(innum = 0, id = "classifavg", param_vals = list())
#' PipeOpClassifAvg$new(innum = 0, collect_multiplicity = FALSE, id = "classifavg", param_vals = list())
#' ```
#' * `innum` :: `numeric(1)`\cr
#' Determines the number of input channels.
#' If `innum` is 0 (default), a vararg input channel is created that can take an arbitrary number of inputs.
#' * `collect_multiplicity` :: `logical(1)`\cr
#' If `TRUE`, the input is a [`Multiplicity`] collecting channel. This means, a
#' [`Multiplicity`] input, instead of multiple normal inputs, is accepted and the members are aggregated. This requires `innum` to be 0.
#' Default is `FALSE`.
#' * `id` :: `character(1)`
#' Identifier of the resulting object, default `"classifavg"`.
#' * `param_vals` :: named `list`\cr
Expand All @@ -51,6 +57,7 @@
#' @section Methods:
#' Only methods inherited from [`PipeOpEnsemble`]/[`PipeOp`].
#' @family PipeOps
#' @family Multiplicity PipeOps
#' @family Ensembles
#' @include PipeOpEnsemble.R
#' @export
Expand All @@ -70,8 +77,8 @@
PipeOpClassifAvg = R6Class("PipeOpClassifAvg",
inherit = PipeOpEnsemble,
public = list(
initialize = function(innum = 0, collect = FALSE, id = "classifavg", param_vals = list()) {
super$initialize(innum, collect, id, param_vals = param_vals, prediction_type = "PredictionClassif", packages = "stats")
initialize = function(innum = 0, collect_multiplicity = FALSE, id = "classifavg", param_vals = list()) {
super$initialize(innum, collect_multiplicity, id, param_vals = param_vals, prediction_type = "PredictionClassif", packages = "stats")
}
),
private = list(
Expand Down
16 changes: 9 additions & 7 deletions R/PipeOpEnsemble.R
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@
#' @section Construction:
#' Note: This object is typically constructed via a derived class, e.g. [`PipeOpClassifAvg`] or [`PipeOpRegrAvg`].
#' ```
#' PipeOpEnsemble$new(innum = 0, collect = FALSE, id, param_set = ParamSet$new(), param_vals = list(), packages = character(0), prediction_type = "Prediction")
#' PipeOpEnsemble$new(innum = 0, collect_multiplicity = FALSE, id, param_set = ParamSet$new(), param_vals = list(), packages = character(0), prediction_type = "Prediction")
#' ```
#'
#' * `innum` :: `numeric(1)`\cr
#' Determines the number of input channels.
#' If `innum` is 0 (default), a vararg input channel is created that can take an arbitrary number of inputs.
#' * `collect` :: `logical(1)`\cr
#' If `TRUE`, the vararg input channel is turned into a [`Multiplicity`] collecting channel, e.g.,
#' all input [`Prediction`][mlr3::Prediction]s are collected. Default is `FALSE`.
#' * `collect_multiplicity` :: `logical(1)`\cr
#' If `TRUE`, the input is a [`Multiplicity`] collecting channel. This means, a
#' [`Multiplicity`] input, instead of multiple normal inputs, is accepted and the members are aggregated. This requires `innum` to be 0.
#' Default is `FALSE`.
#' * `id` :: `character(1)`\cr
#' Identifier of the resulting object.
#' * `param_set` :: [`ParamSet`][paradox::ParamSet]\cr
Expand Down Expand Up @@ -73,20 +74,21 @@
#' This method is abstract, it must be implemented by deriving classes.
#'
#' @family PipeOps
#' @family Multiplicity PipeOps
#' @family Ensembles
#' @include PipeOp.R
#' @export
PipeOpEnsemble = R6Class("PipeOpEnsemble",
inherit = PipeOp,
public = list(
initialize = function(innum = 0, collect = FALSE, id, param_set = ParamSet$new(), param_vals = list(), packages = character(0), prediction_type = "Prediction", tags = NULL) {
initialize = function(innum = 0, collect_multiplicity = FALSE, id, param_set = ParamSet$new(), param_vals = list(), packages = character(0), prediction_type = "Prediction", tags = NULL) {
assert_integerish(innum, lower = 0)
param_set$add(ParamUty$new("weights", custom_check = check_weights(innum), tags = "predict"))
param_set$values$weights = 1
inname = if (innum) rep_suffix("input", innum) else "..."
intype = c("NULL", prediction_type)
private$.collect = assert_flag(collect)
if (collect) {
private$.collect = assert_flag(collect_multiplicity)
if (collect_multiplicity) {
if (innum) {
stop("collect only works with innum == 0.")
}
Expand Down
14 changes: 8 additions & 6 deletions R/PipeOpFeatureUnion.R
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#'
#' @section Construction:
#' ```
#' PipeOpFeatureUnion$new(innum = 0, collect = FALSE, id = "featureunion", param_vals = list(),
#' PipeOpFeatureUnion$new(innum = 0, collect_multiplicity = FALSE, id = "featureunion", param_vals = list(),
#' assert_targets_equal = TRUE)
#' ```
#'
Expand All @@ -31,9 +31,10 @@
#' If `innum` is 0 (default), a vararg input channel is created that can take an arbitrary number
#' of inputs. If `innum` is a `character` vector, the number of input channels is the length of
#' `innum`, and the columns of the result are prefixed with the values.
#' * `collect` :: `logical(1)`\cr
#' If `TRUE`, the vararg input channel is turned into a [`Multiplicity`] collecting channel, e.g.,
#' all input [`Task`][mlr3::Task]s are collected. Default is `FALSE`.
#' * `collect_multiplicity` :: `logical(1)`\cr
#' If `TRUE`, the input is a [`Multiplicity`] collecting channel. This means, a
#' [`Multiplicity`] input, instead of multiple normal inputs, is accepted and the members are aggregated. This requires `innum` to be 0.
#' Default is `FALSE`.
#' * `id` :: `character(1)`\cr
#' Identifier of the resulting object, default `"featureunion"`.
#' * `param_vals` :: named `list`\cr
Expand Down Expand Up @@ -75,6 +76,7 @@
#' Only methods inherited from [`PipeOp`].
#'
#' @family PipeOps
#' @family Multiplicity PipeOps
#' @include PipeOp.R
#' @export
#' @examples
Expand All @@ -98,7 +100,7 @@ PipeOpFeatureUnion = R6Class("PipeOpFeatureUnion",
public = list(
assert_targets_equal = NULL,
inprefix = NULL,
initialize = function(innum = 0L, collect = FALSE, id = "featureunion", param_vals = list(), assert_targets_equal = TRUE) {
initialize = function(innum = 0L, collect_multiplicity = FALSE, id = "featureunion", param_vals = list(), assert_targets_equal = TRUE) {
assert(
check_int(innum, lower = 0L),
check_character(innum, min.len = 1L, any.missing = FALSE)
Expand All @@ -113,7 +115,7 @@ PipeOpFeatureUnion = R6Class("PipeOpFeatureUnion",
self$assert_targets_equal = assert_targets_equal
inname = if (innum) rep_suffix("input", innum) else "..."
intype = "Task"
private$.collect = assert_flag(collect)
private$.collect = assert_flag(collect_multiplicity)
if (collect) {
if (innum) {
stop("collect only works with innum == 0.")
Expand Down
28 changes: 26 additions & 2 deletions R/PipeOpMultiplicity.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
#' @description
#' Implicate a [`Multiplicity`] by returning the input(s) converted to a [`Multiplicity`].
#'
#' This [`PipeOp`] has multiple input channels; all inputs are collected into a [`Multiplicity`]
#' and then are forwarded along a single edge, causing the following [`PipeOp`]s to be called
#' multiple times, once for each [`Multiplicity`] member.
#'
#' Note that [`Multiplicity`] is currently an experimental features and the implementation or UI
#' may change.
#'
#' @section Construction:
#' ```
#' PipeOpMultiplicityImply$new(innum = 0, id = "multiplicityimply", param_vals = list())
Expand Down Expand Up @@ -50,6 +57,8 @@
#' Only methods inherited from [`PipeOp`].
#'
#' @family PipeOps
#' @family Multiplicity PipeOps
#' @family Experimental Features
#' @include PipeOp.R
#' @export
#' @examples
Expand Down Expand Up @@ -104,7 +113,14 @@ mlr_pipeops$add("multiplicityimply", PipeOpMultiplicityImply)
#' @format [`R6Class`] object inheriting from [`PipeOp`].
#'
#' @description
#' Explicate a [`Multiplicity`] by returning the unclassed input [`Multiplicity`], i.e., a `list()`.
#' Explicate a [`Multiplicity`] by turning the input [`Multiplicity`] into multiple outputs.
#'
#' This [`PipeOp`] has multiple output channels; the members of the input [`Multiplicity`]
#' are forwarded each along a single edge. Therefore, only multiplicities with exactly as many
#' members as `outnum` are accepted.
#'
#' Note that [`Multiplicity`] is currently an experimental features and the implementation or UI
#' may change.
#'
#' @section Construction:
#' ```
Expand Down Expand Up @@ -143,6 +159,8 @@ mlr_pipeops$add("multiplicityimply", PipeOpMultiplicityImply)
#' Only methods inherited from [`PipeOp`].
#'
#' @family PipeOps
#' @family Multiplicity PipeOps
#' @family Experimental Features
#' @include PipeOp.R
#' @export
#' @examples
Expand Down Expand Up @@ -185,7 +203,11 @@ mlr_pipeops$add("multiplicityexply", PipeOpMultiplicityExply, list("N"))
#' @format [`R6Class`] object inheriting from [`PipeOp`].
#'
#' @description
#' Replicate the input and return a [`Multiplicity`].
#' Replicate the input as a [`Multiplicity`], causing subsequent [`PipeOp`]s to be executed multiple
#' `reps` times.
#'
#' Note that [`Multiplicity`] is currently an experimental features and the implementation or UI
#' may change.
#'
#' @section Construction:
#' ```
Expand Down Expand Up @@ -218,6 +240,8 @@ mlr_pipeops$add("multiplicityexply", PipeOpMultiplicityExply, list("N"))
#' Only methods inherited from [`PipeOp`].
#'
#' @family PipeOps
#' @family Multiplicity PipeOps
#' @family Experimental Features
#' @include PipeOp.R
#' @export
#' @examples
Expand Down
22 changes: 20 additions & 2 deletions R/PipeOpOVR.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,20 @@
#'
#' @description
#' Splits a [classification Task][mlr3::TaskClassif] into several binary [classification
#' Tasks][mlr3::TaskClassif] to perform "One vs. Rest" classification.
#' Tasks][mlr3::TaskClassif] to perform "One vs. Rest" classification. This works in combination
#' with [`PipeOpOVRUnite`].
#'
#' For each target level a new binary [classification Task][mlr3::TaskClassif] is constructed with
#' the respective target level being the positive class and all other target levels being the
#' new negative class `"rest"`.
#'
#' This [`PipeOp`] creates a [`Multiplicity`], which means that subsequent [`PipeOp`]s are executed
#' multiple times, once for each created [binary `Task`][mlr3::TaskClassif], until a [`PipeOpOVRUnite`]
#' is reached.
#'
#' Note that [`Multiplicity`] is currently an experimental features and the implementation or UI
#' may change.
#'
#' @section Construction:
#' ```
#' PipeOpOVRSplit$new(id = "ovrsplit", param_vals = list())
Expand Down Expand Up @@ -54,6 +62,8 @@
#' @section Methods:
#' Only methods inherited from [`PipeOp`].
#' @family PipeOps
#' @family Multiplicity PipeOps
#' @family Experimental Features
#' @include PipeOp.R
#' @export
#' @examples
Expand Down Expand Up @@ -107,7 +117,7 @@ mlr_pipeops$add("ovrsplit", PipeOpOVRSplit)
#'
#' @description
#' Perform "One vs. Rest" classification by (weighted) majority vote prediction from [classification
#' Predictions][mlr3::PredictionClassif].
#' Predictions][mlr3::PredictionClassif]. This works in combination with [`PipeOpOVRSplit`].
#'
#' Weights can be set as a parameter; if none are provided, defaults to equal weights for each
#' prediction.
Expand All @@ -118,6 +128,12 @@ mlr_pipeops$add("ovrsplit", PipeOpOVRSplit)
#'
#' Missing values during prediction are treated as each class label being equally likely.
#'
#' This [`PipeOp`] uses a [`Multiplicity`] input, which is created by [`PipeOpOVRSplit`] and causes
#' [`PipeOp`]s on the way to this [`PipeOp`] to be called once for each individual [binary `Task`][mlr3::TaskClassif].
#'
#' Note that [`Multiplicity`] is currently an experimental features and the implementation or UI
#' may change.
#'
#' @section Construction:
#' ```
#' PipeOpOVRUnite$new(id = "ovrunite", param_vals = list())
Expand Down Expand Up @@ -152,6 +168,8 @@ mlr_pipeops$add("ovrsplit", PipeOpOVRSplit)
#' Only methods inherited from [`PipeOpEnsemble`]/[`PipeOp`].
#' @family PipeOps
#' @family Ensembles
#' @family Multiplicity PipeOps
#' @family Experimental Features
#' @include PipeOpEnsemble.R
#' @export
#' @examples
Expand Down
11 changes: 8 additions & 3 deletions R/PipeOpRegrAvg.R
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,15 @@
#'
#' @section Construction:
#' ```
#' PipeOpRegrAvg$new(innum = 0, id = "regravg", param_vals = list())
#' PipeOpRegrAvg$new(innum = 0, collect_multiplicity = FALSE, id = "regravg", param_vals = list())
#' ```
#' * `innum` :: `numeric(1)`\cr
#' Determines the number of input channels.
#' If `innum` is 0 (default), a vararg input channel is created that can take an arbitrary number of inputs.
#' * `collect_multiplicity` :: `logical(1)`\cr
#' If `TRUE`, the input is a [`Multiplicity`] collecting channel. This means, a
#' [`Multiplicity`] input, instead of multiple normal inputs, is accepted and the members are aggregated. This requires `innum` to be 0.
#' Default is `FALSE`.
#' * `id` :: `character(1)`
#' Identifier of the resulting object, default `"regravg"`.
#' * `param_vals` :: named `list`\cr
Expand All @@ -47,6 +51,7 @@
#' Only methods inherited from [`PipeOpEnsemble`]/[`PipeOp`].
#'
#' @family PipeOps
#' @family Multiplicity PipeOps
#' @family Ensembles
#' @include PipeOpEnsemble.R
#' @export
Expand All @@ -66,8 +71,8 @@ PipeOpRegrAvg = R6Class("PipeOpRegrAvg",
inherit = PipeOpEnsemble,

public = list(
initialize = function(innum = 0, collect = FALSE, id = "regravg", param_vals = list(), ...) {
super$initialize(innum, collect, id, param_vals = param_vals, prediction_type = "PredictionRegr", ...)
initialize = function(innum = 0, collect_multiplicity = FALSE, id = "regravg", param_vals = list(), ...) {
super$initialize(innum, collect_multiplicity, id, param_vals = param_vals, prediction_type = "PredictionRegr", ...)
}
),
private = list(
Expand Down
43 changes: 41 additions & 2 deletions R/multiplicity.R
Original file line number Diff line number Diff line change
@@ -1,12 +1,51 @@
#' @title Multiplicity
#'
#' @description
#' Construct an object of the S3 class [`Multiplicity`], which is a named or
#' unnamed lists of data.
#' A [`Multiplicity`] class S3 object.
#'
#' The function of multiplicities is to indicate that [`PipeOp`]s should be executed
#' multiple times with multiple values.
#'
#' A [`Multiplicity`] is a container, like a
#' `list()`, that contains multiple values. If the message that is passed along the
#' edge of a [`Graph`] is a [`Multiplicity`]-object, then the [`PipeOp`] that receives
#' this object will *usually* be called once for each contained value. The result of
#' each of these calls is then, again, packed in a [`Multiplicity`] and sent along the
#' outgoing edge(s) of that [`PipeOp`]. This means that a [`Multiplicity`] can cause
#' multiple [`PipeOp`]s in a row to be run multiple times, where the run for each element
#' of the [`Multiplicity`] is independent from the others.
#'
#' Most [`PipeOp`]s only return a [`Multiplicity`] if their input was a [`Multiplicity`]
#' (and after having run their code multiple times, once for each entry). However,
#' there are a few special [`PipeOp`]s that are "aware" of [`Multiplicity`] objects. These
#' may either *create* a [`Multiplicity`] even though not having a [`Multiplicity`] input
#' (e.g. [`PipeOpReplicate`] or [`PipeOpOVRSplit`]) -- causing the subsequent [`PipeOp`]s
#' to be run multiple times -- or *collect* a [`Multiplicity`], being called only once
#' even though their input is a [`Multiplicity`] (e.g. [`PipeOpOVRUnite`] or [`PipeOpFeatureUnion`]
#' if constructed with the `collect_multiplicity` argument set to `TRUE`). The combination
#' of these mechanisms makes it possible for parts of a [`Graph`] to be called variably
#' many times if "sandwiched" between [`Multiplicity`] creating and collecting [`PipeOp`]s.
#'
#' Whether a [`PipeOp`] creates or collects a [`Multiplicity`] is indicated by the `$input`
#' or `$output` slot (which indicate names and types of in/out channels). If the `train` and
#' `predict` types of an input or output are surrounded by square brackets ("`[`", "`]`"), then
#' this channel handles a [`Multiplicity`] explicitly. Depending on the function of the [`PipeOp`],
#' it will usually collect (input channel) or create (output channel) a [`Multiplicity`].
#' [`PipeOp`]s without this indicator are [`Multiplicity`] agnostic and blindly execute their
#' function multiple times when given a [`Multiplicity`].
#'
#' If a [`PipeOp`] is trained on a [`Multiplicity`], the `$state` slot is set to a [`Multiplicity`]
#' as well; this [`Multiplicity`] contains the "original" `$state` resulting from each individual
#' call of the [`PipeOP`] with the input [`Multiplicity`]'s content. If a [`PipeOp`] was trained
#' with a [`Multiplicity`], then the `predict()` argument must be a [`Multiplicity`] with the same
#' number of elements.
#'
#' @param \dots \cr
#' Can be anything.
#' @return [`Multiplicity`]
#' @family Special Graph Messages
#' @family Experimental Features
#' @family Multiplicity PipeOps
#' @export
Multiplicity = function(...) {
structure(list(...), class = "Multiplicity")
Expand Down
Loading

0 comments on commit 8e21fbb

Please sign in to comment.