boundary_compute: Compute the classification decision boundary

View source: R/boundary_compute.R

boundary_computeR Documentation

Compute the classification decision boundary

Description

Generates a 2D grid of predicted class labels (and optionally class probabilities) for a fitted classbound model. The resulting boundary data is stored in the returned object and consumed directly by plot_boundary().

Usage

boundary_compute(
  model,
  feature_range = NULL,
  resolution = 100,
  predfun = NULL,
  projection = NULL,
  reference = NULL,
  ...
)

Arguments

model

A classbound model object returned by fit_model() or as_classbound(), or a named list of classbound objects for multi-model comparison. All models in a list must share the same training features and class levels.

feature_range

A named list of length 2 specifying the axis ranges, e.g., list(bill_length_mm = c(30, 60), bill_depth_mm = c(10, 25)). Alternatively, a character vector of exactly two feature names (ranges computed from training data). If NULL and the model has exactly two numeric features, ranges are auto-detected. When projection is provided, this defines the limits of the 2D projected space.

resolution

An integer >= 2 specifying the number of grid points per axis. Higher values produce smoother boundaries. Default is 100; use 50 for faster interactive exploration.

predfun

An optional custom prediction function for non-standard classifiers. Must accept ⁠(model, newdata, ...)⁠ and return a vector/factor of predicted classes, or a list with ⁠$class⁠ (factor) and ⁠$probs⁠ (probability matrix or NULL).

projection

An optional named list defining a high-dimensional projection. Must contain ⁠$basis⁠ (a numeric matrix, rows = features, columns = 2 axes, must be orthonormal). Optionally contains ⁠$center⁠ and ⁠$scale⁠ (numeric vectors of length equal to the number of features) to reverse pre-projection standardization. Only supported for models trained on numeric features.

reference

An optional named list of fixed reference values for features not specified in feature_range (2D slice mode only). Names must match training feature names. If NULL, numeric features are imputed at their median and categorical features at their mode.

...

Additional arguments passed to predict_model().

Details

2D slice (two-feature visualization)

When projection is NULL, boundary_compute() generates a regular grid over the two features named in feature_range. If the model was trained on more than two features, all remaining numeric features are fixed at their training-set median and categorical features at their training-set mode, unless you supply explicit values via reference.

This is a 2D slice of the full multivariate decision boundary. Two observations that appear in the same region may still be separated in a dimension that is held fixed. Use this mode when you want to examine how two specific features interact, or when your model was trained on exactly two features.

Projection (high-dimensional visualization)

When projection is provided, the 2D grid is generated in the projected space and then inverse-projected back to the original feature space before prediction. This means the model uses all of its training features; only the visualization is collapsed to two dimensions.

The projection ⁠$basis⁠ must be a numeric matrix with:

  • row count equal to the number of training features, row names matching feature names

  • exactly two columns (the projected axes)

  • orthonormal columns (crossprod(basis) must equal diag(2))

Suitable bases can be obtained from prcomp() or the tourr package.

Multi-model comparison

Pass a named list of classbound objects (all trained on the same features and class levels) to compute boundaries for multiple models at once. The result contains a model column, suitable for use with plot_boundary(facet_col = "model").

Value

A modified classbound object with the additional class "classbound_boundary". The boundary grid is stored in ⁠$boundary_data⁠ (columns: x, y, prediction, and per-class probability columns when available). For multi-model input, also contains a model column.

See Also

fit_model(), plot_boundary(), boundary_workflow_set()

Examples


library(palmerpenguins)
data(penguins)
peng_data <- na.omit(penguins[, c("species", "bill_length_mm", "bill_depth_mm")])

# Fit and compute 2D boundary with auto-detected ranges
m <- fit_model(peng_data, species ~ ., rpart::rpart)
m <- boundary_compute(m, resolution = 50)
head(m$boundary_data)

# Explicit axis ranges
m <- boundary_compute(m,
  feature_range = list(bill_length_mm = c(30, 60), bill_depth_mm = c(10, 25)),
  resolution = 100
)

# 3-feature model visualized as a 2D slice
peng3d <- na.omit(penguins[, c(
  "species", "bill_length_mm",
  "bill_depth_mm", "flipper_length_mm"
)])
m3d <- fit_model(peng3d, species ~ ., rpart::rpart)
m3d_slice <- boundary_compute(m3d,
  feature_range = list(bill_length_mm = c(30, 60), bill_depth_mm = c(10, 25)),
  resolution = 50
)

# 3-feature model visualized via PCA projection
feat_cols <- c("bill_length_mm", "bill_depth_mm", "flipper_length_mm")
pca <- prcomp(peng3d[, feat_cols], scale. = TRUE)
basis <- pca$rotation[, 1:2]
m3d_proj <- boundary_compute(m3d,
  feature_range = list(PC1 = c(-4, 4), PC2 = c(-3, 3)),
  resolution = 50,
  projection = list(basis = basis, center = pca$center, scale = pca$scale)
)


classbound documentation built on Sept. 30, 2026, 5:13 p.m.