*! version 30aug2024

Models

Throughout we use Y to denote the outcome variable,
X to denote confounders,
Z to denote instrumental variable(s), and
D to denote the treatment variable(s) of interest.

Partially-linear model [partial]

Y = a.D + g(X) + U
D = m(X) + V

where the aim is to estimate a while controlling for X. To this end,
we estimate the conditional expectations
E[Y|X] and E[D|X] using a supervised machine learner.

Interactive model [interactive]

Y = g(X,D) + U
D = m(X) + V

which relaxes the assumption that X and D are separable.
D is a binary treatment variable,
and we aim to estimate the average treatment effect (ATE)
or average treatment effect on the treated (ATET).
We estimate the conditional expectations E[D|X], as well as
E[Y|X,D=0] and E[Y|X,D=1] (jointly added using ddml E[Y|X,D]).

Partially-linear IV model [iv]

Y = a.D + g(X) + U
Z = m(X) + V

where the aim is to estimate a.
We estimate the conditional expectations E[Y|X],
E[D|X] and E[Z|X] using a supervised machine
learner.

Flexible partially-linear IV model [fiv]

Y = a.D + g(X) + U
D = m(Z) + g(X) + V

where the estimand of interest is a.
We estimate the conditional expectations
E[Y|X],
E[D^|X] and D^:=E[D|Z,X] using a supervised machine
learner. The instrument is then formed as D^-E^[D^|X] where E^[D^|X] denotes
the estimate of E[D^|X].

Note: "" is a placeholder that is used because last step (estimation of E[D|X])
uses the fitted values from estimating E[D|X,Z].

Interactive IV model [interactiveiv]

Y = g(Z,X) + U
D = h(Z,X) + V
Z = m(X) + E

where the aim is to estimate the local average treatment effect (LATE).
We estimate, using a supervised machine
learner, the following conditional expectations:
E[Y|X,Z=0] and E[Y|X,Z=1] (jointly added using ddml E[Y|X,Z]);
E[D|X,Z=0] and E[D|X,Z=1] (jointly added using ddml E[D|X,Z]);
and E[Z|X].

Main steps when estimating with ddml

Estimation with ddml proceeds in four steps.

Step 1. Initialize ddml and select model:

ddml init
model [if] [in]
[ , mname(name) kfolds(integer)
fcluster(varname)
foldvar(varlist) reps(integer)
norandom tabfold vars(varlist) ]

where model is either partial, iv, interactive, fiv, interactiveiv;
see model descriptions.

Step 2. Add supervised ML programs for estimating conditional expectations:

ddml eq
[ , mname(name) vname(varname) learner(varname)
vtype(string)
predopt(string) ] :
command depvar vars [ , cmdopt ]

where, depending on model chosen in Step 1,
eq is either
E[Y|X] E[Y|D,X] E[Y|X,Z] E[D|X] E[D|X,Z] E[Z|X].
command is a supported supervised ML program (e.g. pystacked or cvlasso).
See supported programs.

Note: Options before ":" and after the first comma refer to ddml.
Options that come after the final comma refer to the estimation command.

Step 3. Cross-fitting:

ddml crossfit [ , mname(name) shortstack ]

This step implements the cross-fitting algorithm. Each learner is fitted iteratively on training folds and out-of-sample predicted values are obtained.

Step 4. Estimate causal effects:

ddml estimate [ , mname(name) robust cluster(varname) vce(type) atet ateu trim(real) ]

The ddml estimate command returns treatment effect estimates for all combination of learners
added in Step 2.

Optional. Report/post selected results:

ddml estimate [ , mname(name) spec(integer or string) rep(integer or string) allcombos notable replay ]

Optional. Retrieve information from ddml:

ddml extract [ object_name , mname(name) show(display_item) ename(name) vname(varname)
stata keys key1(string) key2(string) key3(string) subkey1(string)
subkey2(string) ]

display_item can be stweights, ssweights, psweights, weights, mse, n, or pystacked.
ddml stores many internal results on associative arrays.
See ddml extract for details.

For full details and further options, follow the links to the detailed help files above.

Compatible programs

ddml is compatible with a large set of user-written Stata commands.
It has been tested with

- the pystacked package (see pystacked and below).
Note that pystacked requires Stata 16.

- lassopack for regularized regression (see lasso2, cvlasso, rlasso).

- rforest by Zou & Schonlau. Note that rforest requires the option
vtype(none).

- svmachines by Guenther & Schonlau.

Beyond these, it is compatible with any Stata program that

- uses the standard "reg y x" syntax,

- supports if-conditions,

- and comes with predict post-estimation programs.

pystacked implements stacking regression (Wolpert, 1992)
via Stata's Python integration in combination with
scikit-learn's
sklearn.ensemble.StackingRegressor and
sklearn.ensemble.StackingClassifier.
Stacking is a way of combining multiple supervised
machine learners (the "base" or "level-0" learners) into
a meta learner.

pystacked is the recommended way to specify multiple learners in ddml.
pystacked provides a fast way of estimating all the learners in a single call to one program,
and ddml has integrated support for various features provided by pystacked.
ddml will store the predicted values of the specified base learners as well as the combined ("stacked") predicted values.
It also stores the stacking weights used by pystacked along with the ddml short-stacking weights.
See ddml stacking for more details.