diff --git a/NAMESPACE b/NAMESPACE index a6cf4ca2..4214e39c 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -52,6 +52,7 @@ export(activation_2) export(adjust_deg_free) export(all_neighbors) export(batch_size) +export(buffer) export(class_weights) export(conditional_min_criterion) export(conditional_test_statistic) @@ -93,6 +94,7 @@ export(is_unknown) export(kernel_offset) export(learn_rate) export(loss_reduction) +export(lower_limit) export(lower_quantile) export(max_nodes) export(max_num_terms) @@ -184,6 +186,7 @@ export(unbiased_rules) export(under_ratio) export(unique_cut) export(unknown) +export(upper_limit) export(validation_set_prop) export(value_inverse) export(value_sample) diff --git a/NEWS.md b/NEWS.md index d15ebbc9..1d938332 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,12 @@ # dials (development version) +* Added three new parameters for use in postprocessing in the tailor package (#357). + - `buffer()` sets the distance on either side of a classification threshold + within which predictions are considered equivocal in + `tailor::adjust_equivocal_zone()`. + - `lower_limit()` and `upper_limit()` sets the ranges for + numeric predictions in `tailor::adjust_numeric_range()`. + * All messages, warnings and errors has been translated to use {cli} package (#311). # dials 1.3.0 diff --git a/R/param_buffer.R b/R/param_buffer.R new file mode 100644 index 00000000..a9b058c8 --- /dev/null +++ b/R/param_buffer.R @@ -0,0 +1,26 @@ +#' Buffer size +#' +#' In equivocal zones, predictions are considered equivocal (i.e. "could +#' go either way") if their probability falls within some distance on either +#' side of the classification threshold. That distance is called the "buffer." +#' +#' A buffer of .5 is only possible if the classification threshold is .5. +#' In that case, all probability predictions are considered equivocal, +#' regardless of their value in \code{[0, 1]}. +#' Otherwise, the maximum buffer is `min(threshold, 1 - threshold)`. +#' +#' @inheritParams Laplace +#' @seealso [threshold()] +#' @examples +#' buffer() +#' @export +buffer <- function(range = c(0, .5), trans = NULL) { + new_quant_param( + type = "double", + range = range, + inclusive = c(TRUE, TRUE), + trans = trans, + label = c(buffer = "buffer"), + finalize = NULL + ) +} diff --git a/R/param_range_limits.R b/R/param_range_limits.R new file mode 100644 index 00000000..9b759531 --- /dev/null +++ b/R/param_range_limits.R @@ -0,0 +1,37 @@ +#' Limits for the range of predictions +#' +#' Range limits truncate model predictions to a specific range of values, +#' typically to avoid extreme or unrealistic predictions. +#' +#' @inheritParams Laplace +#' @examples +#' lower_limit() +#' upper_limit() +#' @name range_limits +#' @export + +#' @rdname range_limits +#' @export +lower_limit <- function(range = c(-Inf, Inf), trans = NULL) { + new_quant_param( + type = "double", + range = range, + inclusive = c(TRUE, FALSE), + trans = trans, + label = c(lower_limit = "Lower Limit"), + finalize = NULL + ) +} + +#' @rdname range_limits +#' @export +upper_limit <- function(range = c(-Inf, Inf), trans = NULL) { + new_quant_param( + type = "double", + range = range, + inclusive = c(FALSE, TRUE), + trans = trans, + label = c(upper_limit = "Upper Limit"), + finalize = NULL + ) +} diff --git a/_pkgdown.yml b/_pkgdown.yml index 68b4fb65..bb27589b 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -112,6 +112,11 @@ reference: - scale_pos_weight - shrinkage_correlation + - title: Parameter objects for post-processing + contents: + - buffer + - range_limits + - title: Finalizing parameters contents: - finalize diff --git a/man/buffer.Rd b/man/buffer.Rd new file mode 100644 index 00000000..00d3769f --- /dev/null +++ b/man/buffer.Rd @@ -0,0 +1,35 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/param_buffer.R +\name{buffer} +\alias{buffer} +\title{Buffer size} +\usage{ +buffer(range = c(0, 0.5), trans = NULL) +} +\arguments{ +\item{range}{A two-element vector holding the \emph{defaults} for the smallest and +largest possible values, respectively. If a transformation is specified, +these values should be in the \emph{transformed units}.} + +\item{trans}{A \code{trans} object from the \code{scales} package, such as +\code{scales::transform_log10()} or \code{scales::transform_reciprocal()}. If not provided, +the default is used which matches the units used in \code{range}. If no +transformation, \code{NULL}.} +} +\description{ +In equivocal zones, predictions are considered equivocal (i.e. "could +go either way") if their probability falls within some distance on either +side of the classification threshold. That distance is called the "buffer." +} +\details{ +A buffer of .5 is only possible if the classification threshold is .5. +In that case, all probability predictions are considered equivocal, +regardless of their value in \code{[0, 1]}. +Otherwise, the maximum buffer is \code{min(threshold, 1 - threshold)}. +} +\examples{ +buffer() +} +\seealso{ +\code{\link[=threshold]{threshold()}} +} diff --git a/man/range_limits.Rd b/man/range_limits.Rd new file mode 100644 index 00000000..633173f6 --- /dev/null +++ b/man/range_limits.Rd @@ -0,0 +1,30 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/param_range_limits.R +\name{range_limits} +\alias{range_limits} +\alias{lower_limit} +\alias{upper_limit} +\title{Limits for the range of predictions} +\usage{ +lower_limit(range = c(-Inf, Inf), trans = NULL) + +upper_limit(range = c(-Inf, Inf), trans = NULL) +} +\arguments{ +\item{range}{A two-element vector holding the \emph{defaults} for the smallest and +largest possible values, respectively. If a transformation is specified, +these values should be in the \emph{transformed units}.} + +\item{trans}{A \code{trans} object from the \code{scales} package, such as +\code{scales::transform_log10()} or \code{scales::transform_reciprocal()}. If not provided, +the default is used which matches the units used in \code{range}. If no +transformation, \code{NULL}.} +} +\description{ +Range limits truncate model predictions to a specific range of values, +typically to avoid extreme or unrealistic predictions. +} +\examples{ +lower_limit() +upper_limit() +} diff --git a/tests/testthat/test-params.R b/tests/testthat/test-params.R index 70e114f6..68f6eb6b 100644 --- a/tests/testthat/test-params.R +++ b/tests/testthat/test-params.R @@ -4,6 +4,7 @@ test_that("param ranges", { expect_equal(sample_size(1:2)$range, list(lower = 1L, upper = 2L)) expect_equal(learn_rate(c(.1, .9))$range, list(lower = 0.1, upper = 0.9)) expect_equal(loss_reduction(c(.1, .9))$range, list(lower = 0.1, upper = 0.9)) + expect_equal(buffer(c(0, .25))$range, list(lower = 0, upper = .25)) expect_equal(cost_complexity(c(.1, .9))$range, list(lower = 0.1, upper = 0.9)) expect_equal(epochs(1:2)$range, list(lower = 1L, upper = 2L)) expect_equal(degree()$range, list(lower = 1, upper = 3)) @@ -83,6 +84,8 @@ test_that("param ranges", { expect_equal(harmonic_frequency(c(2, 100))$range, list(lower = 2, upper = 100)) expect_equal(validation_set_prop(c(0.1, 0.4))$range, list(lower = 0.1, upper = 0.4)) expect_equal(target_weight(c(0.1, 0.4))$range, list(lower = 0.1, upper = 0.4)) + expect_equal(lower_limit(c(Inf, 0))$range, list(lower = Inf, upper = 0)) + expect_equal(upper_limit(c(0, Inf))$range, list(lower = 0, upper = Inf)) })