Attaches pointwise confidence intervals to the CATE predictions of any fitted meta-learner (s_learner(), t_learner(), x_learner(), dr_learner(), r_learner()) using the nonparametric bootstrap. For each of n_boot replicates the training data is resampled with replacement, the entire learner pipeline (including any nuisance models and cross-fitting) is refitted, and CATEs are predicted for newdata. A pointwise interval is then formed from the bootstrap distribution at each row of newdata.

cate_ci(
  object,
  newdata,
  train_data,
  n_boot = 200,
  level = 0.95,
  type = c("percentile", "normal"),
  ...
)

Arguments

object

A fitted meta-learner of class "cate_learner".

newdata

A data.frame of points at which to predict CATEs and their intervals; must contain the covariate columns.

train_data

The data.frame the model was fitted on (with the outcome, treatment and covariate columns), used to draw the bootstrap resamples on which the pipeline is refitted.

n_boot

Number of bootstrap replicates. Default 200.

level

Confidence level. Default 0.95.

type

Interval type. "percentile" (default) uses the empirical quantiles of the bootstrap CATEs; "normal" centres the interval on the point estimate and uses a normal-quantile multiple of the bootstrap standard error.

...

Ignored.

Value

A data.frame with one row per row of newdata and columns estimate (the point CATE from object), se (the bootstrap standard error) and lower/upper (the confidence limits).

Details

Because the meta-learners accept arbitrary (and typically non-smooth) machine-learning base learners, no closed-form standard error is available for \(\hat\tau(x)\); the bootstrap is the one mechanism that applies uniformly across all five learners. Two caveats are worth keeping in mind. First, bootstrap coverage for CATEs estimated with flexible learners is only approximate and can be anti-conservative, so the intervals are best read as a measure of estimation stability rather than exact frequentist coverage. Second, refitting the full pipeline n_boot times is computationally expensive. Set the seed with set.seed() beforehand for reproducibility.

Examples

# \donttest{
library(mlr3)
data(synth_train)
data(synth_test)
set.seed(1)
m <- t_learner(synth_train, outcome = "y", treatment = "t",
               learner = lrn("regr.rpart"))
ci <- cate_ci(m, synth_test, train_data = synth_train, n_boot = 50)
head(ci)
#>     estimate       se      lower    upper
#> 1 -1.2920574 1.320084 -2.5701632 1.939378
#> 2 -0.2280423 1.992101 -3.5247973 2.809399
#> 3  1.5599339 1.078420 -0.1271374 3.488867
#> 4 -0.4125864 1.559691 -2.3463466 3.128760
#> 5  0.1015885 1.422533 -2.1076826 2.452699
#> 6 -2.9193186 1.634543 -4.5333756 1.715560
# }