*! version 30aug2024

Partially-linear model with pystacked and stacking:

Preparation: load the data, define global macros, set the seed and initialize the model.

. use https://github.com/aahrens1/ddml/raw/master/data/sipp1991.dta, clear

. global Y net_tfa

. global D e401

. global X tw age inc fsize educ db marr twoearn pira hown

. set seed 42

. ddml init partial, kfolds(2) reps(2)

Add supervised machine learners for estimating conditional expectations.
For simplicity, we use pystacked's default learners:
OLS, cross-validated lasso, and gradient boosting.

. ddml E[Y|X]: pystacked $Y $X

. ddml E[D|X]: pystacked $D $X

Cross-fitting and estimation:
The learners are iteratively fitted on the training data to obtain the estimated conditional expectations,
and then the causal coefficient of interest is estimated along with heteroskedastic-consistent SEs.
Note that the initial stacking is specified at the cross-fitting stage.
In addition to the standard stacking done by pystacked,
also request short-stacking and pooled-stacking to be done by ddml.

. ddml crossfit, shortstack poolstack

. ddml estimate, robust

Examine the standard (pystacked) stacking weights as well as
the ddml short-stacking and pooled-stacking weights.

. ddml extract, show(stweights)

. ddml extract, show(ssweights)

. ddml extract, show(psweights)

Re-stack without cross-fitting, using the single-best learner
instead of the default constrained nonlinear least squares.
We do this using the ddml estimate command.
Since no stacking method is specified,
restacking will be done for all three methods.

. ddml estimate, robust finalest(singlebest)

As above, but request short-stacking only at the cross-fitting stage.
Note the speed improvement.

. ddml crossfit, shortstack nostdstack

. ddml estimate, robust

Re-stack the above without cross-fitting, using OLS as the final estimator.
Use the option shortstack since only these results are re-stacked.

. ddml estimate, robust shortstack finalest(ols)

. ddml estimate, robust shortstack finalest(ols)

Extended example with specified pystacked learners and settings:

Same example as above, but specify the base learners explicitly.
We again make use of pystacked integration,
so there is a single call to pystacked for each conditional expectation.
The first learner in the stacked ensemble is OLS.
We also use cross-validated lasso, ridge and two random forests with different settings.
The settings are stored in macros for readability.

. ddml init partial, kfolds(2) reps(2)

. global rflow max_features(5) min_samples_leaf(1) max_samples(.7)

. global rfhigh max_features(5) min_samples_leaf(10) max_samples(.7)

. ddml E[Y|X]: pystacked $Y $X || method(ols) || method(lassocv) || method(ridgecv) || method(rf) opt($rflow) || method(rf) opt($rfhigh), type(reg)

. ddml E[D|X]: pystacked $D $X || method(ols) || method(lassocv) || method(ridgecv) || method(rf) opt($rflow) || method(rf) opt($rfhigh), type(reg)

Note: Options before ":" and after the first comma refer to ddml.
Options that come after the final comma refer to the estimation command.
Make sure to not confuse the two types of options.

The learners are iteratively fitted on the training data.
In addition to the standard stacking done by pystacked,
also request short-stacking to be done by ddml.
Finally, estimate the coefficients of interest.

. ddml crossfit, shortstack

. ddml estimate, robust

Examine the standard (pystacked) stacking weights as well as the ddml short-stacking weights.

. ddml extract, show(stweights)

. ddml extract, show(ssweights)