Meta-Learners
onlinecml.metalearners.s_learner.OnlineSLearner
Bases: BaseOnlineEstimator
Online S-Learner for CATE estimation via a single augmented model.
Trains a single outcome model on features augmented with the treatment indicator. CATE is estimated as the difference in predictions when the treatment indicator is set to 1 vs 0, holding covariates fixed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Regressor or None
|
A River regressor. Must support |
None
|
treatment_feature
|
str
|
Name of the synthetic treatment feature added to |
'__treatment__'
|
Notes
Predict-then-learn: At each step, CATE is predicted before the model is updated. This avoids look-ahead bias in the running ATE.
Limitation: Because treatment is just another feature, the
S-Learner can under-regularize the treatment effect and produce
biased CATE estimates when treatment is rare or the model is
mis-specified. For better CATE estimates, prefer OnlineTLearner
or OnlineRLearner.
Examples:
>>> from onlinecml.datasets import LinearCausalStream
>>> from river.linear_model import LinearRegression
>>> model = OnlineSLearner(LinearRegression())
>>> for x, w, y, _ in LinearCausalStream(n=200, seed=42):
... model.learn_one(x, w, y)
>>> isinstance(model.predict_ate(), float)
True
Source code in onlinecml/metalearners/s_learner.py
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | |
learn_one(x, treatment, outcome, propensity=None)
Process one observation and update the outcome model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
dict
|
Feature dictionary for this observation. |
required |
treatment
|
int
|
Treatment indicator (0 = control, 1 = treated). |
required |
outcome
|
float
|
Observed outcome. |
required |
propensity
|
float or None
|
Not used by S-Learner; included for API compatibility. |
None
|
Source code in onlinecml/metalearners/s_learner.py
predict_one(x)
Predict the CATE for a single unit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
dict
|
Feature dictionary for the unit. |
required |
Returns:
| Type | Description |
|---|---|
float
|
Estimated CATE: |
Source code in onlinecml/metalearners/s_learner.py
onlinecml.metalearners.t_learner.OnlineTLearner
Bases: BaseOnlineEstimator
Online T-Learner for CATE estimation via two separate outcome models.
Trains one model on treated units and one on control units. CATE is estimated as the difference in predictions from the two models.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
treated_model
|
Regressor or None
|
Model for treated units |
None
|
control_model
|
Regressor or None
|
Model for control units |
None
|
Notes
Predict-then-learn: CATE is predicted from both models before either model is updated. This avoids look-ahead bias.
IPW correction: If propensity is passed to learn_one,
the sample weight 1/p (treated) or 1/(1-p) (control) is
passed as w to the model's learn_one call. This corrects
for treatment imbalance. If the River model does not support sample
weights, the weight is silently ignored.
Single-arm cold start: If only one treatment arm has been seen,
the other model returns 0 (River default for untrained regression).
A UserWarning is emitted on predict_one when either model
has seen no data.
Examples:
>>> from onlinecml.datasets import LinearCausalStream
>>> from river.linear_model import LinearRegression
>>> model = OnlineTLearner(LinearRegression(), LinearRegression())
>>> for x, w, y, _ in LinearCausalStream(n=200, seed=42):
... model.learn_one(x, w, y)
>>> isinstance(model.predict_one({"x0": 0.5}), float)
True
Source code in onlinecml/metalearners/t_learner.py
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | |
learn_one(x, treatment, outcome, propensity=None)
Process one observation and update the appropriate arm model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
dict
|
Feature dictionary for this observation. |
required |
treatment
|
int
|
Treatment indicator (0 = control, 1 = treated). |
required |
outcome
|
float
|
Observed outcome. |
required |
propensity
|
float or None
|
If provided, computes IPW weight |
None
|
Source code in onlinecml/metalearners/t_learner.py
predict_one(x)
Predict the CATE for a single unit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
dict
|
Feature dictionary for the unit. |
required |
Returns:
| Type | Description |
|---|---|
float
|
Estimated CATE: |
Warns:
| Type | Description |
|---|---|
UserWarning
|
If either arm model has not seen any data yet, the prediction from that model defaults to 0 (River's untrained regressor default), which may bias the CATE estimate. |
Source code in onlinecml/metalearners/t_learner.py
onlinecml.metalearners.x_learner.OnlineXLearner
Bases: BaseOnlineEstimator
Online X-Learner for CATE estimation in unbalanced treatment groups.
Implements a three-stage pipeline adapted for the online setting:
-
Stage 1 (T-Learner base): Train two outcome models
mu1(x) = E[Y|X, W=1]andmu0(x) = E[Y|X, W=0]. -
Stage 2 (Imputed effects): For each treated unit, impute a control potential outcome:
D1 = Y - mu0(X). For each control unit:D0 = mu1(X) - Y. -
Stage 3 (CATE models): Train two CATE models —
tau1on treated units' imputed effects andtau0on control units'. The final CATE is a propensity-weighted combination:CATE(x) = p(x) * tau0(x) + (1-p(x)) * tau1(x).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mu1_model
|
Regressor or None
|
Outcome model for treated units. Defaults to |
None
|
mu0_model
|
Regressor or None
|
Outcome model for control units. Defaults to |
None
|
tau1_model
|
Regressor or None
|
CATE model trained on treated units' imputed effects.
Defaults to |
None
|
tau0_model
|
Regressor or None
|
CATE model trained on control units' imputed effects.
Defaults to |
None
|
ps_model
|
OnlinePropensityScore or None
|
Propensity score model for the weighted combination.
Defaults to |
None
|
Notes
Predict-first-then-learn: All five models predict before any are updated. This approximates the cross-fitting required for stage 2.
The X-Learner is most effective when treatment groups are substantially unbalanced — it leverages information from the larger group to improve CATE estimates for the smaller group.
Examples:
>>> from onlinecml.datasets import LinearCausalStream
>>> model = OnlineXLearner()
>>> for x, w, y, _ in LinearCausalStream(n=500, seed=42):
... model.learn_one(x, w, y)
>>> isinstance(model.predict_one({"x0": 0.5}), float)
True
Source code in onlinecml/metalearners/x_learner.py
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | |
learn_one(x, treatment, outcome, propensity=None)
Process one observation and update all internal models.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
dict
|
Feature dictionary for this observation. |
required |
treatment
|
int
|
Treatment indicator (0 = control, 1 = treated). |
required |
outcome
|
float
|
Observed outcome. |
required |
propensity
|
float or None
|
If provided, used for the weighted combination instead of the internal propensity model. |
None
|
Source code in onlinecml/metalearners/x_learner.py
predict_one(x)
Predict the CATE for a single unit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
dict
|
Feature dictionary for the unit. |
required |
Returns:
| Type | Description |
|---|---|
float
|
Estimated CATE: propensity-weighted combination of
|
Source code in onlinecml/metalearners/x_learner.py
onlinecml.metalearners.r_learner.OnlineRLearner
Bases: BaseOnlineEstimator
Online R-Learner for CATE via the Robinson (1988) transformation.
Estimates CATE by orthogonalizing the treatment assignment and outcome with respect to their conditional means. The residualized targets are:
.. math::
\tilde{W}_i = W_i - \hat{p}(X_i)
\tilde{Y}_i = Y_i - \hat{m}(X_i)
The CATE model is then trained on the pseudo-outcome
tilde_Y / tilde_W weighted by tilde_W^2:
.. math::
\hat{\tau}(x) = \arg\min_\tau
\mathbb{E}[(\tilde{Y}_i - \tau(X_i) \tilde{W}_i)^2]
This approach is the theoretical foundation of Double Machine Learning (DML) and produces nearly oracle-rate CATE estimates when both nuisance models are consistent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ps_model
|
OnlinePropensityScore or None
|
Propensity score model |
None
|
outcome_model
|
Regressor or None
|
Outcome model |
None
|
cate_model
|
Regressor or None
|
CATE model trained on Robinson-residualized targets.
Defaults to |
None
|
Notes
Predict-first-then-learn: All three models predict before any are updated. This is the natural online approximation to cross-fitting.
Residual weighting: The CATE model is updated with sample weight
w = tilde_W^2 when the River model supports sample weights. When
|tilde_W| is very small (near 0.05), the update is skipped to
avoid noisy updates from nearly-deterministic treatment assignments.
Connection to DML: The R-Learner is equivalent to Partially Linear DML (Robinson 1988, Chernozhukov et al. 2018) when the CATE model is linear.
References
Robinson, P.M. (1988). Root-N-consistent semiparametric regression. Econometrica, 56(4), 931-954.
Nie, X. and Wager, S. (2021). Quasi-oracle estimation of heterogeneous treatment effects. Biometrika, 108(2), 299-319.
Examples:
>>> from onlinecml.datasets import LinearCausalStream
>>> from river.linear_model import LinearRegression, LogisticRegression
>>> model = OnlineRLearner(
... ps_model=None,
... outcome_model=LinearRegression(),
... cate_model=LinearRegression(),
... )
>>> for x, w, y, _ in LinearCausalStream(n=500, seed=42):
... model.learn_one(x, w, y)
>>> isinstance(model.predict_ate(), float)
True
Source code in onlinecml/metalearners/r_learner.py
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | |
learn_one(x, treatment, outcome, propensity=None)
Process one observation using the Robinson transformation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
dict
|
Feature dictionary for this observation. |
required |
treatment
|
int
|
Treatment indicator (0 = control, 1 = treated). |
required |
outcome
|
float
|
Observed outcome. |
required |
propensity
|
float or None
|
If provided, uses this logged propensity instead of the internal model. |
None
|
Source code in onlinecml/metalearners/r_learner.py
predict_one(x)
Predict the CATE for a single unit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
dict
|
Feature dictionary for the unit. |
required |
Returns:
| Type | Description |
|---|---|
float
|
Estimated CATE from the Robinson-residualized model. |