knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.width = 6, fig.height = 5 )
classbound is an R package for exploring and comparing classification decision boundaries. Given a fitted classifier and a dataset, it answers a simple question: where in the feature space does the model change its prediction?
The package supports:
predict() returns class labelsexplorapp()) for visual explorationdevtools::install_github("natydasilva/classbound")
The classbound() wrapper fits a model, computes the decision boundary, and plots it in a single call.
library(classbound) library(palmerpenguins) penguins <- na.omit(penguins[, c("species", "bill_length_mm", "bill_depth_mm")]) classbound( data = penguins, formula = species ~ bill_length_mm + bill_depth_mm, classifier = rpart::rpart )
The colored regions show the predicted class for each point in the feature space. Training observations are overlaid as points colored by their true class.
For more control, use the three-step pipeline:
# Step 1: Fit the model model <- fit_model(penguins, species ~ bill_length_mm + bill_depth_mm, rpart::rpart) # Step 2: Compute the boundary grid model <- boundary_compute( model, feature_range = list(bill_length_mm = c(30, 60), bill_depth_mm = c(10, 25)), resolution = 80 ) # Step 3: Plot plot_boundary( model, obs_data = penguins, x_col = "bill_length_mm", y_col = "bill_depth_mm", true_label = "species" )
boundary_compute() returns the same model object with $boundary_data populated. This means you can reuse the same fitted model with different visualizations, zoom levels, or color settings without refitting.
classbound works with any classifier whose predict() method returns a vector of class labels. Most classifiers work automatically:
# SVM (returns class labels natively; no extra work needed) classbound(penguins, species ~ bill_length_mm + bill_depth_mm, e1071::svm) # Random forest (matrix interface: randomForest expects x and y separately) classbound(penguins, species ~ bill_length_mm + bill_depth_mm, randomForest::randomForest, interface = "matrix" )
For classifiers whose predict() returns a list or other complex object, use the predfun argument to extract the class labels:
# MASS::qda returns a list, so extract $class manually classbound( penguins, species ~ bill_length_mm + bill_depth_mm, MASS::qda, predfun = function(model, newdata, ...) predict(model, newdata, ...)$class )
Classifiers that return class probabilities (e.g., rpart, randomForest) enable a gradient visualization where decision regions are shaded by model confidence:
model <- fit_model(penguins, species ~ bill_length_mm + bill_depth_mm, rpart::rpart) model <- boundary_compute(model) plot_boundary( model, obs_data = penguins, x_col = "bill_length_mm", y_col = "bill_depth_mm", true_label = "species", show_gradient = TRUE )
Deep colors indicate high model confidence; faded colors near boundaries indicate uncertainty.
Classifiers that do not provide probabilities (e.g., standard SVMs, PPtree) always show flat solid regions regardless of show_gradient = TRUE.
For interactive exploration without writing code, launch the built-in Shiny application:
# Launch with a dataset pre-loaded explorapp(data = penguins, target_col = "species") # Or launch empty and simulate data interactively explorapp()
See the vignette("explorapp-guide") for a full walkthrough of the interactive features.
vignette("high-dimensional") (2D slice vs. projection) vignette("tidymodels-workflow") (comparing classifiers with boundary_workflow_set()) vignette("custom_adapters") (predfun and custom S3 adapters) vignette("tourr-workflow") (animated projection tours) Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.