diff --git a/DESCRIPTION b/DESCRIPTION
index 7a54a3604..5e14389f0 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -133,6 +133,7 @@ Collate:
'PipeOpChunk.R'
'PipeOpClassBalancing.R'
'PipeOpClassWeights.R'
+ 'PipeOpClassWeightsEx.R'
'PipeOpClassifAvg.R'
'PipeOpColApply.R'
'PipeOpColRoles.R'
diff --git a/NAMESPACE b/NAMESPACE
index 7d18e1f4f..1aa760109 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -105,6 +105,7 @@ export(PipeOpBranch)
export(PipeOpChunk)
export(PipeOpClassBalancing)
export(PipeOpClassWeights)
+export(PipeOpClassWeightsEx)
export(PipeOpClassifAvg)
export(PipeOpColApply)
export(PipeOpColRoles)
diff --git a/R/PipeOpClassWeights.R b/R/PipeOpClassWeights.R
index bf7588423..f0b72ca98 100644
--- a/R/PipeOpClassWeights.R
+++ b/R/PipeOpClassWeights.R
@@ -5,25 +5,26 @@
#' @format [`R6Class`][R6::R6Class] object inheriting from [`PipeOpTaskPreproc`]/[`PipeOp`].
#'
#' @description
-#' Adds a class weight column to the [`Task`][mlr3::Task] that different [`Learner`][mlr3::Learner]s may be
-#' able to use for sample weighting. Sample weights are added to each sample according to the target class.
+#' Adds a class weight column to the [`Task`][mlr3::Task], influencing how different [`Learner`][mlr3::Learner]s weight samples during training.
+#' It is also possible to add a weight column to the [`Task`][mlr3::Task], which affects how samples are weighted during evaluation.
+#' Sample weights are assigned to each observation according to its target class.
#'
#' Only binary [classification tasks][mlr3::TaskClassif] are supported.
#'
#' Caution: when constructed naively without parameter, the weights are all set to 1. The `minor_weight` parameter
#' must be adjusted for this [`PipeOp`] to be useful.
#'
-#' Note this only sets the `"weights_learner"` column.
-#' It therefore influences the behaviour of subsequent [`Learner`][mlr3::Learner]s, but does not influence resampling or evaluation metric weights.
+#' It is possible to set either one of the `"weights_learner"` and `"weights_measure"` columns, both of them or none of them.
+#' Thus, the behavior of subsequent [`Learner`][mlr3::Learner]s or evaluation metric weights can be determined.
#'
#' @section Construction:
#' ```
#' PipeOpClassWeights$new(id = "classweights", param_vals = list())
#' ```
#'
-#' * `id` :: `character(1)`
+#' * `id` :: `character(1)` \cr
#' Identifier of the resulting object, default `"classweights"`
-#' * `param_vals` :: named `list`\cr
+#' * `param_vals` :: named `list` \cr
#' List of hyperparameter settings, overwriting the hyperparameter settings that would otherwise be set during construction. Default `list()`.
#'
#' @section Input and Output Channels:
@@ -40,12 +41,14 @@
#' The parameters are the parameters inherited from [`PipeOpTaskPreproc`]; however, the `affect_columns` parameter is *not* present. Further parameters are:
#' * `minor_weight` :: `numeric(1)` \cr
#' Weight given to samples of the minor class. Major class samples have weight 1. Initialized to 1.
-#' @section Internals:
-#' Introduces, or overwrites, the "weights" column in the [`Task`][mlr3::Task]. However, the [`Learner`][mlr3::Learner] method needs to
-#' respect weights for this to have an effect.
+#' * `weight_type` :: `character` \cr
+#' Determines whether `"weights_learner"`, `"weights_measure"`, both or none of the columns will be set. Defaults to `"learner"`. An empty
+#' vector leaves the task unchanged.
#'
-#' The newly introduced column is named `.WEIGHTS`; there will be a naming conflict if this column already exists and is *not* a
-#' weight column itself.
+#' @section Internals:
+#' Adds a `.WEIGHTS` column to the [`Task`][mlr3::Task], which is removed from the feature role and mapped to the requested weight roles.
+#' The [`Learner`][mlr3::Learner] must support weights for this to have an effect. There will be a naming conflict if this column already
+#' exists and is *not* as weight column itself.
#'
#' @section Fields:
#' Only fields inherited from [`PipeOp`].
@@ -84,20 +87,26 @@ PipeOpClassWeights = R6Class("PipeOpClassWeights",
public = list(
initialize = function(id = "classweights", param_vals = list()) {
ps = ps(
- minor_weight = p_dbl(lower = 0, upper = Inf, tags = "train")
- )
- ps$values = list(minor_weight = 1)
+ minor_weight = p_dbl(init = 1, lower = 0, upper = Inf, tags = "train"),
+ weight_type = p_uty(init = "learner", tags = "train",
+ custom_check = crate(function(x) check_character(x, max.len = 2) %check&&% check_subset(x, choices = c("learner", "measure"))))
+ )
super$initialize(id, param_set = ps, param_vals = param_vals, can_subset_cols = FALSE, task_type = "TaskClassif", tags = "imbalanced data")
}
),
private = list(
-
.train_task = function(task) {
+ pv = self$param_set$get_values(tags = "train")
+
if ("twoclass" %nin% task$properties) {
stop("Only binary classification Tasks are supported.")
}
+ # return task as is, if weight_type is an empty list
+ if (length(pv$weight_type) == 0)
+ return(task)
+
weightcolname = ".WEIGHTS"
if (weightcolname %in% unlist(task$col_roles)) {
stopf("Weight column '%s' is already in the Task", weightcolname)
@@ -106,14 +115,17 @@ PipeOpClassWeights = R6Class("PipeOpClassWeights",
truth = task$truth()
minor = names(which.min(table(task$truth())))
- wcol = setnames(data.table(ifelse(truth == minor, self$param_set$values$minor_weight, 1)), weightcolname)
+ wcol = setnames(data.table(ifelse(truth == minor, pv$minor_weight, 1)), weightcolname)
task$cbind(wcol)
task$col_roles$feature = setdiff(task$col_roles$feature, weightcolname)
- if ("weights_learner" %in% mlr_reflections$task_col_roles$classif) {
- task$col_roles$weights_learner = weightcolname
- } else {
- task$col_roles$weight = weightcolname
+
+ classif_roles = mlr_reflections$task_col_roles$classif
+
+ for (type in pv$weight_type) {
+ preferred_role = paste0("weights_", type)
+ final_role = if (preferred_role %in% classif_roles) preferred_role else "weight"
+ task$col_roles[[final_role]] = weightcolname
}
task
},
diff --git a/R/PipeOpClassWeightsEx.R b/R/PipeOpClassWeightsEx.R
new file mode 100644
index 000000000..f97b0ab54
--- /dev/null
+++ b/R/PipeOpClassWeightsEx.R
@@ -0,0 +1,171 @@
+#' @title Class Weights for Sample Weighting - Extended
+#'
+#' @usage NULL
+#' @name mlr_pipeops_classweightsex
+#' @format [`R6Class`][R6::R6Class] object inheriting from [`PipeOpTaskPreproc`]/[`PipeOp`].
+#'
+#' @description
+#' Adds a class weight column to the [`Task`][mlr3::Task], influencing how different [`Learner`][mlr3::Learner]s weight samples during training.
+#' It is also possible to add a weight column to the [`Task`][mlr3::Task], which affects how samples are weighted during evaluation.
+#' Sample weights are assigned to each observation according to its target class.
+#'
+#' Binary as well as multiclass [classification tasks][mlr3::TaskClassif] are supported.
+#'
+#' It is possible to set either one of the `"weights_learner"` and `"weights_measure"` columns, both of them or none of them.
+#' Thus, the behavior of subsequent [`Learner`][mlr3::Learner]s or evaluation metric weights can be determined.
+#'
+#' @section Construction:
+#' ```
+#' PipeOpClassWeightsEx$new(id = "classweightsex", param_vals = list())
+#' ```
+#'
+#' * `id` :: `character(1)` \cr
+#' Identifier of the resulting object, default `"classweightsex"`
+#' * `param_vals` :: named `list`\cr
+#' List of hyperparameter settings, overwriting the hyperparameter settings that would otherwise be set during construction. Default `list()`.
+#'
+#' @section Input and Output Channels:
+#' Input and output channels are inherited from [`PipeOpTaskPreproc`]. Instead of a [`Task`][mlr3::Task], a
+#' [`TaskClassif`][mlr3::TaskClassif] is used as input and output during training and prediction.
+#'
+#' The output during training is the input [`Task`][mlr3::Task] with added weights column according to target class.
+#' The output during prediction is the unchanged input.
+#'
+#' @section State:
+#' The `$state` is a named `list` with the `$state` elements inherited from [`PipeOpTaskPreproc`].
+#'
+#' @section Parameters:
+#' The parameters are the parameters inherited from [`PipeOpTaskPreproc`]; however, the `affect_columns` parameter is *not* present. Further parameters are:
+#' * `weight_type` :: `character` \cr
+#' Determines whether `"weights_learner"`, `"weights_measure"`, both or none of the columns will be set.
+#' * `weight_method` :: `character(1)` \cr
+#' The method that is chosen to determine the weights of the samples. Methods encompass (`"inverse_class_frequency"`, `"inverse_square_root_of_frequency"`, `"median_frequency_balancing"`, `"explicit"`).
+#' * `mapping` :: named `numeric` \cr
+#' Depends on `"weight_method" = "explicit"`. Must be a named numeric vector that specifies a finite weight for each target class in the task.
+#'
+#' The newly introduced column is named `.WEIGHTS`; there will be a naming conflict if this column already exists and is *not* a
+#' weight column itself.
+#'
+#' @section Internals:
+#' The `.WEIGHTS` column is removed from the feature role and re-assigned to the requested weight roles. When `weight_method = "explicit"`,
+#' the mapping must cover every class present in the training data and may not contain additional classes.
+#'
+#' @section Fields:
+#' Only fields inherited from [`PipeOp`].
+#'
+#' @section Methods:
+#' Only methods inherited from [`PipeOpTaskPreproc`]/[`PipeOp`].
+#'
+#' @family PipeOps
+#' @template seealso_pipeopslist
+#' @include PipeOpTaskPreproc.R
+#' @export
+#' @examples
+#' library("mlr3")
+#'
+#' task = tsk("spam")
+#'
+#' poicf = po("classweightsex", param_vals = list(weight_type = c("learner", "measure"), weight_method = "inverse_class_frequency"))
+#' result = poicf$train(list(task))[[1L]]
+#'
+#' if ("weights_learner" %in% names(result)) {
+#' result$weights_learner # recent mlr3-versions
+#' } else {
+#' result$weights # old mlr3-versions
+#' }
+#'
+#' result$weights_measure
+#'
+#'
+#' if ("weights_measure" %in% names(result)) {
+#' result$weights_measure # recent mlr3-versions
+#' } else {
+#' result$weights # old mlr3-versions
+#' }
+
+PipeOpClassWeightsEx = R6Class("PipeOpClassWeightsEx",
+ inherit = PipeOpTaskPreproc,
+
+ public = list(
+ initialize = function(id = "classweightsex", param_vals = list()) {
+ ps = ps(
+ weight_type = p_uty(init = "learner", tags = "train",
+ custom_check = crate(function(x) check_character(x, max.len = 2) %check&&% check_subset(x, choices = c("learner", "measure")))),
+ weight_method = p_fct(init = "explicit",
+ levels = c("inverse_class_frequency", "inverse_square_root_of_frequency", "median_frequency_balancing", "effective_number_of_samples", "explicit"), tags = c("train", "required")),
+ mapping = p_uty(tags = "train",
+ custom_check = crate(function(x) {
+ if (is.null(x)) {
+ return(TRUE)
+ }
+ check_numeric(x, any.missing = FALSE, finite = TRUE) %check&&%
+ check_character(names(x), any.missing = FALSE, unique = TRUE, min.chars = 1)
+ }),
+ depends = weight_method == "explicit")
+ )
+ super$initialize(id, param_set = ps, param_vals = param_vals, can_subset_cols = FALSE, task_type = "TaskClassif", tags = "imbalanced data")
+ }
+ ),
+ private = list(
+
+ .train_task = function(task) {
+ pv = self$param_set$get_values(tags = "train")
+
+ if (is.null(pv$weight_type) ||
+ is.null(pv$weight_method) ||
+ (pv$weight_method == "explicit" && is.null(pv$mapping))) {
+ return(task)
+ }
+
+ class_names = task$class_names
+ if (identical(pv$weight_method, "explicit")) {
+ mapping_names = names(pv$mapping)
+ missing = setdiff(class_names, mapping_names)
+ extra = setdiff(mapping_names, class_names)
+
+ if (length(missing)) {
+ stopf("Explicit class weights must cover every class in the task; missing: %s", paste(missing, collapse = ", "))
+ }
+ if (length(extra)) {
+ stopf("Explicit class weights contain labels not present in the task: %s", paste(extra, collapse = ", "))
+ }
+ }
+
+
+ weightcolname = ".WEIGHTS"
+ if (weightcolname %in% unlist(task$col_roles)) {
+ stopf("Weight column '%s' is already in the Task", weightcolname)
+ }
+
+ truth = task$truth()
+
+ class_frequency = prop.table(table(truth))
+ class_names = names(class_frequency)
+
+ weights_by_class = switch(pv$weight_method,
+ "inverse_class_frequency" = 1 / class_frequency,
+ "inverse_square_root_of_frequency" = 1 / sqrt(class_frequency),
+ "median_frequency_balancing" = median(class_frequency) / class_frequency,
+ "explicit" = pv$mapping
+ )
+
+ weights_table = data.table(weights_by_class[truth])
+ wcol = setnames(as.data.table(weights_table[[ncol(weights_table)]]), weightcolname)
+ task$cbind(wcol)
+ task$col_roles$feature = setdiff(task$col_roles$feature, weightcolname)
+
+
+ classif_roles = mlr_reflections$task_col_roles$classif
+ for (type in pv$weight_type) {
+ preferred_role = paste0("weights_", type)
+ final_role = if (preferred_role %in% classif_roles) preferred_role else "weight"
+ task$col_roles[[final_role]] = weightcolname
+ }
+ task
+ },
+
+ .predict_task = identity
+ )
+)
+
+mlr_pipeops$add("classweightsex", PipeOpClassWeightsEx)
diff --git a/attic/PipeOpClassWeightsEx - test code.R b/attic/PipeOpClassWeightsEx - test code.R
new file mode 100644
index 000000000..5dcd2f792
--- /dev/null
+++ b/attic/PipeOpClassWeightsEx - test code.R
@@ -0,0 +1,23 @@
+# library("mlr3")
+#
+#' task = tsk("spam")
+#' opb = po("classweightsex", param_vals = list(weight_method = "inverse_class_frequency"))
+#' opb = po("classweightsex", param_vals = list(weight_method = "inverse square root of frequency"))
+#' opb = po("classweightsex", param_vals = list(weight_method = "median frequency balancing"))
+# opb = po("classweightsex", param_vals = list(weight_method = "explicit", mapping = c("setosa" = 0.3, "virginica" = 0.5, "versicolor" = 0.4)))
+#
+# task weights
+# if ("weights_learner" %in% names(task)) {
+# task$weights_learner # recent mlr3-versions
+# } else {
+# task$weights # old mlr3-versions
+# }
+#
+# double the instances in the minority class (spam)
+# opb$param_set$values$minor_weight = 2
+# result = opb$train(list(task))[[1L]]
+# if ("weights_learner" %in% names(result)) {
+# result$weights_learner # recent mlr3-versions
+# } else {
+# result$weights # old mlr3-versions
+# }
diff --git a/man/PipeOp.Rd b/man/PipeOp.Rd
index f5921c3a0..4ced30e81 100644
--- a/man/PipeOp.Rd
+++ b/man/PipeOp.Rd
@@ -293,6 +293,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/PipeOpEncodePL.Rd b/man/PipeOpEncodePL.Rd
index 4407d32a0..6ab59bcca 100644
--- a/man/PipeOpEncodePL.Rd
+++ b/man/PipeOpEncodePL.Rd
@@ -117,6 +117,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/PipeOpEnsemble.Rd b/man/PipeOpEnsemble.Rd
index 415859086..7a153a929 100644
--- a/man/PipeOpEnsemble.Rd
+++ b/man/PipeOpEnsemble.Rd
@@ -114,6 +114,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/PipeOpImpute.Rd b/man/PipeOpImpute.Rd
index b8a2aa73f..203c69a76 100644
--- a/man/PipeOpImpute.Rd
+++ b/man/PipeOpImpute.Rd
@@ -180,6 +180,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/PipeOpTargetTrafo.Rd b/man/PipeOpTargetTrafo.Rd
index 99d957a39..277b2bec5 100644
--- a/man/PipeOpTargetTrafo.Rd
+++ b/man/PipeOpTargetTrafo.Rd
@@ -153,6 +153,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/PipeOpTaskPreproc.Rd b/man/PipeOpTaskPreproc.Rd
index 75afdab08..a054b2c16 100644
--- a/man/PipeOpTaskPreproc.Rd
+++ b/man/PipeOpTaskPreproc.Rd
@@ -210,6 +210,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/PipeOpTaskPreprocSimple.Rd b/man/PipeOpTaskPreprocSimple.Rd
index 9463f488d..4b4b50510 100644
--- a/man/PipeOpTaskPreprocSimple.Rd
+++ b/man/PipeOpTaskPreprocSimple.Rd
@@ -153,6 +153,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops.Rd b/man/mlr_pipeops.Rd
index c41449bbe..ff746f947 100644
--- a/man/mlr_pipeops.Rd
+++ b/man/mlr_pipeops.Rd
@@ -105,6 +105,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_adas.Rd b/man/mlr_pipeops_adas.Rd
index 33a094003..fec9dcbde 100644
--- a/man/mlr_pipeops_adas.Rd
+++ b/man/mlr_pipeops_adas.Rd
@@ -114,6 +114,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_blsmote.Rd b/man/mlr_pipeops_blsmote.Rd
index 08c6b0d8d..250c0a047 100644
--- a/man/mlr_pipeops_blsmote.Rd
+++ b/man/mlr_pipeops_blsmote.Rd
@@ -119,6 +119,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_boxcox.Rd b/man/mlr_pipeops_boxcox.Rd
index 1b672f56c..62e22ec3a 100644
--- a/man/mlr_pipeops_boxcox.Rd
+++ b/man/mlr_pipeops_boxcox.Rd
@@ -103,6 +103,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_branch.Rd b/man/mlr_pipeops_branch.Rd
index db449402b..59494bde7 100644
--- a/man/mlr_pipeops_branch.Rd
+++ b/man/mlr_pipeops_branch.Rd
@@ -116,6 +116,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_chunk.Rd b/man/mlr_pipeops_chunk.Rd
index c82b399bf..83ff1fa75 100644
--- a/man/mlr_pipeops_chunk.Rd
+++ b/man/mlr_pipeops_chunk.Rd
@@ -95,6 +95,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_classbalancing.Rd b/man/mlr_pipeops_classbalancing.Rd
index fd95b8cdc..b921a6477 100644
--- a/man/mlr_pipeops_classbalancing.Rd
+++ b/man/mlr_pipeops_classbalancing.Rd
@@ -137,6 +137,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_chunk}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_classifavg.Rd b/man/mlr_pipeops_classifavg.Rd
index beb232e55..db2f89bb1 100644
--- a/man/mlr_pipeops_classifavg.Rd
+++ b/man/mlr_pipeops_classifavg.Rd
@@ -110,6 +110,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_chunk}},
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_classweights.Rd b/man/mlr_pipeops_classweights.Rd
index 678b0c4fa..9dc137ea8 100644
--- a/man/mlr_pipeops_classweights.Rd
+++ b/man/mlr_pipeops_classweights.Rd
@@ -8,16 +8,17 @@
\code{\link[R6:R6Class]{R6Class}} object inheriting from \code{\link{PipeOpTaskPreproc}}/\code{\link{PipeOp}}.
}
\description{
-Adds a class weight column to the \code{\link[mlr3:Task]{Task}} that different \code{\link[mlr3:Learner]{Learner}}s may be
-able to use for sample weighting. Sample weights are added to each sample according to the target class.
+Adds a class weight column to the \code{\link[mlr3:Task]{Task}}, influencing how different \code{\link[mlr3:Learner]{Learner}}s weight samples during training.
+It is also possible to add a weight column to the \code{\link[mlr3:Task]{Task}}, which affects how samples are weighted during evaluation.
+Sample weights are assigned to each observation according to its target class.
Only binary \link[mlr3:TaskClassif]{classification tasks} are supported.
Caution: when constructed naively without parameter, the weights are all set to 1. The \code{minor_weight} parameter
must be adjusted for this \code{\link{PipeOp}} to be useful.
-Note this only sets the \code{"weights_learner"} column.
-It therefore influences the behaviour of subsequent \code{\link[mlr3:Learner]{Learner}}s, but does not influence resampling or evaluation metric weights.
+It is possible to set either one of the \code{"weights_learner"} and \code{"weights_measure"} columns, both of them or none of them.
+Thus, the behavior of subsequent \code{\link[mlr3:Learner]{Learner}}s or evaluation metric weights can be determined.
}
\section{Construction}{
@@ -25,9 +26,9 @@ It therefore influences the behaviour of subsequent \code{\link[mlr3:Learner]{Le
\if{html}{\out{
}}\preformatted{PipeOpClassWeights$new(id = "classweights", param_vals = list())
}\if{html}{\out{
}}
\itemize{
-\item \code{id} :: \code{character(1)}
+\item \code{id} :: \code{character(1)} \cr
Identifier of the resulting object, default \code{"classweights"}
-\item \code{param_vals} :: named \code{list}\cr
+\item \code{param_vals} :: named \code{list} \cr
List of hyperparameter settings, overwriting the hyperparameter settings that would otherwise be set during construction. Default \code{list()}.
}
}
@@ -52,16 +53,17 @@ The parameters are the parameters inherited from \code{\link{PipeOpTaskPreproc}}
\itemize{
\item \code{minor_weight} :: \code{numeric(1)} \cr
Weight given to samples of the minor class. Major class samples have weight 1. Initialized to 1.
+\item \code{weight_type} :: \code{character} \cr
+Determines whether \code{"weights_learner"}, \code{"weights_measure"}, both or none of the columns will be set. Defaults to \code{"learner"}. An empty
+vector leaves the task unchanged.
}
}
\section{Internals}{
-Introduces, or overwrites, the "weights" column in the \code{\link[mlr3:Task]{Task}}. However, the \code{\link[mlr3:Learner]{Learner}} method needs to
-respect weights for this to have an effect.
-
-The newly introduced column is named \code{.WEIGHTS}; there will be a naming conflict if this column already exists and is \emph{not} a
-weight column itself.
+Adds a \code{.WEIGHTS} column to the \code{\link[mlr3:Task]{Task}}, which is removed from the feature role and mapped to the requested weight roles.
+The \code{\link[mlr3:Learner]{Learner}} must support weights for this to have an effect. There will be a naming conflict if this column already
+exists and is \emph{not} as weight column itself.
}
\section{Fields}{
@@ -115,6 +117,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_chunk}},
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_classweightsex.Rd b/man/mlr_pipeops_classweightsex.Rd
new file mode 100644
index 000000000..8c13abddb
--- /dev/null
+++ b/man/mlr_pipeops_classweightsex.Rd
@@ -0,0 +1,190 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/PipeOpClassWeightsEx.R
+\name{mlr_pipeops_classweightsex}
+\alias{mlr_pipeops_classweightsex}
+\alias{PipeOpClassWeightsEx}
+\title{Class Weights for Sample Weighting - Extended}
+\format{
+\code{\link[R6:R6Class]{R6Class}} object inheriting from \code{\link{PipeOpTaskPreproc}}/\code{\link{PipeOp}}.
+}
+\description{
+Adds a class weight column to the \code{\link[mlr3:Task]{Task}}, influencing how different \code{\link[mlr3:Learner]{Learner}}s weight samples during training.
+It is also possible to add a weight column to the \code{\link[mlr3:Task]{Task}}, which affects how samples are weighted during evaluation.
+Sample weights are assigned to each observation according to its target class.
+
+Binary as well as multiclass \link[mlr3:TaskClassif]{classification tasks} are supported.
+
+It is possible to set either one of the \code{"weights_learner"} and \code{"weights_measure"} columns, both of them or none of them.
+Thus, the behavior of subsequent \code{\link[mlr3:Learner]{Learner}}s or evaluation metric weights can be determined.
+}
+\section{Construction}{
+
+
+\if{html}{\out{}}\preformatted{PipeOpClassWeightsEx$new(id = "classweightsex", param_vals = list())
+}\if{html}{\out{
}}
+\itemize{
+\item \code{id} :: \code{character(1)} \cr
+Identifier of the resulting object, default \code{"classweightsex"}
+\item \code{param_vals} :: named \code{list}\cr
+List of hyperparameter settings, overwriting the hyperparameter settings that would otherwise be set during construction. Default \code{list()}.
+}
+}
+
+\section{Input and Output Channels}{
+
+Input and output channels are inherited from \code{\link{PipeOpTaskPreproc}}. Instead of a \code{\link[mlr3:Task]{Task}}, a
+\code{\link[mlr3:TaskClassif]{TaskClassif}} is used as input and output during training and prediction.
+
+The output during training is the input \code{\link[mlr3:Task]{Task}} with added weights column according to target class.
+The output during prediction is the unchanged input.
+}
+
+\section{State}{
+
+The \verb{$state} is a named \code{list} with the \verb{$state} elements inherited from \code{\link{PipeOpTaskPreproc}}.
+}
+
+\section{Parameters}{
+
+The parameters are the parameters inherited from \code{\link{PipeOpTaskPreproc}}; however, the \code{affect_columns} parameter is \emph{not} present. Further parameters are:
+\itemize{
+\item \code{weight_type} :: \code{character} \cr
+Determines whether \code{"weights_learner"}, \code{"weights_measure"}, both or none of the columns will be set.
+\item \code{weight_method} :: \code{character(1)} \cr
+The method that is chosen to determine the weights of the samples. Methods encompass (\code{"inverse_class_frequency"}, \code{"inverse_square_root_of_frequency"}, \code{"median_frequency_balancing"}, \code{"explicit"}).
+\item \code{mapping} :: named \code{numeric} \cr
+Depends on \code{"weight_method" = "explicit"}. Must be a named numeric vector that specifies a finite weight for each target class in the task.
+}
+
+The newly introduced column is named \code{.WEIGHTS}; there will be a naming conflict if this column already exists and is \emph{not} a
+weight column itself.
+}
+
+\section{Internals}{
+
+The \code{.WEIGHTS} column is removed from the feature role and re-assigned to the requested weight roles. When \code{weight_method = "explicit"},
+the mapping must cover every class present in the training data and may not contain additional classes.
+}
+
+\section{Fields}{
+
+Only fields inherited from \code{\link{PipeOp}}.
+}
+
+\section{Methods}{
+
+Only methods inherited from \code{\link{PipeOpTaskPreproc}}/\code{\link{PipeOp}}.
+}
+
+\examples{
+library("mlr3")
+
+task = tsk("spam")
+
+poicf = po("classweightsex", param_vals = list(weight_type = c("learner", "measure"), weight_method = "inverse_class_frequency"))
+result = poicf$train(list(task))[[1L]]
+
+if ("weights_learner" \%in\% names(result)) {
+ result$weights_learner # recent mlr3-versions
+} else {
+ result$weights # old mlr3-versions
+}
+
+result$weights_measure
+
+
+if ("weights_measure" \%in\% names(result)) {
+ result$weights_measure # recent mlr3-versions
+} else {
+ result$weights # old mlr3-versions
+}
+}
+\seealso{
+https://mlr-org.com/pipeops.html
+
+Other PipeOps:
+\code{\link{PipeOp}},
+\code{\link{PipeOpEncodePL}},
+\code{\link{PipeOpEnsemble}},
+\code{\link{PipeOpImpute}},
+\code{\link{PipeOpTargetTrafo}},
+\code{\link{PipeOpTaskPreproc}},
+\code{\link{PipeOpTaskPreprocSimple}},
+\code{\link{mlr_pipeops}},
+\code{\link{mlr_pipeops_adas}},
+\code{\link{mlr_pipeops_blsmote}},
+\code{\link{mlr_pipeops_boxcox}},
+\code{\link{mlr_pipeops_branch}},
+\code{\link{mlr_pipeops_chunk}},
+\code{\link{mlr_pipeops_classbalancing}},
+\code{\link{mlr_pipeops_classifavg}},
+\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_colapply}},
+\code{\link{mlr_pipeops_collapsefactors}},
+\code{\link{mlr_pipeops_colroles}},
+\code{\link{mlr_pipeops_copy}},
+\code{\link{mlr_pipeops_datefeatures}},
+\code{\link{mlr_pipeops_decode}},
+\code{\link{mlr_pipeops_encode}},
+\code{\link{mlr_pipeops_encodeimpact}},
+\code{\link{mlr_pipeops_encodelmer}},
+\code{\link{mlr_pipeops_encodeplquantiles}},
+\code{\link{mlr_pipeops_encodepltree}},
+\code{\link{mlr_pipeops_featureunion}},
+\code{\link{mlr_pipeops_filter}},
+\code{\link{mlr_pipeops_fixfactors}},
+\code{\link{mlr_pipeops_histbin}},
+\code{\link{mlr_pipeops_ica}},
+\code{\link{mlr_pipeops_imputeconstant}},
+\code{\link{mlr_pipeops_imputehist}},
+\code{\link{mlr_pipeops_imputelearner}},
+\code{\link{mlr_pipeops_imputemean}},
+\code{\link{mlr_pipeops_imputemedian}},
+\code{\link{mlr_pipeops_imputemode}},
+\code{\link{mlr_pipeops_imputeoor}},
+\code{\link{mlr_pipeops_imputesample}},
+\code{\link{mlr_pipeops_kernelpca}},
+\code{\link{mlr_pipeops_learner}},
+\code{\link{mlr_pipeops_learner_pi_cvplus}},
+\code{\link{mlr_pipeops_learner_quantiles}},
+\code{\link{mlr_pipeops_missind}},
+\code{\link{mlr_pipeops_modelmatrix}},
+\code{\link{mlr_pipeops_multiplicityexply}},
+\code{\link{mlr_pipeops_multiplicityimply}},
+\code{\link{mlr_pipeops_mutate}},
+\code{\link{mlr_pipeops_nearmiss}},
+\code{\link{mlr_pipeops_nmf}},
+\code{\link{mlr_pipeops_nop}},
+\code{\link{mlr_pipeops_ovrsplit}},
+\code{\link{mlr_pipeops_ovrunite}},
+\code{\link{mlr_pipeops_pca}},
+\code{\link{mlr_pipeops_proxy}},
+\code{\link{mlr_pipeops_quantilebin}},
+\code{\link{mlr_pipeops_randomprojection}},
+\code{\link{mlr_pipeops_randomresponse}},
+\code{\link{mlr_pipeops_regravg}},
+\code{\link{mlr_pipeops_removeconstants}},
+\code{\link{mlr_pipeops_renamecolumns}},
+\code{\link{mlr_pipeops_replicate}},
+\code{\link{mlr_pipeops_rowapply}},
+\code{\link{mlr_pipeops_scale}},
+\code{\link{mlr_pipeops_scalemaxabs}},
+\code{\link{mlr_pipeops_scalerange}},
+\code{\link{mlr_pipeops_select}},
+\code{\link{mlr_pipeops_smote}},
+\code{\link{mlr_pipeops_smotenc}},
+\code{\link{mlr_pipeops_spatialsign}},
+\code{\link{mlr_pipeops_subsample}},
+\code{\link{mlr_pipeops_targetinvert}},
+\code{\link{mlr_pipeops_targetmutate}},
+\code{\link{mlr_pipeops_targettrafoscalerange}},
+\code{\link{mlr_pipeops_textvectorizer}},
+\code{\link{mlr_pipeops_threshold}},
+\code{\link{mlr_pipeops_tomek}},
+\code{\link{mlr_pipeops_tunethreshold}},
+\code{\link{mlr_pipeops_unbranch}},
+\code{\link{mlr_pipeops_updatetarget}},
+\code{\link{mlr_pipeops_vtreat}},
+\code{\link{mlr_pipeops_yeojohnson}}
+}
+\concept{PipeOps}
diff --git a/man/mlr_pipeops_colapply.Rd b/man/mlr_pipeops_colapply.Rd
index 11b1280c4..f68e8202a 100644
--- a/man/mlr_pipeops_colapply.Rd
+++ b/man/mlr_pipeops_colapply.Rd
@@ -126,6 +126,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
\code{\link{mlr_pipeops_copy}},
diff --git a/man/mlr_pipeops_collapsefactors.Rd b/man/mlr_pipeops_collapsefactors.Rd
index 60044c35b..5d7c530d0 100644
--- a/man/mlr_pipeops_collapsefactors.Rd
+++ b/man/mlr_pipeops_collapsefactors.Rd
@@ -129,6 +129,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_colroles}},
\code{\link{mlr_pipeops_copy}},
diff --git a/man/mlr_pipeops_colroles.Rd b/man/mlr_pipeops_colroles.Rd
index 6fe93c31a..7cfdbab93 100644
--- a/man/mlr_pipeops_colroles.Rd
+++ b/man/mlr_pipeops_colroles.Rd
@@ -107,6 +107,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_copy}},
diff --git a/man/mlr_pipeops_copy.Rd b/man/mlr_pipeops_copy.Rd
index be1a51822..151b2f4e8 100644
--- a/man/mlr_pipeops_copy.Rd
+++ b/man/mlr_pipeops_copy.Rd
@@ -112,6 +112,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_datefeatures.Rd b/man/mlr_pipeops_datefeatures.Rd
index a2fab76bb..cbad5feb4 100644
--- a/man/mlr_pipeops_datefeatures.Rd
+++ b/man/mlr_pipeops_datefeatures.Rd
@@ -137,6 +137,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_decode.Rd b/man/mlr_pipeops_decode.Rd
index 76b08510b..62004e0ea 100644
--- a/man/mlr_pipeops_decode.Rd
+++ b/man/mlr_pipeops_decode.Rd
@@ -172,6 +172,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_encode.Rd b/man/mlr_pipeops_encode.Rd
index bc286e459..6c61dc8a8 100644
--- a/man/mlr_pipeops_encode.Rd
+++ b/man/mlr_pipeops_encode.Rd
@@ -133,6 +133,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_encodeimpact.Rd b/man/mlr_pipeops_encodeimpact.Rd
index 33776ca10..5da848c75 100644
--- a/man/mlr_pipeops_encodeimpact.Rd
+++ b/man/mlr_pipeops_encodeimpact.Rd
@@ -117,6 +117,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_encodelmer.Rd b/man/mlr_pipeops_encodelmer.Rd
index 33cb75759..ba4c01b0b 100644
--- a/man/mlr_pipeops_encodelmer.Rd
+++ b/man/mlr_pipeops_encodelmer.Rd
@@ -129,6 +129,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_encodeplquantiles.Rd b/man/mlr_pipeops_encodeplquantiles.Rd
index 700611995..c83adfe2a 100644
--- a/man/mlr_pipeops_encodeplquantiles.Rd
+++ b/man/mlr_pipeops_encodeplquantiles.Rd
@@ -122,6 +122,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_encodepltree.Rd b/man/mlr_pipeops_encodepltree.Rd
index 2053eb2b5..8f2c85061 100644
--- a/man/mlr_pipeops_encodepltree.Rd
+++ b/man/mlr_pipeops_encodepltree.Rd
@@ -137,6 +137,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_featureunion.Rd b/man/mlr_pipeops_featureunion.Rd
index de03f667a..7fe182c43 100644
--- a/man/mlr_pipeops_featureunion.Rd
+++ b/man/mlr_pipeops_featureunion.Rd
@@ -130,6 +130,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_filter.Rd b/man/mlr_pipeops_filter.Rd
index 308e66011..cdd336f38 100644
--- a/man/mlr_pipeops_filter.Rd
+++ b/man/mlr_pipeops_filter.Rd
@@ -159,6 +159,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_fixfactors.Rd b/man/mlr_pipeops_fixfactors.Rd
index 2eba59b67..8c4e031b3 100644
--- a/man/mlr_pipeops_fixfactors.Rd
+++ b/man/mlr_pipeops_fixfactors.Rd
@@ -90,6 +90,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_histbin.Rd b/man/mlr_pipeops_histbin.Rd
index 3baeeb225..24010441f 100644
--- a/man/mlr_pipeops_histbin.Rd
+++ b/man/mlr_pipeops_histbin.Rd
@@ -102,6 +102,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_ica.Rd b/man/mlr_pipeops_ica.Rd
index 6de1101d2..6aab2770e 100644
--- a/man/mlr_pipeops_ica.Rd
+++ b/man/mlr_pipeops_ica.Rd
@@ -130,6 +130,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_imputeconstant.Rd b/man/mlr_pipeops_imputeconstant.Rd
index c2d42877b..67c331de6 100644
--- a/man/mlr_pipeops_imputeconstant.Rd
+++ b/man/mlr_pipeops_imputeconstant.Rd
@@ -110,6 +110,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_imputehist.Rd b/man/mlr_pipeops_imputehist.Rd
index a53263e3e..c02fe01ae 100644
--- a/man/mlr_pipeops_imputehist.Rd
+++ b/man/mlr_pipeops_imputehist.Rd
@@ -96,6 +96,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_imputelearner.Rd b/man/mlr_pipeops_imputelearner.Rd
index fb7c920a9..a1d1f14b8 100644
--- a/man/mlr_pipeops_imputelearner.Rd
+++ b/man/mlr_pipeops_imputelearner.Rd
@@ -135,6 +135,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_imputemean.Rd b/man/mlr_pipeops_imputemean.Rd
index a4b33fa0f..6de08f869 100644
--- a/man/mlr_pipeops_imputemean.Rd
+++ b/man/mlr_pipeops_imputemean.Rd
@@ -89,6 +89,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_imputemedian.Rd b/man/mlr_pipeops_imputemedian.Rd
index 8655e1ecc..5ecf5af43 100644
--- a/man/mlr_pipeops_imputemedian.Rd
+++ b/man/mlr_pipeops_imputemedian.Rd
@@ -89,6 +89,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_imputemode.Rd b/man/mlr_pipeops_imputemode.Rd
index b35b83b13..00dd07f89 100644
--- a/man/mlr_pipeops_imputemode.Rd
+++ b/man/mlr_pipeops_imputemode.Rd
@@ -96,6 +96,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_imputeoor.Rd b/man/mlr_pipeops_imputeoor.Rd
index 187c23acf..22f270c31 100644
--- a/man/mlr_pipeops_imputeoor.Rd
+++ b/man/mlr_pipeops_imputeoor.Rd
@@ -147,6 +147,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_imputesample.Rd b/man/mlr_pipeops_imputesample.Rd
index e80476851..f66520412 100644
--- a/man/mlr_pipeops_imputesample.Rd
+++ b/man/mlr_pipeops_imputesample.Rd
@@ -91,6 +91,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_kernelpca.Rd b/man/mlr_pipeops_kernelpca.Rd
index b18f5806f..015a9354a 100644
--- a/man/mlr_pipeops_kernelpca.Rd
+++ b/man/mlr_pipeops_kernelpca.Rd
@@ -105,6 +105,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_learner.Rd b/man/mlr_pipeops_learner.Rd
index aab63683b..5c65f98dd 100644
--- a/man/mlr_pipeops_learner.Rd
+++ b/man/mlr_pipeops_learner.Rd
@@ -131,6 +131,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_learner_pi_cvplus.Rd b/man/mlr_pipeops_learner_pi_cvplus.Rd
index 188718a80..da5d836f5 100644
--- a/man/mlr_pipeops_learner_pi_cvplus.Rd
+++ b/man/mlr_pipeops_learner_pi_cvplus.Rd
@@ -137,6 +137,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_learner_quantiles.Rd b/man/mlr_pipeops_learner_quantiles.Rd
index 88244f271..5b8357027 100644
--- a/man/mlr_pipeops_learner_quantiles.Rd
+++ b/man/mlr_pipeops_learner_quantiles.Rd
@@ -122,6 +122,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_missind.Rd b/man/mlr_pipeops_missind.Rd
index 578044460..ff3d6c28b 100644
--- a/man/mlr_pipeops_missind.Rd
+++ b/man/mlr_pipeops_missind.Rd
@@ -114,6 +114,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_modelmatrix.Rd b/man/mlr_pipeops_modelmatrix.Rd
index f13f6f6e0..f1649c389 100644
--- a/man/mlr_pipeops_modelmatrix.Rd
+++ b/man/mlr_pipeops_modelmatrix.Rd
@@ -95,6 +95,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_multiplicityexply.Rd b/man/mlr_pipeops_multiplicityexply.Rd
index 66f591560..50fadfe73 100644
--- a/man/mlr_pipeops_multiplicityexply.Rd
+++ b/man/mlr_pipeops_multiplicityexply.Rd
@@ -96,6 +96,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_multiplicityimply.Rd b/man/mlr_pipeops_multiplicityimply.Rd
index 2ac6cce80..98465b447 100644
--- a/man/mlr_pipeops_multiplicityimply.Rd
+++ b/man/mlr_pipeops_multiplicityimply.Rd
@@ -102,6 +102,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_mutate.Rd b/man/mlr_pipeops_mutate.Rd
index 8adb36b74..cec9c88af 100644
--- a/man/mlr_pipeops_mutate.Rd
+++ b/man/mlr_pipeops_mutate.Rd
@@ -107,6 +107,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_nearmiss.Rd b/man/mlr_pipeops_nearmiss.Rd
index 8d4898a66..e05d74e20 100644
--- a/man/mlr_pipeops_nearmiss.Rd
+++ b/man/mlr_pipeops_nearmiss.Rd
@@ -109,6 +109,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_nmf.Rd b/man/mlr_pipeops_nmf.Rd
index 7f0cfc265..b58f62327 100644
--- a/man/mlr_pipeops_nmf.Rd
+++ b/man/mlr_pipeops_nmf.Rd
@@ -152,6 +152,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_nop.Rd b/man/mlr_pipeops_nop.Rd
index 7526ba53d..afd12d239 100644
--- a/man/mlr_pipeops_nop.Rd
+++ b/man/mlr_pipeops_nop.Rd
@@ -92,6 +92,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_ovrsplit.Rd b/man/mlr_pipeops_ovrsplit.Rd
index 062e086f8..9b20e2f77 100644
--- a/man/mlr_pipeops_ovrsplit.Rd
+++ b/man/mlr_pipeops_ovrsplit.Rd
@@ -109,6 +109,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_ovrunite.Rd b/man/mlr_pipeops_ovrunite.Rd
index 3ce033902..4e41972d3 100644
--- a/man/mlr_pipeops_ovrunite.Rd
+++ b/man/mlr_pipeops_ovrunite.Rd
@@ -104,6 +104,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_pca.Rd b/man/mlr_pipeops_pca.Rd
index 4b8245e41..66a335fdf 100644
--- a/man/mlr_pipeops_pca.Rd
+++ b/man/mlr_pipeops_pca.Rd
@@ -106,6 +106,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_proxy.Rd b/man/mlr_pipeops_proxy.Rd
index d1b92cf65..5bdb2a034 100644
--- a/man/mlr_pipeops_proxy.Rd
+++ b/man/mlr_pipeops_proxy.Rd
@@ -114,6 +114,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_quantilebin.Rd b/man/mlr_pipeops_quantilebin.Rd
index 3570d0503..88933e7f7 100644
--- a/man/mlr_pipeops_quantilebin.Rd
+++ b/man/mlr_pipeops_quantilebin.Rd
@@ -94,6 +94,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_randomprojection.Rd b/man/mlr_pipeops_randomprojection.Rd
index 486c91d5f..7422ce25c 100644
--- a/man/mlr_pipeops_randomprojection.Rd
+++ b/man/mlr_pipeops_randomprojection.Rd
@@ -106,6 +106,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_randomresponse.Rd b/man/mlr_pipeops_randomresponse.Rd
index e3331d268..5b71e7c5f 100644
--- a/man/mlr_pipeops_randomresponse.Rd
+++ b/man/mlr_pipeops_randomresponse.Rd
@@ -118,6 +118,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_regravg.Rd b/man/mlr_pipeops_regravg.Rd
index 76fac8eb0..7ecb472ca 100644
--- a/man/mlr_pipeops_regravg.Rd
+++ b/man/mlr_pipeops_regravg.Rd
@@ -104,6 +104,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_removeconstants.Rd b/man/mlr_pipeops_removeconstants.Rd
index 3da03d8ce..73b951bbb 100644
--- a/man/mlr_pipeops_removeconstants.Rd
+++ b/man/mlr_pipeops_removeconstants.Rd
@@ -94,6 +94,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_renamecolumns.Rd b/man/mlr_pipeops_renamecolumns.Rd
index 131433937..9284f3b46 100644
--- a/man/mlr_pipeops_renamecolumns.Rd
+++ b/man/mlr_pipeops_renamecolumns.Rd
@@ -93,6 +93,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_replicate.Rd b/man/mlr_pipeops_replicate.Rd
index 9d015566d..bbc0c796c 100644
--- a/man/mlr_pipeops_replicate.Rd
+++ b/man/mlr_pipeops_replicate.Rd
@@ -86,6 +86,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_rowapply.Rd b/man/mlr_pipeops_rowapply.Rd
index 62226792b..0d9ab6485 100644
--- a/man/mlr_pipeops_rowapply.Rd
+++ b/man/mlr_pipeops_rowapply.Rd
@@ -92,6 +92,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_scale.Rd b/man/mlr_pipeops_scale.Rd
index 3bf30b521..363d5e49d 100644
--- a/man/mlr_pipeops_scale.Rd
+++ b/man/mlr_pipeops_scale.Rd
@@ -113,6 +113,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_scalemaxabs.Rd b/man/mlr_pipeops_scalemaxabs.Rd
index 011f75107..61870330a 100644
--- a/man/mlr_pipeops_scalemaxabs.Rd
+++ b/man/mlr_pipeops_scalemaxabs.Rd
@@ -83,6 +83,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_scalerange.Rd b/man/mlr_pipeops_scalerange.Rd
index 48af7d223..f18be1080 100644
--- a/man/mlr_pipeops_scalerange.Rd
+++ b/man/mlr_pipeops_scalerange.Rd
@@ -93,6 +93,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_select.Rd b/man/mlr_pipeops_select.Rd
index 7d678830b..8a4ae3d98 100644
--- a/man/mlr_pipeops_select.Rd
+++ b/man/mlr_pipeops_select.Rd
@@ -105,6 +105,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_smote.Rd b/man/mlr_pipeops_smote.Rd
index 0bfd310db..d9c63e967 100644
--- a/man/mlr_pipeops_smote.Rd
+++ b/man/mlr_pipeops_smote.Rd
@@ -111,6 +111,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_smotenc.Rd b/man/mlr_pipeops_smotenc.Rd
index 5a231bb2a..ad5465c4f 100644
--- a/man/mlr_pipeops_smotenc.Rd
+++ b/man/mlr_pipeops_smotenc.Rd
@@ -123,6 +123,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_spatialsign.Rd b/man/mlr_pipeops_spatialsign.Rd
index efad79930..ff1aa36df 100644
--- a/man/mlr_pipeops_spatialsign.Rd
+++ b/man/mlr_pipeops_spatialsign.Rd
@@ -88,6 +88,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_subsample.Rd b/man/mlr_pipeops_subsample.Rd
index 6cd121c46..563909b24 100644
--- a/man/mlr_pipeops_subsample.Rd
+++ b/man/mlr_pipeops_subsample.Rd
@@ -113,6 +113,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_targetinvert.Rd b/man/mlr_pipeops_targetinvert.Rd
index 33f65c50c..fd9cb3040 100644
--- a/man/mlr_pipeops_targetinvert.Rd
+++ b/man/mlr_pipeops_targetinvert.Rd
@@ -83,6 +83,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_targetmutate.Rd b/man/mlr_pipeops_targetmutate.Rd
index b348d1ce3..9226c6a76 100644
--- a/man/mlr_pipeops_targetmutate.Rd
+++ b/man/mlr_pipeops_targetmutate.Rd
@@ -131,6 +131,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_targettrafoscalerange.Rd b/man/mlr_pipeops_targettrafoscalerange.Rd
index 8400551c5..416172a88 100644
--- a/man/mlr_pipeops_targettrafoscalerange.Rd
+++ b/man/mlr_pipeops_targettrafoscalerange.Rd
@@ -102,6 +102,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_textvectorizer.Rd b/man/mlr_pipeops_textvectorizer.Rd
index d40503694..291adcae9 100644
--- a/man/mlr_pipeops_textvectorizer.Rd
+++ b/man/mlr_pipeops_textvectorizer.Rd
@@ -207,6 +207,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_threshold.Rd b/man/mlr_pipeops_threshold.Rd
index d8aa2fa5c..bcb428b5b 100644
--- a/man/mlr_pipeops_threshold.Rd
+++ b/man/mlr_pipeops_threshold.Rd
@@ -96,6 +96,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_tomek.Rd b/man/mlr_pipeops_tomek.Rd
index 7a3bee4bd..7fd6ae37e 100644
--- a/man/mlr_pipeops_tomek.Rd
+++ b/man/mlr_pipeops_tomek.Rd
@@ -102,6 +102,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_tunethreshold.Rd b/man/mlr_pipeops_tunethreshold.Rd
index f2707ef05..973d61771 100644
--- a/man/mlr_pipeops_tunethreshold.Rd
+++ b/man/mlr_pipeops_tunethreshold.Rd
@@ -122,6 +122,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_unbranch.Rd b/man/mlr_pipeops_unbranch.Rd
index f79719aed..02b74d9fa 100644
--- a/man/mlr_pipeops_unbranch.Rd
+++ b/man/mlr_pipeops_unbranch.Rd
@@ -95,6 +95,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_updatetarget.Rd b/man/mlr_pipeops_updatetarget.Rd
index 263b41ff3..988840ace 100644
--- a/man/mlr_pipeops_updatetarget.Rd
+++ b/man/mlr_pipeops_updatetarget.Rd
@@ -115,6 +115,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_vtreat.Rd b/man/mlr_pipeops_vtreat.Rd
index 81514f09d..e6b52bdcc 100644
--- a/man/mlr_pipeops_vtreat.Rd
+++ b/man/mlr_pipeops_vtreat.Rd
@@ -169,6 +169,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/man/mlr_pipeops_yeojohnson.Rd b/man/mlr_pipeops_yeojohnson.Rd
index f1823e343..def9dc73f 100644
--- a/man/mlr_pipeops_yeojohnson.Rd
+++ b/man/mlr_pipeops_yeojohnson.Rd
@@ -105,6 +105,7 @@ Other PipeOps:
\code{\link{mlr_pipeops_classbalancing}},
\code{\link{mlr_pipeops_classifavg}},
\code{\link{mlr_pipeops_classweights}},
+\code{\link{mlr_pipeops_classweightsex}},
\code{\link{mlr_pipeops_colapply}},
\code{\link{mlr_pipeops_collapsefactors}},
\code{\link{mlr_pipeops_colroles}},
diff --git a/tests/testthat/test_pipeop_classweights.R b/tests/testthat/test_pipeop_classweights.R
index 17bf67b94..4624423ae 100644
--- a/tests/testthat/test_pipeop_classweights.R
+++ b/tests/testthat/test_pipeop_classweights.R
@@ -12,16 +12,47 @@ test_that("PipeOpClassWeights - basic properties", {
})
test_that("PipeOpClassWeights", {
- op = PipeOpClassWeights$new()
+
+ op = po("classweights")
task = mlr_tasks$get("pima")
- op$param_set$values = list(minor_weight = 3)
+ op$param_set$values$minor_weight = 3
nt = op$train(list(task))[[1L]]
expect_equal(nt$data(), task$data())
-
weights = if ("weights_learner" %in% names(nt)) "weights_learner" else "weights"
expect_equal(nt[[weights]]$weight, ifelse(nt$truth(nt[[weights]]$row_ids) == "neg", 1, 3))
+})
+
+test_that("PipeOpClassWeights - weight roles assigned", {
+ task = mlr_tasks$get("pima")
+ classif_roles = mlr_reflections$task_col_roles$classif
+ configs = list(
+ weight_type = "learner",
+ weight_type = "measure",
+ weight_type = c("learner", "measure"),
+ weight_type = character()
+ )
+
+ for (cfg in configs) {
+ task_clone = task$clone(deep = TRUE)
+ po_roles = po("classweights", param_vals = list(
+ minor_weight = 2,
+ weight_type = cfg))
+ nt = po_roles$train(list(task_clone))[[1L]]
+ weightcolname = ".WEIGHTS"
+
+ if (length(cfg) == 0) {
+ expect_false(weightcolname %in% unlist(nt$col_roles))
+ next
+ }
+ expect_false(weightcolname %in% nt$col_roles$feature)
+ for (type in cfg) {
+ preferred_role = paste0("weights_", type)
+ final_role = if (preferred_role %in% classif_roles) preferred_role else "weight"
+ expect_true(weightcolname %in% nt$col_roles[[final_role]])
+ }
+ }
})
test_that("PipeOpClassWeights - error for Tasks without weights property, #937", {
diff --git a/tests/testthat/test_pipeop_classweightsex.R b/tests/testthat/test_pipeop_classweightsex.R
new file mode 100644
index 000000000..f9311ccf2
--- /dev/null
+++ b/tests/testthat/test_pipeop_classweightsex.R
@@ -0,0 +1,124 @@
+
+test_that("PipeOpClassWeightsEx - basic properties", {
+ op = PipeOpClassWeightsEx$new()
+ task = mlr_tasks$get("german_credit")
+ expect_pipeop(op)
+ train_pipeop(op, inputs = list(task))
+ predict_pipeop(op, inputs = list(task))
+
+ expect_datapreproc_pipeop_class(PipeOpClassWeightsEx, task = task,
+ predict_like_train = FALSE)
+})
+
+test_that("PipeOpClassWeightsEx - error for Tasks without weights property, #937", {
+ skip_if_not_installed("mlr3learners")
+ skip_if_not_installed("MASS")
+
+ set.seed(1234)
+ task = as_task_classif(data.table(
+ y = factor(rep(c("A", "B", "A", "C"), 4)),
+ x = runif(16)
+ ), target = "y")
+
+ # no error: Learner has weights property
+ gr = po("classweightsex", param_vals = list(mapping = c("A" = 0.6, "B" = 0.3, "C" = 0.1))) %>>% lrn("classif.featureless")
+ expect_no_error(gr$train(task))
+
+ # error: Learner does not have weights property
+ gr = po("classweightsex", param_vals = list(mapping = c("A" = 0.6, "B" = 0.3, "C" = 0.1))) %>>% lrn("classif.lda")
+ expect_error(gr$train(task), ".*Learner does not support weights.*")
+
+ # no error: use_weights is set to "ignore"
+ gr = po("classweightsex", param_vals = list(mapping = c("A" = 0.6, "B" = 0.4, "C" = 0.1))) %>>% lrn("classif.lda", use_weights = "ignore")
+ expect_no_error(gr$train(task))
+
+})
+
+test_that("PipeOpClassWeightsEx", {
+
+ task = mlr_tasks$get("penguins")
+
+ # Method inverse_class_frequency
+ poicf = po("classweightsex", param_vals = list(weight_method = "inverse_class_frequency"))
+ nt = poicf$train(list(task))[[1L]]
+ expect_equal(nt$data(), task$data())
+
+ freq = prop.table(table(task$truth()))
+ manual_weights = 1 / freq[task$truth()]
+
+ if ("weights_learner" %in% names(nt$col_roles)) {
+ computed_weights = nt$weights_learner
+ } else {
+ computed_weights = nt$weights
+ }
+
+ expect_equal(computed_weights[["weight"]], as.numeric(unclass(manual_weights)))
+
+ # Method inverse square root of class frequency
+ poisf = po("classweightsex", param_vals = list(weight_method = "inverse_square_root_of_frequency"))
+ nt = poisf$train(list(task))[[1L]]
+ expect_equal(nt$data(), task$data())
+
+ freq = prop.table(table(task$truth()))
+ manual_weights = 1 / sqrt(freq[task$truth()])
+
+ if ("weights_learner" %in% names(nt$col_roles)) {
+ computed_weights = nt$weights_learner
+ } else {
+ computed_weights = nt$weights
+ }
+
+ expect_equal(computed_weights[["weight"]], as.numeric(unclass(manual_weights)))
+
+ # Method median frequency balancing
+ pomfb = po("classweightsex", param_vals = list(weight_method = "median_frequency_balancing"))
+ nt = pomfb$train(list(task))[[1L]]
+ expect_equal(nt$data(), task$data())
+
+ freq = prop.table(table(task$truth()))
+ manual_weights = median(freq[task$truth()]) / freq[task$truth()]
+
+ if ("weights_learner" %in% names(nt$col_roles)) {
+ computed_weights = nt$weights_learner
+ } else {
+ computed_weights = nt$weights
+ }
+
+ expect_equal(computed_weights[["weight"]], as.numeric(unclass(manual_weights)))
+
+})
+
+test_that("PipeOpClassWeightsEx - explicit mapping must cover all classes", {
+ task = mlr_tasks$get("penguins")
+ po_explicit = po("classweightsex", param_vals = list(
+ weight_method = "explicit",
+ mapping = c("Adelie" = 0.5, "Chinstrap" = 0.3)
+ ))
+ expect_error(
+ po_explicit$train(list(task)),
+ "missing.*class",
+ fixed = FALSE
+ )
+})
+
+test_that("PipeOpClassWeightsEx - weight roles assigned", {
+ classif_roles = mlr_reflections$task_col_roles$classif
+ configs = list(
+ "learner",
+ "measure",
+ c("learner", "measure")
+ )
+
+ for (wt in configs) {
+ task = mlr_tasks$get("penguins")
+ po_roles = po("classweightsex", param_vals = list(weight_method = "inverse_class_frequency", weight_type = wt))
+ nt = po_roles$train(list(task))[[1L]]
+ weightcolname = ".WEIGHTS"
+ expect_false(weightcolname %in% nt$col_roles$feature)
+ for (type in wt) {
+ preferred_role = paste0("weights_", type)
+ final_role = if (preferred_role %in% classif_roles) preferred_role else "weight"
+ expect_true(weightcolname %in% nt$col_roles[[final_role]])
+ }
+ }
+})