Predict from a brulee_tab_icl
Usage
# S3 method for class 'brulee_tab_icl'
predict(object, new_data, type = NULL, quantile_levels = (1:9)/10, ...)Arguments
- object
A
brulee_tab_iclobject frombrulee_tab_icl().- new_data
A data frame or matrix of new predictors.
- type
A single character string for the type of prediction. Valid options are:
"class"for hard class predictions (classification)."prob"for class probabilities (classification)."numeric"for the mean of the predictive distribution (regression)."quantile"for quantiles of the predictive distribution (regression)."variance"for its variance (regression).
If
NULL(the default), the natural type for the outcome is used:"class"for a factor outcome and"numeric"for a numeric one.- quantile_levels
A numeric vector of quantile levels, each in the open interval
(0, 1), sorted and unique. Only used whentype = "quantile". Defaults to(1:9) / 10.- ...
Not used, but required for extensibility.
Value
A tibble of predictions. The number of rows is guaranteed to match
new_data. For type = "prob" there is one column per outcome class;
otherwise there is a single prediction column: .pred_class for "class",
.pred for "numeric", .pred_variance for "variance", and
.pred_quantile for "quantile" (a hardhat::quantile_pred() vector
packing all requested levels into one column).
Details
Because TabICL is an in-context learner, prediction reloads the pretrained
weights from the checkpoint directory stored on object and conditions on the
training rows captured at fit time. The same preprocessing and ensembling used
for object are applied to new_data; see brulee_tab_icl() for details.
For classification, "prob" returns one column per class (named
.pred_<level>) and "class" returns the highest-probability class.
Ensembling and aggregation
The regression checkpoint is a quantile regression head: it emits a fixed
grid of quantile values for every row, which are monotonized and turned into
a continuous distribution (piecewise-linear between the knots, exponential
tails outside them). Every returned statistic is a readout from that
distribution, so quantile_levels does not change what the model computes,
only which values are read off afterwards. Any level in the open interval
(0, 1) is available, including levels far enough into the tails to be
extrapolated.
With num_estimators > 1, each ensemble member yields its own distribution
and the members are combined on the outcome's scale. The combination rule
depends on the statistic:
.predis the arithmetic mean across members of each member's distribution mean..pred_quantileaverages the members' quantile curves level by level (Vincentization). Averaging monotone curves preserves monotonicity, so the pooled result is still a valid quantile function..pred_varianceis the geometric mean across members. A variance is a positive scale parameter, so members are pooled multiplicatively.
Two consequences are worth stating plainly. First, .pred is the mean of the
predictive distribution, so it is not the same as the 0.5 entry of
.pred_quantile; this differs from predict.brulee_chronos(), where .pred
is defined to be the median. Second, .pred_variance pools each member's own
variance and so does not include the spread between members' central
estimates; it will not equal the variance implied by .pred_quantile.
.pred_variance is on the squared scale of the outcome. The target is
standardized internally and the variance is scaled back by the square of the
target's standard deviation. Note that the reference Python implementation
instead applies the full location-scale inverse to the variance; brulee's
values differ from it deliberately.
Examples
if (FALSE) { # \dontrun{
if (rlang::is_installed(c("MASS", "ggplot2")) &
tab_icl_weights_available() &
interactive()) {
library(ggplot2)
motorcycles <- MASS::mcycle
in_tr <- seq(1, nrow(motorcycles), by = 2)
mcycle_tr <- motorcycles[in_tr, ]
mcycle_te <- motorcycles[-in_tr, ]
mcycle_grid <-
dplyr::tibble(
times = seq(min(motorcycles$times), max(motorcycles$times), length.out = 200)
)
mcycle_grid$.row <- seq_len(nrow(mcycle_grid))
fit <- brulee_tab_icl(accel ~ times, data = mcycle_tr)
# ------------------------------------------------------------------------------
# Predict mean acceleration
mean_pred <- predict(fit, mcycle_grid) |> dplyr::bind_cols(mcycle_grid)
mean_p <-
mean_pred |>
ggplot(aes(times)) +
geom_point(data = mcycle_te, aes(y = accel), alpha = 1 / 2) +
geom_line(aes(y = .pred))
#------------------------------------------------------------------------------Predict 5 %, 50%
# Predict 5%, 50%, and 90% quantiles of acceleration
q_pred <-
predict(fit,
mcycle_grid,
type = "quantile",
quantile_levels = c(0.1, 0.5, 0.9))
q_pred$.row <- seq_len(nrow(q_pred))
q_pred_longer <-
q_pred$.pred_quantile |>
dplyr::as_tibble() |>
dplyr::full_join(mcycle_grid, by = ".row") |>
dplyr::mutate(level = format(.quantile_levels))
mean_p +
geom_line(
data = q_pred_longer,
aes(y = .pred_quantile, col = level, group = level)
)
}
} # }
