Code
from _api_doc_utils import *Cross-fit partially linear Double ML
Group: Causal inference
PartiallyLinearDML estimates the treatment coefficient in
\[ y = \theta d + g(x) + u, \qquad d = m(x) + v, \]
using cross-fitted ridge nuisance regressions. The final coefficient is estimated from the orthogonalized residual-on-residual score. Fold membership is a deterministic seeded shuffle, so equal seeds reproduce assignments and different seeds change them.
Constructor: cm.PartiallyLinearDML
Use PartiallyLinearDML(penalty=None, cv=5, n_folds=5, seed=42), then fit(y, d, x). summary() reports the coefficient, robust standard error, covariance, and selected nuisance penalties by fold.
rng = np.random.default_rng(13)
x = rng.normal(size=(400, 4))
d = 0.3 + x @ np.array([0.5, -0.4, 0.2, 0.1]) + rng.normal(scale=0.8, size=400)
y = 1.3 * d + x @ np.array([0.4, -0.2, 0.1, 0.3]) + rng.normal(scale=0.6, size=400)
model = cm.PartiallyLinearDML(penalty=np.logspace(-4, 1, 10), cv=3, n_folds=4, seed=1)
model.fit(y, d, x)
print(model.summary()['coef'])
print(model.summary()['outcome_penalties'][:2])summary() contractThe table below is generated by fitting the live class in this repository and then inspecting summary(). Shapes are shown because most values are plain NumPy arrays or scalars.
rng = np.random.default_rng(113)
x = rng.normal(size=(160, 4))
d = 0.3 + x @ np.array([0.5, -0.4, 0.2, 0.1]) + rng.normal(size=160) * 0.8
y = 1.3 * d + x @ np.array([0.4, -0.2, 0.1, 0.3]) + rng.normal(size=160) * 0.6
model = cm.PartiallyLinearDML(penalty=np.logspace(-4, 1, 6), cv=3, n_folds=4, seed=1)
model.fit(y, d, x)
summary = model.summary()
display(HTML(html_table(["summary() key", "shape"], summary_shape_rows(summary))))