metacausal.adapters.CausalMLAdapter

class metacausal.adapters.CausalMLAdapter(model, name=None, propensity_model=None)[source]

Bases: object

Wrap a CausalML estimator as a metacausal causal estimator.

Supports all three estimation families from the causalml package:

Meta-learners (causalml.inference.meta)

BaseSRegressor, BaseTRegressor, BaseXRegressor, BaseDRRegressor, BaseRRegressor, and their Classifier variants. predict(X) returns (n, 1); squeezed to (n,). estimate_ate() returns (ate, lb, ub) arrays of shape (1,).

Tree-based methods (causalml.inference.tree)

CausalTreeRegressor: predict(X) returns (n,) directly. UpliftTreeClassifier, UpliftRandomForestClassifier: predict(X) returns (n, 2) — P(Y=1|control) and P(Y=1|treatment). Uplift (CATE) is computed as treatment column minus control column. These models require string treatment labels; the adapter converts binary T automatically using model.control_name for control and "treatment" for the treated group.

TMLE (TMLELearner from causalml.inference.meta)

ATE-only (supports_cate=False). TMLELearner has no fit() or predict() — it does all work in estimate_ate(X, T, Y, p) where p is a required propensity-score array. The adapter fits the propensity model during fit(), seeds TMLE’s internal outcome learner, runs estimate_ate once, and caches the (ate, lb, ub) triple; ate() is then a constant-time lookup. Caching is necessary because TMLE’s estimate_ate refits its own outcome learner (with an un-seeded validation split) per call, which makes successive calls with identical inputs drift. Provide a propensity_model at construction time to customise the propensity estimator.

Parameters:
  • model (CausalML estimator) – An initialized (unfitted) CausalML estimator instance.

  • name (str or None) – Display name. Defaults to the class name of the wrapped model.

  • propensity_model (sklearn classifier or None) – Used only for TMLELearner. Fitted during fit() to produce the propensity scores p that TMLE requires. Default: LogisticRegression(max_iter=500). Ignored for all other CausalML estimators (they handle propensity internally or accept it optionally via their own p parameter).

Notes

Seed / reproducibility: CausalML has no uniform random_state in fit(). The adapter passes random_state as seed for BaseDRRegressor and BaseRRegressor (the only classes that accept it). For all other classes, set random_state at model construction time. CausalEnsemble forwards seeds but the wrapped model may ignore them.

Deep-copy requirement: the wrapped model must be deep-copyable for bootstrap resampling and cross-fitting. Standard sklearn-backed CausalML models are deep-copyable; models with GPU tensors or open file handles may fail.

Examples

>>> from causalml.inference.meta import BaseTRegressor
>>> from sklearn.ensemble import HistGradientBoostingRegressor as HGBR
>>> from metacausal.adapters import CausalMLAdapter
>>> from metacausal.datasets import load_lalonde
>>> X, T, Y = load_lalonde()
>>> t_learner = CausalMLAdapter(BaseTRegressor(learner=HGBR(max_iter=20)))
>>> t_learner.fit(X, T, Y, random_state=42)
>>> result = t_learner.ate()
>>> result
ComponentAteEstimate(ate=..., ci=[..., ...])

Methods

__init__

ate

Return the ATE.

cate

Return CATE predictions.

fit

Fit the wrapped CausalML model.

validate_outcome_type

Validate the wrapped CausalML model's nuisance configuration.

Attributes

Details

ate(X=None)[source]

Return the ATE.

TMLELearner: calls estimate_ate(X_train, T_train, Y_train, p=p_hat) using training data and cached propensity scores. The X argument is ignored — TMLE’s targeted update is tied to the training sample.

All other estimators: if estimate_ate() is available, calls it on the training data (regardless of X). CausalML’s DR-based ATE estimators require the original outcome and treatment data. Falls back to mean(cate(X_eval)) for estimators without estimate_ate() (e.g. uplift tree/forest).

Parameters:

X (ndarray | None)

Return type:

ComponentAteEstimate

cate(X)[source]

Return CATE predictions.

Squeezes (n, 1) meta-learner output to (n,). For uplift tree/forest, computes P(Y=1|T=1,X) - P(Y=1|T=0,X). Raises NotImplementedError for TMLELearner (ATE-only).

Parameters:

X (ndarray)

Return type:

ComponentCateEstimate

fit(X, T, Y, **kwargs)[source]

Fit the wrapped CausalML model.

For TMLELearner: fits the propensity model on (X, T) and caches the scores. TMLE itself has no fit() — all its work happens in ate() via estimate_ate().

For all other classes: deep-copies the model, maps our (X, T, Y) convention to CausalML’s (X, treatment, y) convention, and calls model.fit(). Passes random_state as seed for estimators whose fit() accepts that parameter (e.g. BaseDRRegressor).

Parameters:
Return type:

None

validate_outcome_type(detected)[source]

Validate the wrapped CausalML model’s nuisance configuration.

TMLELearner is the one quirk worth catching: even for binary outcomes, its learner slot must be a regressor — TMLE’s internal logit transform expects raw conditional means, not probabilities. For the meta-learner *Classifier family, outcome-slot classifier-ness is enforced by CausalML itself; the capability declaration here keeps them out of the continuous path so the misuse can’t arise.

Parameters:

detected (str)

Return type:

None

property name: str
property supports_cate: bool