1. Training a Modified Causal Forest#
Regression tree splits the data into non-overlapping strata thanks to its non-parametric nature. The average of the dependent variable within each strata serve as the prediction for observations with similar covariate values. An issue with this approach is that using discrete, non-overlapping data splits can be inefficient, since valuable information from neighboring data points is not used. Furthermore, the curse of dimensionality makes it challenging to consistently fit stable splits with good performance. Lastly, the number of potential data splits grows significantly as the number of covariates increases, which can lead to exponential increases in computing time if all possible splits are evaluated at each node of the tree.
Random forest (to some extent) solves these problems by building many decorrelated trees and averaging their predictions. To do so, different random samples of the data, generated by bootstrapping or subsampling, and random subsets of covariates for each splitting decision in an individual leaf are used to build each tree.
The mcf estimates causal effects under a causal identification model and uses separate construction and filling samples for honesty. The research establishes asymptotic properties under identification, honesty, regularity and sampling assumptions; optional implementation settings do not by themselves establish all those conditions. See Lechner and Mareckova (2024).
1.1. Forest Growing#
Each node selects the best admissible split under cf_mce_vart:
Value |
Objective |
|---|---|
|
Outcome-regression mean squared error (MSE). |
|
Outcome MSE plus mean correlated errors (MCE), with the applicable additive treatment penalty. Default. |
|
Negative effect variance, favoring heterogeneous effects. |
|
Random switching between the outcome MSE/MCE objective and the treatment-prediction penalty objective. |
For criteria 1 and 3, cf_mce_type='cross_error' is the default.
It averages products of matched-outcome errors centered at the observed
treatment-specific leaf means. cf_mce_type='covariance' instead centers matched outcomes
at their matched-sample means.
How the program matches is governed by the argument cf_match_nn_prog_score.
The program matches either by outcome scores (one per treatment) or on all covariates by Mahalanobis matching. If there are many covariates, it is advisable to match on outcome scores due to the curse of dimensionality. When performing Mahalanobis matching, a practical issue may be that the required inverse of the covariance matrix is unstable. For this reason the program allows to only use the main diagonal to invert the covariance matrix. This is regulated via the argument cf_nn_main_diag_only.
The treatment penalty favors splits that help predict treatment assignment.
Each split must still leave enough observations from every treatment group
in both daughter nodes, as required by cf_n_min_treat. It must also
satisfy the minimum proportions controlled by cf_alpha_reg_min and
cf_alpha_reg_max. With cf_alpha_reg_type='treatment' (the default
for discrete treatments), these proportions apply separately to each
treatment group. cf_penalty_type='mse_d'
and 'diff_d' provide alternative constructions; cf_p_diff_penalty controls
the penalty.
1.2. Split balance and candidate variables#
For discrete treatments, cf_alpha_reg_type='treatment' requires each daughter
to retain at least an alpha share of each parent treatment group, rounded upward
and subject to treatment-specific minima. Continuous treatments use pooled
balance. The admissible alpha range is \(0 \leq \alpha < 0.5\); the default
one-point grid resolves to 0.10.
cf_m_grid is the number of candidate-count grid values.
Candidate counts follow the share bounds. With
Poisson randomization, a nominal count \(m\) becomes
\(1+\operatorname{Poisson}(m-1)\), capped by the available variables.
Always-in variables have priority; when the draw is smaller than their number,
only a random subset is considered.
If the initial randomized search finds no admissible split, the algorithm retries all available variables and supported thresholds. Minimum-cell and balance restrictions still apply.
1.3. Filling the leaves#
After the trees are constructed, a separate sample is used to estimate the potential outcomes within their leaves. These observations were not used to choose the splits.
cf_subsample_power_eval and cf_subsample_factor_eval control how
many observations from this sample are used to fill each tree. Set
cf_subsample_factor_eval=False to use all available filling
observations. Larger filling samples can reduce the number of empty
leaves but require more computation.
See the API for details.
1.3.1. Example#
The following block illustrates a configuration; call train() and
predict() as in Getting started to obtain estimates.
from mcf.example_data import example_data
from mcf.mcf_main import ModifiedCausalForest
# Generate example data using the built-in function `example_data()`
training_df, prediction_df, name_dict = example_data()
my_mcf = ModifiedCausalForest(
var_y_name="outcome",
var_d_name="treat",
var_x_name_ord=["x_cont0", "x_cont1", "x_ord1"],
# Determine splitting rule when growing trees
cf_mce_vart = 3,
# Determine penalty function
cf_p_diff_penalty = 3,
# Determine method of nearest neighbour matching
cf_match_nn_prog_score = True,
# Type of penalty function
cf_penalty_type='mse_d'
)