metacausal.aggregation.CBA

class metacausal.aggregation.CBA(eps=0.01)[source]

Bases: AgreementStrategy

Consensus Based Averaging (Machluf et al., 2024).

Selects a high-agreement subset of component models via Kendall’s tau rank correlation and averages them with uniform weights.

The algorithm:

  1. Compute pairwise Kendall’s tau between all component CATE predictions.

  2. Compute mean tau per model (how well each model agrees with others).

  3. Sort models descending by mean tau.

  4. Find the “knee” — the largest drop in consecutive mean taus.

  5. Select models above the knee and average with uniform weights.

Complexity is O(K² n log n) for pairwise Kendall’s tau; practical for K < ~20 component models.

Source: Machluf et al. (2024). “Robust CATE Estimation Using Novel Ensemble Methods.” arXiv:2407.03690, Appendix A.

Parameters:

eps (float) – Tolerance for the flat-differences guard. If max(diff) - min(diff) < eps, all consecutive drops are considered equal and all models are selected (no meaningful knee exists). Metacausal-specific default; not from the original paper.

Examples

>>> from sklearn.linear_model import LinearRegression
>>> from sklearn.ensemble import HistGradientBoostingRegressor as HGBR
>>> from metacausal import CausalEnsemble
>>> from metacausal.adapters import GenericCATEAdapter
>>> from metacausal.aggregation import CBA
>>> from metacausal.datasets import load_lalonde
>>> X, T, Y = load_lalonde()
>>> def fit_linear(X, T, Y, **kwargs):
...     treated = T == 1
...     m1 = LinearRegression().fit(X[treated], Y[treated])
...     m0 = LinearRegression().fit(X[~treated], Y[~treated])
...     return (m1, m0)
>>> def fit_hgb(X, T, Y, **kwargs):
...     treated = T == 1
...     m1 = HGBR(max_iter=20).fit(X[treated], Y[treated])
...     m0 = HGBR(max_iter=20).fit(X[~treated], Y[~treated])
...     return (m1, m0)
>>> def cate_fn(state, X):
...     m1, m0 = state
...     return m1.predict(X) - m0.predict(X)
>>> methods = [
...     GenericCATEAdapter(fit_linear, cate_fn, name="linear"),
...     GenericCATEAdapter(fit_hgb, cate_fn, name="hgb"),
... ]
>>> ens = CausalEnsemble(methods=methods, aggregation=CBA())
>>> _ = ens.fit(X, T, Y, random_state=42)
>>> ens.ate()
AteEstimate(ate=..., n_methods=2, aggregation='CBA', spread=...)

Methods

__init__

aggregate

Aggregate component CATEs using stored weights.

compute_weights

Compute CBA weights from training-data CATE predictions.

Attributes

ensemble_weights

Ensemble weights computed during fit().

eps

strategy_family

Details

compute_weights(cate_matrix, model_names)[source]

Compute CBA weights from training-data CATE predictions.

Called once during CausalEnsemble.fit().

Parameters:
  • cate_matrix (array of shape (K, n)) – Training-data CATE predictions, one row per model.

  • model_names (list[str]) – Adapter names in the same order as rows of cate_matrix.

Returns:

EnsembleWeights with uniform weights over the selected subset.

Return type:

EnsembleWeights

eps: float = 0.01