From 7e808409f907172e09813c495571258b4a4efffd Mon Sep 17 00:00:00 2001 From: Alexander Winterstetter Date: Mon, 20 Oct 2025 08:19:21 +0200 Subject: [PATCH 01/18] one blank line added --- R/PipeOpClassWeights.R | 1 + 1 file changed, 1 insertion(+) diff --git a/R/PipeOpClassWeights.R b/R/PipeOpClassWeights.R index bf7588423..03d0baa89 100644 --- a/R/PipeOpClassWeights.R +++ b/R/PipeOpClassWeights.R @@ -94,6 +94,7 @@ PipeOpClassWeights = R6Class("PipeOpClassWeights", .train_task = function(task) { + if ("twoclass" %nin% task$properties) { stop("Only binary classification Tasks are supported.") } From 74b68d78ff63cbe93cbe64c83b920bea50b8de9d Mon Sep 17 00:00:00 2001 From: Alexander Winterstetter Date: Mon, 20 Oct 2025 12:45:30 +0200 Subject: [PATCH 02/18] added weight_type HP in PipeOpClassWeights --- R/PipeOpClassWeights.R | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/R/PipeOpClassWeights.R b/R/PipeOpClassWeights.R index 03d0baa89..61f511251 100644 --- a/R/PipeOpClassWeights.R +++ b/R/PipeOpClassWeights.R @@ -84,17 +84,15 @@ PipeOpClassWeights = R6Class("PipeOpClassWeights", public = list( initialize = function(id = "classweights", param_vals = list()) { ps = ps( - minor_weight = p_dbl(lower = 0, upper = Inf, tags = "train") + minor_weight = p_dbl(init = 1, lower = 0, upper = Inf, tags = "train"), + weight_type = p_uty(init = c("learner", "measure"), tags = "train") ) - ps$values = list(minor_weight = 1) 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) { - - if ("twoclass" %nin% task$properties) { stop("Only binary classification Tasks are supported.") } @@ -111,10 +109,19 @@ PipeOpClassWeights = R6Class("PipeOpClassWeights", 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 + if ("learner" %in% self$param_set$values$weight_type) { + if ("weights_learner" %in% mlr_reflections$task_col_roles$classif) { + task$col_roles$weights_learner = weightcolname + } else { + task$col_roles$weight = weightcolname + } + } + if ("measure" %in% self$param_set$values$weight_type) { + if ("weights_measure" %in% mlr_reflections$task_col_roles$classif) { + task$col_roles$weights_measure = weightcolname + } else { + task$col_roles$weight = weightcolname + } } task }, From 7831975c08ebc4e854ab7d7f3d273d231970a967 Mon Sep 17 00:00:00 2001 From: Alexander Winterstetter Date: Mon, 20 Oct 2025 13:57:47 +0200 Subject: [PATCH 03/18] setup of PipeOpClassWeightsEx --- R/PipeOpClassWeightsEx.R | 86 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 R/PipeOpClassWeightsEx.R diff --git a/R/PipeOpClassWeightsEx.R b/R/PipeOpClassWeightsEx.R new file mode 100644 index 000000000..d1400dd7e --- /dev/null +++ b/R/PipeOpClassWeightsEx.R @@ -0,0 +1,86 @@ +#' 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")) +#' +#' # 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 +#' } + +PipeOpClassWeightsEx = R6Class("PipeOpClassWeightsEx", + inherit = PipeOpTaskPreproc, + + public = list( + initialize = function(id = "classweightsex", param_vals = list()) { + ps = ps( + weight_type = p_uty(init = c("learner", "measure"), tags = "train"), + 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 = "train"), + mapping = p_uty(tags = "train") + ) + 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) { + browser() + #if ("twoclass" %nin% task$properties) { + # stop("Only binary classification Tasks are supported.") + #} + + weightcolname = ".WEIGHTS" + if (weightcolname %in% unlist(task$col_roles)) { + stopf("Weight column '%s' is already in the Task", weightcolname) + } + + truth = task$truth() + minor = names(which.min(table(task$truth()))) + class_frequency = table(truth) / length(truth) + if (self$param_set$values$weight_method == "inverse class frequency") { + wcol = setnames(data.table(truth)[data.table(class_frequency^-1), on = .(truth)][, "N"], weightcolname) + } else if (self$param_set$values$weight_method == "inverse square root of frequency") { + wcol = setnames(data.table(truth)[data.table((class_frequency^0.5)^-1), on = .(truth)][, "N"], weightcolname) + } else if (self$param_set$values$weight_method == "median frequency balancing") { + wcol = setnames(data.table(truth)[data.table(median(class_frequency) / class_frequency), on = .(truth)][, "N"], weightcolname) + } else if (self$param_set$values$weight_method == "explicit") { + task$cbind(data.table(.WEIGHTS = mapping[task$truth()])) + } + task$cbind(wcol) + task$col_roles$feature = setdiff(task$col_roles$feature, weightcolname) + if ("learner" %in% self$param_set$values$weight_type) { + if ("weights_learner" %in% mlr_reflections$task_col_roles$classif) { + task$col_roles$weights_learner = weightcolname + } else { + task$col_roles$weight = weightcolname + } + } + if ("measure" %in% self$param_set$values$weight_type) { + if ("weights_measure" %in% mlr_reflections$task_col_roles$classif) { + task$col_roles$weights_measure = weightcolname + } else { + task$col_roles$weight = weightcolname + } + } + task + }, + + .predict_task = identity + ) +) + +mlr_pipeops$add("classweightsex", PipeOpClassWeightsEx) + From 622b8bff7115670dbac491a070675256da058d7d Mon Sep 17 00:00:00 2001 From: Alexander Winterstetter Date: Mon, 20 Oct 2025 16:31:24 +0200 Subject: [PATCH 04/18] fixes for explicit weight_method --- R/PipeOpClassWeightsEx.R | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/R/PipeOpClassWeightsEx.R b/R/PipeOpClassWeightsEx.R index d1400dd7e..021a3021a 100644 --- a/R/PipeOpClassWeightsEx.R +++ b/R/PipeOpClassWeightsEx.R @@ -4,6 +4,7 @@ #' 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)) { @@ -57,7 +58,7 @@ PipeOpClassWeightsEx = R6Class("PipeOpClassWeightsEx", } else if (self$param_set$values$weight_method == "median frequency balancing") { wcol = setnames(data.table(truth)[data.table(median(class_frequency) / class_frequency), on = .(truth)][, "N"], weightcolname) } else if (self$param_set$values$weight_method == "explicit") { - task$cbind(data.table(.WEIGHTS = mapping[task$truth()])) + wcol = data.table(.WEIGHTS = self$param_set$values$mapping[task$truth()]) } task$cbind(wcol) task$col_roles$feature = setdiff(task$col_roles$feature, weightcolname) From 5674f4ee3686fae6d345fc55a2656b66704d1ce5 Mon Sep 17 00:00:00 2001 From: Alexander Winterstetter Date: Mon, 20 Oct 2025 16:48:43 +0200 Subject: [PATCH 05/18] fixed error in test --- tests/testthat/test_pipeop_classweights.R | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/testthat/test_pipeop_classweights.R b/tests/testthat/test_pipeop_classweights.R index 17bf67b94..bdc62efa1 100644 --- a/tests/testthat/test_pipeop_classweights.R +++ b/tests/testthat/test_pipeop_classweights.R @@ -12,16 +12,15 @@ 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 - error for Tasks without weights property, #937", { From 4d1a0df31eb30443b6defe1f8601f374300cb3bb Mon Sep 17 00:00:00 2001 From: Alexander Winterstetter Date: Mon, 20 Oct 2025 18:56:17 +0200 Subject: [PATCH 06/18] added PipeOpClassWeightsEx to DESCRIPTION --- DESCRIPTION | 1 + 1 file changed, 1 insertion(+) 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' From f161f67223e4c1434eb59308e99e982c30f3d460 Mon Sep 17 00:00:00 2001 From: Alexander Winterstetter Date: Tue, 21 Oct 2025 10:37:21 +0200 Subject: [PATCH 07/18] executed devtools::document() --- man/PipeOpClassWeightsEx.Rd | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 man/PipeOpClassWeightsEx.Rd diff --git a/man/PipeOpClassWeightsEx.Rd b/man/PipeOpClassWeightsEx.Rd new file mode 100644 index 000000000..9f6dea1ed --- /dev/null +++ b/man/PipeOpClassWeightsEx.Rd @@ -0,0 +1,30 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/PipeOpClassWeightsEx.R +\name{PipeOpClassWeightsEx} +\alias{PipeOpClassWeightsEx} +\title{library("mlr3")} +\description{ +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))) +} +\section{task weights}{ +if ("weights_learner" \%in\% names(task)) { +task$weights_learner # recent mlr3-versions +} else { +task$weights # old mlr3-versions +} +} + +\section{double the instances in the minority class (spam)}{ +opb$param_set$values$minor_weight = 2 +result = opb$train(list(task))[\link{1L}] +if ("weights_learner" \%in\% names(result)) { +result$weights_learner # recent mlr3-versions +} else { +result$weights # old mlr3-versions +} +} + From 0805eb605016d9641d9923df6bcdb0fa03229852 Mon Sep 17 00:00:00 2001 From: Alexander Winterstetter Date: Tue, 21 Oct 2025 15:14:01 +0200 Subject: [PATCH 08/18] fixed documentation for PipeOpClassWeightsEx --- NAMESPACE | 1 + R/PipeOpClassWeightsEx.R | 88 ++++++++++++++++- man/PipeOpClassWeightsEx.Rd | 30 ------ man/mlr_pipeops_classweights.Rd | 163 +++++++++++++++++++++++++++++++- 4 files changed, 247 insertions(+), 35 deletions(-) delete mode 100644 man/PipeOpClassWeightsEx.Rd 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/PipeOpClassWeightsEx.R b/R/PipeOpClassWeightsEx.R index 021a3021a..59ee4d49c 100644 --- a/R/PipeOpClassWeightsEx.R +++ b/R/PipeOpClassWeightsEx.R @@ -1,10 +1,67 @@ +#' @title Class Weights for Sample - Extended +#' +#' @usage NULL +#' @name mlr_pipeops_classweights +#' @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. +#' +#' 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. +#' +#' @section Construction: +#' ``` +#' PipeOpClassWeights$new(id = "classweights", param_vals = list()) +#' ``` +#' +#' * `id` :: `character(1)` +#' Identifier of the resulting object, default `"classweights"` +#' * `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: +#' * `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. +#' +#' 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 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") -#' 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))) +#' opb = po("classweights") #' #' # task weights #' if ("weights_learner" %in% names(task)) { @@ -85,3 +142,26 @@ PipeOpClassWeightsEx = R6Class("PipeOpClassWeightsEx", mlr_pipeops$add("classweightsex", PipeOpClassWeightsEx) +# 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/PipeOpClassWeightsEx.Rd b/man/PipeOpClassWeightsEx.Rd deleted file mode 100644 index 9f6dea1ed..000000000 --- a/man/PipeOpClassWeightsEx.Rd +++ /dev/null @@ -1,30 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/PipeOpClassWeightsEx.R -\name{PipeOpClassWeightsEx} -\alias{PipeOpClassWeightsEx} -\title{library("mlr3")} -\description{ -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))) -} -\section{task weights}{ -if ("weights_learner" \%in\% names(task)) { -task$weights_learner # recent mlr3-versions -} else { -task$weights # old mlr3-versions -} -} - -\section{double the instances in the minority class (spam)}{ -opb$param_set$values$minor_weight = 2 -result = opb$train(list(task))[\link{1L}] -if ("weights_learner" \%in\% names(result)) { -result$weights_learner # recent mlr3-versions -} else { -result$weights # old mlr3-versions -} -} - diff --git a/man/mlr_pipeops_classweights.Rd b/man/mlr_pipeops_classweights.Rd index 678b0c4fa..bb7760bca 100644 --- a/man/mlr_pipeops_classweights.Rd +++ b/man/mlr_pipeops_classweights.Rd @@ -1,10 +1,13 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/PipeOpClassWeights.R +% Please edit documentation in R/PipeOpClassWeights.R, R/PipeOpClassWeightsEx.R \name{mlr_pipeops_classweights} \alias{mlr_pipeops_classweights} \alias{PipeOpClassWeights} +\alias{PipeOpClassWeightsEx} \title{Class Weights for Sample Weighting} \format{ +\code{\link[R6:R6Class]{R6Class}} object inheriting from \code{\link{PipeOpTaskPreproc}}/\code{\link{PipeOp}}. + \code{\link[R6:R6Class]{R6Class}} object inheriting from \code{\link{PipeOpTaskPreproc}}/\code{\link{PipeOp}}. } \description{ @@ -16,12 +19,34 @@ 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. + +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. + +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. } \section{Construction}{ +\if{html}{\out{
}}\preformatted{PipeOpClassWeights$new(id = "classweights", param_vals = list()) +}\if{html}{\out{
}} +\itemize{ +\item \code{id} :: \code{character(1)} +Identifier of the resulting object, default \code{"classweights"} +\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()}. +} + + + \if{html}{\out{
}}\preformatted{PipeOpClassWeights$new(id = "classweights", param_vals = list()) }\if{html}{\out{
}} \itemize{ @@ -34,6 +59,13 @@ List of hyperparameter settings, overwriting the hyperparameter settings that wo \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. + + 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. @@ -43,11 +75,21 @@ 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}}. + + 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{minor_weight} :: \code{numeric(1)} \cr +Weight given to samples of the minor class. Major class samples have weight 1. Initialized to 1. +} + + 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{minor_weight} :: \code{numeric(1)} \cr @@ -57,6 +99,13 @@ Weight given to samples of the minor class. Major class samples have weight 1. I \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. + + 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. @@ -66,11 +115,17 @@ weight column itself. \section{Fields}{ +Only fields inherited from \code{\link{PipeOp}}. + + Only fields inherited from \code{\link{PipeOp}}. } \section{Methods}{ +Only methods inherited from \code{\link{PipeOpTaskPreproc}}/\code{\link{PipeOp}}. + + Only methods inherited from \code{\link{PipeOpTaskPreproc}}/\code{\link{PipeOp}}. } @@ -87,6 +142,26 @@ if ("weights_learner" \%in\% names(task)) { 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 +} +library("mlr3") + +task = tsk("spam") +opb = po("classweights") + +# 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]] @@ -99,6 +174,92 @@ if ("weights_learner" \%in\% names(result)) { \seealso{ https://mlr-org.com/pipeops.html +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_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}} + Other PipeOps: \code{\link{PipeOp}}, \code{\link{PipeOpEncodePL}}, From 7edf0e4d3847c4a4a32ef007fd3870ce63d98792 Mon Sep 17 00:00:00 2001 From: Alexander Winterstetter Date: Tue, 21 Oct 2025 15:36:05 +0200 Subject: [PATCH 09/18] performed devtools::document() appropriately --- R/PipeOpClassWeightsEx.R | 2 +- man/PipeOp.Rd | 1 + man/PipeOpEncodePL.Rd | 1 + man/PipeOpEnsemble.Rd | 1 + man/PipeOpImpute.Rd | 1 + man/PipeOpTargetTrafo.Rd | 1 + man/PipeOpTaskPreproc.Rd | 1 + man/PipeOpTaskPreprocSimple.Rd | 1 + man/mlr_pipeops.Rd | 1 + man/mlr_pipeops_adas.Rd | 1 + man/mlr_pipeops_blsmote.Rd | 1 + man/mlr_pipeops_boxcox.Rd | 1 + man/mlr_pipeops_branch.Rd | 1 + man/mlr_pipeops_chunk.Rd | 1 + man/mlr_pipeops_classbalancing.Rd | 1 + man/mlr_pipeops_classifavg.Rd | 1 + man/mlr_pipeops_classweights.Rd | 164 +------------------- man/mlr_pipeops_classweightsex.Rd | 187 +++++++++++++++++++++++ man/mlr_pipeops_colapply.Rd | 1 + man/mlr_pipeops_collapsefactors.Rd | 1 + man/mlr_pipeops_colroles.Rd | 1 + man/mlr_pipeops_copy.Rd | 1 + man/mlr_pipeops_datefeatures.Rd | 1 + man/mlr_pipeops_decode.Rd | 1 + man/mlr_pipeops_encode.Rd | 1 + man/mlr_pipeops_encodeimpact.Rd | 1 + man/mlr_pipeops_encodelmer.Rd | 1 + man/mlr_pipeops_encodeplquantiles.Rd | 1 + man/mlr_pipeops_encodepltree.Rd | 1 + man/mlr_pipeops_featureunion.Rd | 1 + man/mlr_pipeops_filter.Rd | 1 + man/mlr_pipeops_fixfactors.Rd | 1 + man/mlr_pipeops_histbin.Rd | 1 + man/mlr_pipeops_ica.Rd | 1 + man/mlr_pipeops_imputeconstant.Rd | 1 + man/mlr_pipeops_imputehist.Rd | 1 + man/mlr_pipeops_imputelearner.Rd | 1 + man/mlr_pipeops_imputemean.Rd | 1 + man/mlr_pipeops_imputemedian.Rd | 1 + man/mlr_pipeops_imputemode.Rd | 1 + man/mlr_pipeops_imputeoor.Rd | 1 + man/mlr_pipeops_imputesample.Rd | 1 + man/mlr_pipeops_kernelpca.Rd | 1 + man/mlr_pipeops_learner.Rd | 1 + man/mlr_pipeops_learner_pi_cvplus.Rd | 1 + man/mlr_pipeops_learner_quantiles.Rd | 1 + man/mlr_pipeops_missind.Rd | 1 + man/mlr_pipeops_modelmatrix.Rd | 1 + man/mlr_pipeops_multiplicityexply.Rd | 1 + man/mlr_pipeops_multiplicityimply.Rd | 1 + man/mlr_pipeops_mutate.Rd | 1 + man/mlr_pipeops_nearmiss.Rd | 1 + man/mlr_pipeops_nmf.Rd | 1 + man/mlr_pipeops_nop.Rd | 1 + man/mlr_pipeops_ovrsplit.Rd | 1 + man/mlr_pipeops_ovrunite.Rd | 1 + man/mlr_pipeops_pca.Rd | 1 + man/mlr_pipeops_proxy.Rd | 1 + man/mlr_pipeops_quantilebin.Rd | 1 + man/mlr_pipeops_randomprojection.Rd | 1 + man/mlr_pipeops_randomresponse.Rd | 1 + man/mlr_pipeops_regravg.Rd | 1 + man/mlr_pipeops_removeconstants.Rd | 1 + man/mlr_pipeops_renamecolumns.Rd | 1 + man/mlr_pipeops_replicate.Rd | 1 + man/mlr_pipeops_rowapply.Rd | 1 + man/mlr_pipeops_scale.Rd | 1 + man/mlr_pipeops_scalemaxabs.Rd | 1 + man/mlr_pipeops_scalerange.Rd | 1 + man/mlr_pipeops_select.Rd | 1 + man/mlr_pipeops_smote.Rd | 1 + man/mlr_pipeops_smotenc.Rd | 1 + man/mlr_pipeops_spatialsign.Rd | 1 + man/mlr_pipeops_subsample.Rd | 1 + man/mlr_pipeops_targetinvert.Rd | 1 + man/mlr_pipeops_targetmutate.Rd | 1 + man/mlr_pipeops_targettrafoscalerange.Rd | 1 + man/mlr_pipeops_textvectorizer.Rd | 1 + man/mlr_pipeops_threshold.Rd | 1 + man/mlr_pipeops_tomek.Rd | 1 + man/mlr_pipeops_tunethreshold.Rd | 1 + man/mlr_pipeops_unbranch.Rd | 1 + man/mlr_pipeops_updatetarget.Rd | 1 + man/mlr_pipeops_vtreat.Rd | 1 + man/mlr_pipeops_yeojohnson.Rd | 1 + 85 files changed, 272 insertions(+), 163 deletions(-) create mode 100644 man/mlr_pipeops_classweightsex.Rd diff --git a/R/PipeOpClassWeightsEx.R b/R/PipeOpClassWeightsEx.R index 59ee4d49c..8e11bc914 100644 --- a/R/PipeOpClassWeightsEx.R +++ b/R/PipeOpClassWeightsEx.R @@ -1,7 +1,7 @@ #' @title Class Weights for Sample - Extended #' #' @usage NULL -#' @name mlr_pipeops_classweights +#' @name mlr_pipeops_classweightsex #' @format [`R6Class`][R6::R6Class] object inheriting from [`PipeOpTaskPreproc`]/[`PipeOp`]. #' #' @description 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 bb7760bca..b45b2fab3 100644 --- a/man/mlr_pipeops_classweights.Rd +++ b/man/mlr_pipeops_classweights.Rd @@ -1,13 +1,10 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/PipeOpClassWeights.R, R/PipeOpClassWeightsEx.R +% Please edit documentation in R/PipeOpClassWeights.R \name{mlr_pipeops_classweights} \alias{mlr_pipeops_classweights} \alias{PipeOpClassWeights} -\alias{PipeOpClassWeightsEx} \title{Class Weights for Sample Weighting} \format{ -\code{\link[R6:R6Class]{R6Class}} object inheriting from \code{\link{PipeOpTaskPreproc}}/\code{\link{PipeOp}}. - \code{\link[R6:R6Class]{R6Class}} object inheriting from \code{\link{PipeOpTaskPreproc}}/\code{\link{PipeOp}}. } \description{ @@ -19,34 +16,12 @@ 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. - -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. - -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. } \section{Construction}{ -\if{html}{\out{
}}\preformatted{PipeOpClassWeights$new(id = "classweights", param_vals = list()) -}\if{html}{\out{
}} -\itemize{ -\item \code{id} :: \code{character(1)} -Identifier of the resulting object, default \code{"classweights"} -\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()}. -} - - - \if{html}{\out{
}}\preformatted{PipeOpClassWeights$new(id = "classweights", param_vals = list()) }\if{html}{\out{
}} \itemize{ @@ -59,13 +34,6 @@ List of hyperparameter settings, overwriting the hyperparameter settings that wo \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. - - 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. @@ -75,21 +43,11 @@ 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}}. - - 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{minor_weight} :: \code{numeric(1)} \cr -Weight given to samples of the minor class. Major class samples have weight 1. Initialized to 1. -} - - 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{minor_weight} :: \code{numeric(1)} \cr @@ -99,13 +57,6 @@ Weight given to samples of the minor class. Major class samples have weight 1. I \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. - - 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. @@ -115,17 +66,11 @@ weight column itself. \section{Fields}{ -Only fields inherited from \code{\link{PipeOp}}. - - Only fields inherited from \code{\link{PipeOp}}. } \section{Methods}{ -Only methods inherited from \code{\link{PipeOpTaskPreproc}}/\code{\link{PipeOp}}. - - Only methods inherited from \code{\link{PipeOpTaskPreproc}}/\code{\link{PipeOp}}. } @@ -142,26 +87,6 @@ if ("weights_learner" \%in\% names(task)) { 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 -} -library("mlr3") - -task = tsk("spam") -opb = po("classweights") - -# 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]] @@ -174,92 +99,6 @@ if ("weights_learner" \%in\% names(result)) { \seealso{ https://mlr-org.com/pipeops.html -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_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}} - Other PipeOps: \code{\link{PipeOp}}, \code{\link{PipeOpEncodePL}}, @@ -276,6 +115,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..8374651c1 --- /dev/null +++ b/man/mlr_pipeops_classweightsex.Rd @@ -0,0 +1,187 @@ +% 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 - 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}} 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. + +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. +} +\section{Construction}{ + + +\if{html}{\out{
}}\preformatted{PipeOpClassWeights$new(id = "classweights", param_vals = list()) +}\if{html}{\out{
}} +\itemize{ +\item \code{id} :: \code{character(1)} +Identifier of the resulting object, default \code{"classweights"} +\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{minor_weight} :: \code{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 \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. +} + +\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") +opb = po("classweights") + +# 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 +} +} +\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}}, From c16b83dd67380c06a46015549052636c676d1391 Mon Sep 17 00:00:00 2001 From: Alexander Winterstetter Date: Thu, 23 Oct 2025 15:47:55 +0200 Subject: [PATCH 10/18] made classweights code more concise --- R/PipeOpClassWeights.R | 19 ++++++------------- R/PipeOpClassWeightsEx.R | 23 ++++++++--------------- 2 files changed, 14 insertions(+), 28 deletions(-) diff --git a/R/PipeOpClassWeights.R b/R/PipeOpClassWeights.R index 61f511251..e62fd3c27 100644 --- a/R/PipeOpClassWeights.R +++ b/R/PipeOpClassWeights.R @@ -109,19 +109,12 @@ PipeOpClassWeights = R6Class("PipeOpClassWeights", task$cbind(wcol) task$col_roles$feature = setdiff(task$col_roles$feature, weightcolname) - if ("learner" %in% self$param_set$values$weight_type) { - if ("weights_learner" %in% mlr_reflections$task_col_roles$classif) { - task$col_roles$weights_learner = weightcolname - } else { - task$col_roles$weight = weightcolname - } - } - if ("measure" %in% self$param_set$values$weight_type) { - if ("weights_measure" %in% mlr_reflections$task_col_roles$classif) { - task$col_roles$weights_measure = weightcolname - } else { - task$col_roles$weight = weightcolname - } + + classif_roles = mlr_reflections$task_col_roles$classif + for (type in self$param_set$values$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 index 8e11bc914..2b81ee344 100644 --- a/R/PipeOpClassWeightsEx.R +++ b/R/PipeOpClassWeightsEx.R @@ -95,7 +95,7 @@ PipeOpClassWeightsEx = R6Class("PipeOpClassWeightsEx", private = list( .train_task = function(task) { - browser() + #if ("twoclass" %nin% task$properties) { # stop("Only binary classification Tasks are supported.") #} @@ -115,23 +115,16 @@ PipeOpClassWeightsEx = R6Class("PipeOpClassWeightsEx", } else if (self$param_set$values$weight_method == "median frequency balancing") { wcol = setnames(data.table(truth)[data.table(median(class_frequency) / class_frequency), on = .(truth)][, "N"], weightcolname) } else if (self$param_set$values$weight_method == "explicit") { - wcol = data.table(.WEIGHTS = self$param_set$values$mapping[task$truth()]) + wcol = setnames(data.table(self$param_set$values$mapping[task$truth()], ".WEIGHTS")) } task$cbind(wcol) task$col_roles$feature = setdiff(task$col_roles$feature, weightcolname) - if ("learner" %in% self$param_set$values$weight_type) { - if ("weights_learner" %in% mlr_reflections$task_col_roles$classif) { - task$col_roles$weights_learner = weightcolname - } else { - task$col_roles$weight = weightcolname - } - } - if ("measure" %in% self$param_set$values$weight_type) { - if ("weights_measure" %in% mlr_reflections$task_col_roles$classif) { - task$col_roles$weights_measure = weightcolname - } else { - task$col_roles$weight = weightcolname - } + + classif_roles = mlr_reflections$task_col_roles$classif + for (type in self$param_set$values$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 }, From 387f54aa8e56c4bf057407ea850031fea15c6197 Mon Sep 17 00:00:00 2001 From: Alexander Winterstetter Date: Sun, 2 Nov 2025 21:07:48 +0100 Subject: [PATCH 11/18] doc changes --- R/PipeOpClassWeights.R | 34 ++++--- R/PipeOpClassWeightsEx.R | 116 ++++++++++------------- attic/PipeOpClassWeightsEx - test code.R | 23 +++++ man/mlr_pipeops_classweights.Rd | 15 +-- man/mlr_pipeops_classweightsex.Rd | 53 +++++------ 5 files changed, 130 insertions(+), 111 deletions(-) create mode 100644 attic/PipeOpClassWeightsEx - test code.R diff --git a/R/PipeOpClassWeights.R b/R/PipeOpClassWeights.R index e62fd3c27..4a6e93972 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. (resampling techniques???) #' #' @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,6 +41,9 @@ #' 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. +#' * `weight_type` :: `character` \cr +#' Determines whether `"weights_learner"`, `"weights_measure"`, both or none of the columns will be set. +#' #' @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. @@ -85,18 +89,25 @@ PipeOpClassWeights = R6Class("PipeOpClassWeights", initialize = function(id = "classweights", param_vals = list()) { ps = ps( minor_weight = p_dbl(init = 1, lower = 0, upper = Inf, tags = "train"), - weight_type = p_uty(init = c("learner", "measure"), 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) { + browser() + 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) @@ -105,13 +116,14 @@ 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) classif_roles = mlr_reflections$task_col_roles$classif - for (type in self$param_set$values$weight_type) { + + 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 diff --git a/R/PipeOpClassWeightsEx.R b/R/PipeOpClassWeightsEx.R index 2b81ee344..d5a342044 100644 --- a/R/PipeOpClassWeightsEx.R +++ b/R/PipeOpClassWeightsEx.R @@ -5,24 +5,22 @@ #' @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. +#' Binary as well as Multiclass [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. (resampling techniques???) #' #' @section Construction: #' ``` -#' PipeOpClassWeights$new(id = "classweights", param_vals = list()) +#' PipeOpClassWeightsEx$new(id = "classweightsex", param_vals = list()) #' ``` #' #' * `id` :: `character(1)` -#' Identifier of the resulting object, default `"classweights"` +#' 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()`. #' @@ -38,11 +36,12 @@ #' #' @section Parameters: #' 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. +#' * `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 `character` \cr +#' Depends on `"weight_method" = "explicit"`. Must be a named character, that specifies for each target class the corresponding weight. #' #' 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. @@ -61,23 +60,24 @@ #' library("mlr3") #' #' task = tsk("spam") -#' opb = po("classweights") #' -#' # task weights -#' if ("weights_learner" %in% names(task)) { -#' task$weights_learner # recent mlr3-versions -#' } else { -#' task$weights # old mlr3-versions -#' } +#' poicf = po("classweightsex", param_vals = list(weight_type = c("learner", "measure"), weight_method = "inverse_class_frequency")) +#' result = poicf$train(list(task))[[1L]] #' -#' # 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 #' } +#' +#' 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, @@ -85,9 +85,13 @@ PipeOpClassWeightsEx = R6Class("PipeOpClassWeightsEx", public = list( initialize = function(id = "classweightsex", param_vals = list()) { ps = ps( - weight_type = p_uty(init = c("learner", "measure"), tags = "train"), - 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 = "train"), - mapping = p_uty(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")))), + 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) check_character(names(x), any.missing = FALSE, unique = TRUE)), + depends = weight_method == "explicit") ) super$initialize(id, param_set = ps, param_vals = param_vals, can_subset_cols = FALSE, task_type = "TaskClassif", tags = "imbalanced data") } @@ -95,10 +99,7 @@ PipeOpClassWeightsEx = R6Class("PipeOpClassWeightsEx", private = list( .train_task = function(task) { - - #if ("twoclass" %nin% task$properties) { - # stop("Only binary classification Tasks are supported.") - #} + pv = self$param_set$get_values(tags = "train") weightcolname = ".WEIGHTS" if (weightcolname %in% unlist(task$col_roles)) { @@ -106,22 +107,28 @@ PipeOpClassWeightsEx = R6Class("PipeOpClassWeightsEx", } truth = task$truth() - minor = names(which.min(table(task$truth()))) - class_frequency = table(truth) / length(truth) - if (self$param_set$values$weight_method == "inverse class frequency") { - wcol = setnames(data.table(truth)[data.table(class_frequency^-1), on = .(truth)][, "N"], weightcolname) - } else if (self$param_set$values$weight_method == "inverse square root of frequency") { - wcol = setnames(data.table(truth)[data.table((class_frequency^0.5)^-1), on = .(truth)][, "N"], weightcolname) - } else if (self$param_set$values$weight_method == "median frequency balancing") { - wcol = setnames(data.table(truth)[data.table(median(class_frequency) / class_frequency), on = .(truth)][, "N"], weightcolname) - } else if (self$param_set$values$weight_method == "explicit") { - wcol = setnames(data.table(self$param_set$values$mapping[task$truth()], ".WEIGHTS")) + + if (is.null(pv$weight_type)) { + return(task) } + + class_frequency = table(truth) / length(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 + ) + + wcol = setnames(data.table(weights_by_class[truth])[, "N"], 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 self$param_set$values$weight_type) { + 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 @@ -135,26 +142,3 @@ PipeOpClassWeightsEx = R6Class("PipeOpClassWeightsEx", mlr_pipeops$add("classweightsex", PipeOpClassWeightsEx) -# 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/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/mlr_pipeops_classweights.Rd b/man/mlr_pipeops_classweights.Rd index b45b2fab3..af63582fc 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. (resampling techniques???) } \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,6 +53,8 @@ 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. } } diff --git a/man/mlr_pipeops_classweightsex.Rd b/man/mlr_pipeops_classweightsex.Rd index 8374651c1..06e91a2d4 100644 --- a/man/mlr_pipeops_classweightsex.Rd +++ b/man/mlr_pipeops_classweightsex.Rd @@ -8,25 +8,23 @@ \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. +Binary as well as Multiclass \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. (resampling techniques???) } \section{Construction}{ -\if{html}{\out{
}}\preformatted{PipeOpClassWeights$new(id = "classweights", param_vals = list()) +\if{html}{\out{
}}\preformatted{PipeOpClassWeightsEx$new(id = "classweightsex", param_vals = list()) }\if{html}{\out{
}} \itemize{ \item \code{id} :: \code{character(1)} -Identifier of the resulting object, default \code{"classweights"} +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()}. } @@ -50,16 +48,14 @@ The \verb{$state} is a named \code{list} with the \verb{$state} elements inherit 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{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. +\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{character} \cr +Depends on \code{"weight_method" = "explicit"}. Must be a named character, that specifies for each target class the corresponding weight. } -\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. } @@ -78,23 +74,24 @@ Only methods inherited from \code{\link{PipeOpTaskPreproc}}/\code{\link{PipeOp}} library("mlr3") task = tsk("spam") -opb = po("classweights") -# task weights -if ("weights_learner" \%in\% names(task)) { - task$weights_learner # recent mlr3-versions -} else { - task$weights # old mlr3-versions -} +poicf = po("classweightsex", param_vals = list(weight_type = c("learner", "measure"), weight_method = "inverse_class_frequency")) +result = poicf$train(list(task))[[1L]] -# 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 } + +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 From 77713112ee2e6190725c5e4b5e86577928c0b802 Mon Sep 17 00:00:00 2001 From: Alexander Winterstetter Date: Sun, 2 Nov 2025 21:56:56 +0100 Subject: [PATCH 12/18] added first tests for PipeOpClassWeightsEx --- R/PipeOpClassWeights.R | 2 +- R/PipeOpClassWeightsEx.R | 13 +++--- tests/testthat/test_pipeop_classweightsex.R | 50 +++++++++++++++++++++ 3 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 tests/testthat/test_pipeop_classweightsex.R diff --git a/R/PipeOpClassWeights.R b/R/PipeOpClassWeights.R index 4a6e93972..46b27ab08 100644 --- a/R/PipeOpClassWeights.R +++ b/R/PipeOpClassWeights.R @@ -97,7 +97,7 @@ PipeOpClassWeights = R6Class("PipeOpClassWeights", ), private = list( .train_task = function(task) { - browser() + pv = self$param_set$get_values(tags = "train") if ("twoclass" %nin% task$properties) { diff --git a/R/PipeOpClassWeightsEx.R b/R/PipeOpClassWeightsEx.R index d5a342044..9efa955bf 100644 --- a/R/PipeOpClassWeightsEx.R +++ b/R/PipeOpClassWeightsEx.R @@ -101,6 +101,12 @@ PipeOpClassWeightsEx = R6Class("PipeOpClassWeightsEx", .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) + } + weightcolname = ".WEIGHTS" if (weightcolname %in% unlist(task$col_roles)) { stopf("Weight column '%s' is already in the Task", weightcolname) @@ -108,10 +114,6 @@ PipeOpClassWeightsEx = R6Class("PipeOpClassWeightsEx", truth = task$truth() - if (is.null(pv$weight_type)) { - return(task) - } - class_frequency = table(truth) / length(truth) class_names = names(class_frequency) @@ -122,7 +124,8 @@ PipeOpClassWeightsEx = R6Class("PipeOpClassWeightsEx", "explicit" = pv$mapping ) - wcol = setnames(data.table(weights_by_class[truth])[, "N"], weightcolname) + 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) diff --git a/tests/testthat/test_pipeop_classweightsex.R b/tests/testthat/test_pipeop_classweightsex.R new file mode 100644 index 000000000..1edb92db7 --- /dev/null +++ b/tests/testthat/test_pipeop_classweightsex.R @@ -0,0 +1,50 @@ + +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(PipeOpClassWeights, 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("iris") + + # 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()) + + + # manual_weights = as.data.table(1 / table(task$data()$Species)) + # 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)) +}) From 7e5fcf2245e9363dcaa9e953197aceb0d7189114 Mon Sep 17 00:00:00 2001 From: Alexander Winterstetter Date: Sun, 2 Nov 2025 22:14:42 +0100 Subject: [PATCH 13/18] impelmented test architecture for comparing weight_method to manual calculation --- R/PipeOpClassWeightsEx.R | 2 +- tests/testthat/test_pipeop_classweightsex.R | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/R/PipeOpClassWeightsEx.R b/R/PipeOpClassWeightsEx.R index 9efa955bf..9a4226dd3 100644 --- a/R/PipeOpClassWeightsEx.R +++ b/R/PipeOpClassWeightsEx.R @@ -114,7 +114,7 @@ PipeOpClassWeightsEx = R6Class("PipeOpClassWeightsEx", truth = task$truth() - class_frequency = table(truth) / length(truth) + class_frequency = prop.table(table(truth)) class_names = names(class_frequency) weights_by_class = switch(pv$weight_method, diff --git a/tests/testthat/test_pipeop_classweightsex.R b/tests/testthat/test_pipeop_classweightsex.R index 1edb92db7..614c7e4f3 100644 --- a/tests/testthat/test_pipeop_classweightsex.R +++ b/tests/testthat/test_pipeop_classweightsex.R @@ -43,8 +43,18 @@ test_that("PipeOpClassWeightsEx", { 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))) + - # manual_weights = as.data.table(1 / table(task$data()$Species)) # 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)) }) From 3ad3dec17fde337d0cb4efc911d599605881da5b Mon Sep 17 00:00:00 2001 From: Alexander Winterstetter Date: Sun, 2 Nov 2025 22:16:02 +0100 Subject: [PATCH 14/18] small fix --- R/PipeOpClassWeightsEx.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/PipeOpClassWeightsEx.R b/R/PipeOpClassWeightsEx.R index 9a4226dd3..5da226067 100644 --- a/R/PipeOpClassWeightsEx.R +++ b/R/PipeOpClassWeightsEx.R @@ -73,7 +73,7 @@ #' result$weights_measure #' #' -#' #' if ("weights_measure" %in% names(result)) { +#' if ("weights_measure" %in% names(result)) { #' result$weights_measure # recent mlr3-versions #' } else { #' result$weights # old mlr3-versions From 3563b3419c87c65af66144c5feb467a4b91a1265 Mon Sep 17 00:00:00 2001 From: Alexander Winterstetter Date: Sun, 2 Nov 2025 23:02:45 +0100 Subject: [PATCH 15/18] fixed error also in documentation --- man/mlr_pipeops_classweightsex.Rd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/mlr_pipeops_classweightsex.Rd b/man/mlr_pipeops_classweightsex.Rd index 06e91a2d4..290ea61d6 100644 --- a/man/mlr_pipeops_classweightsex.Rd +++ b/man/mlr_pipeops_classweightsex.Rd @@ -87,7 +87,7 @@ if ("weights_learner" \%in\% names(result)) { result$weights_measure -#' if ("weights_measure" \%in\% names(result)) { +if ("weights_measure" \%in\% names(result)) { result$weights_measure # recent mlr3-versions } else { result$weights # old mlr3-versions From f50cca1587f75932f4937a4f766b5f9dedda2a97 Mon Sep 17 00:00:00 2001 From: Alexander Winterstetter Date: Sun, 2 Nov 2025 23:10:21 +0100 Subject: [PATCH 16/18] extended tests --- tests/testthat/test_pipeop_classweightsex.R | 34 ++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/tests/testthat/test_pipeop_classweightsex.R b/tests/testthat/test_pipeop_classweightsex.R index 614c7e4f3..24280e02d 100644 --- a/tests/testthat/test_pipeop_classweightsex.R +++ b/tests/testthat/test_pipeop_classweightsex.R @@ -36,7 +36,7 @@ test_that("PipeOpClassWeightsEx - error for Tasks without weights property, #937 test_that("PipeOpClassWeightsEx", { - task = mlr_tasks$get("iris") + task = mlr_tasks$get("penguins") # Method inverse_class_frequency poicf = po("classweightsex", param_vals = list(weight_method = "inverse_class_frequency")) @@ -54,6 +54,38 @@ test_that("PipeOpClassWeightsEx", { 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) / freq + #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))) # 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)) From da6363de812abe34991268f33ec83394089203a5 Mon Sep 17 00:00:00 2001 From: Alexander Winterstetter Date: Wed, 5 Nov 2025 19:39:40 +0100 Subject: [PATCH 17/18] changes in test and doc (last commit before Positron transfer) --- R/PipeOpClassWeightsEx.R | 2 +- tests/testthat/test_pipeop_classweightsex.R | 25 ++++++++++++--------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/R/PipeOpClassWeightsEx.R b/R/PipeOpClassWeightsEx.R index 5da226067..cccce5f7c 100644 --- a/R/PipeOpClassWeightsEx.R +++ b/R/PipeOpClassWeightsEx.R @@ -19,7 +19,7 @@ #' PipeOpClassWeightsEx$new(id = "classweightsex", param_vals = list()) #' ``` #' -#' * `id` :: `character(1)` +#' * `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()`. diff --git a/tests/testthat/test_pipeop_classweightsex.R b/tests/testthat/test_pipeop_classweightsex.R index 24280e02d..5966e56b9 100644 --- a/tests/testthat/test_pipeop_classweightsex.R +++ b/tests/testthat/test_pipeop_classweightsex.R @@ -75,18 +75,21 @@ test_that("PipeOpClassWeightsEx", { nt = pomfb$train(list(task))[[1L]] expect_equal(nt$data(), task$data()) - #freq = prop.table(table(task$truth())) - #manual_weights = median(freq) / freq - #manual_weights = 1 / sqrt(freq[task$truth()]) + 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))) + +}) - #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 - learner and measure", { - # 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)) }) + From 6fcc8dde98e2bbb5c42f5cc9f31cf3a98227da55 Mon Sep 17 00:00:00 2001 From: awinterstetter Date: Thu, 6 Nov 2025 14:14:16 +0100 Subject: [PATCH 18/18] extended tests and refined doc --- R/PipeOpClassWeights.R | 13 ++++--- R/PipeOpClassWeightsEx.R | 40 ++++++++++++++++----- man/mlr_pipeops_classweights.Rd | 13 ++++--- man/mlr_pipeops_classweightsex.Rd | 20 +++++++---- tests/testthat/test_pipeop_classweights.R | 32 +++++++++++++++++ tests/testthat/test_pipeop_classweightsex.R | 37 ++++++++++++++++--- 6 files changed, 122 insertions(+), 33 deletions(-) diff --git a/R/PipeOpClassWeights.R b/R/PipeOpClassWeights.R index 46b27ab08..f0b72ca98 100644 --- a/R/PipeOpClassWeights.R +++ b/R/PipeOpClassWeights.R @@ -15,7 +15,7 @@ #' must be adjusted for this [`PipeOp`] to be useful. #' #' 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. (resampling techniques???) +#' Thus, the behavior of subsequent [`Learner`][mlr3::Learner]s or evaluation metric weights can be determined. #' #' @section Construction: #' ``` @@ -42,14 +42,13 @@ #' * `minor_weight` :: `numeric(1)` \cr #' Weight given to samples of the minor class. Major class samples have weight 1. Initialized to 1. #' * `weight_type` :: `character` \cr -#' Determines whether `"weights_learner"`, `"weights_measure"`, both or none of the columns will be set. +#' 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. #' #' @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. -#' -#' 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. +#' 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`]. diff --git a/R/PipeOpClassWeightsEx.R b/R/PipeOpClassWeightsEx.R index cccce5f7c..f97b0ab54 100644 --- a/R/PipeOpClassWeightsEx.R +++ b/R/PipeOpClassWeightsEx.R @@ -1,4 +1,4 @@ -#' @title Class Weights for Sample - Extended +#' @title Class Weights for Sample Weighting - Extended #' #' @usage NULL #' @name mlr_pipeops_classweightsex @@ -9,10 +9,10 @@ #' 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. +#' 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. (resampling techniques???) +#' Thus, the behavior of subsequent [`Learner`][mlr3::Learner]s or evaluation metric weights can be determined. #' #' @section Construction: #' ``` @@ -39,13 +39,17 @@ #' * `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 `character` \cr -#' Depends on `"weight_method" = "explicit"`. Must be a named character, that specifies for each target class the corresponding weight. +#' 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`]. #' @@ -90,7 +94,13 @@ PipeOpClassWeightsEx = R6Class("PipeOpClassWeightsEx", 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) check_character(names(x), any.missing = FALSE, unique = TRUE)), + 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") @@ -107,6 +117,21 @@ PipeOpClassWeightsEx = R6Class("PipeOpClassWeightsEx", 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) @@ -144,4 +169,3 @@ PipeOpClassWeightsEx = R6Class("PipeOpClassWeightsEx", ) mlr_pipeops$add("classweightsex", PipeOpClassWeightsEx) - diff --git a/man/mlr_pipeops_classweights.Rd b/man/mlr_pipeops_classweights.Rd index af63582fc..9dc137ea8 100644 --- a/man/mlr_pipeops_classweights.Rd +++ b/man/mlr_pipeops_classweights.Rd @@ -18,7 +18,7 @@ Caution: when constructed naively without parameter, the weights are all set to must be adjusted for this \code{\link{PipeOp}} to be useful. 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. (resampling techniques???) +Thus, the behavior of subsequent \code{\link[mlr3:Learner]{Learner}}s or evaluation metric weights can be determined. } \section{Construction}{ @@ -54,17 +54,16 @@ The parameters are the parameters inherited from \code{\link{PipeOpTaskPreproc}} \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. +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}{ diff --git a/man/mlr_pipeops_classweightsex.Rd b/man/mlr_pipeops_classweightsex.Rd index 290ea61d6..8c13abddb 100644 --- a/man/mlr_pipeops_classweightsex.Rd +++ b/man/mlr_pipeops_classweightsex.Rd @@ -3,7 +3,7 @@ \name{mlr_pipeops_classweightsex} \alias{mlr_pipeops_classweightsex} \alias{PipeOpClassWeightsEx} -\title{Class Weights for Sample - Extended} +\title{Class Weights for Sample Weighting - Extended} \format{ \code{\link[R6:R6Class]{R6Class}} object inheriting from \code{\link{PipeOpTaskPreproc}}/\code{\link{PipeOp}}. } @@ -12,10 +12,10 @@ Adds a class weight column to the \code{\link[mlr3:Task]{Task}}, influencing how 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. +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. (resampling techniques???) +Thus, the behavior of subsequent \code{\link[mlr3:Learner]{Learner}}s or evaluation metric weights can be determined. } \section{Construction}{ @@ -23,7 +23,7 @@ Thus, the behavior of subsequent \code{\link[mlr3:Learner]{Learner}}s or evaluat \if{html}{\out{
}}\preformatted{PipeOpClassWeightsEx$new(id = "classweightsex", 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{"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()}. @@ -51,15 +51,21 @@ The parameters are the parameters inherited from \code{\link{PipeOpTaskPreproc}} \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{character} \cr -Depends on \code{"weight_method" = "explicit"}. Must be a named character, that specifies for each target class the corresponding weight. +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}}. diff --git a/tests/testthat/test_pipeop_classweights.R b/tests/testthat/test_pipeop_classweights.R index bdc62efa1..4624423ae 100644 --- a/tests/testthat/test_pipeop_classweights.R +++ b/tests/testthat/test_pipeop_classweights.R @@ -23,6 +23,38 @@ test_that("PipeOpClassWeights", { 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", { skip_if_not_installed("mlr3learners") skip_if_not_installed("MASS") diff --git a/tests/testthat/test_pipeop_classweightsex.R b/tests/testthat/test_pipeop_classweightsex.R index 5966e56b9..f9311ccf2 100644 --- a/tests/testthat/test_pipeop_classweightsex.R +++ b/tests/testthat/test_pipeop_classweightsex.R @@ -6,7 +6,7 @@ test_that("PipeOpClassWeightsEx - basic properties", { train_pipeop(op, inputs = list(task)) predict_pipeop(op, inputs = list(task)) - expect_datapreproc_pipeop_class(PipeOpClassWeights, task = task, + expect_datapreproc_pipeop_class(PipeOpClassWeightsEx, task = task, predict_like_train = FALSE) }) @@ -88,8 +88,37 @@ test_that("PipeOpClassWeightsEx", { }) - -test_that("PipeOpClassWeightsEx - learner and measure", { - +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]]) + } + } +})