Part of #980 (v1.0 M1). Closes #854 when it lands.
Reordering fit to (X, y, treatment, …) is necessary but not sufficient for #854. Pipeline.fit(X, y) passes exactly two things; treatment is a third required array with nowhere to ride. After the flip a CausalML learner still can't be a Pipeline step without an adapter — the reordering just removes the first obstacle.
The mechanism sklearn provides is metadata routing: fit(X, y, **fit_params) with set_fit_request(treatment=True), so a caller writes pipe.fit(X, y, treatment=treatment) and the router delivers treatment to the step that asked for it.
Scope
- Implement metadata routing for
treatment (and p, where learners accept propensity scores) on the meta-learners first — they are the classes users most want inside a Pipeline.
- Decide the interaction with
sklearn.set_config(enable_metadata_routing=True), which is opt-in and off by default: does CausalML require it, or support both paths?
- Establish which transformers in a Pipeline are expected to pass
treatment through untouched, and what happens when an intermediate step resamples rows.
- End-to-end test: a real
Pipeline([...]) with a CausalML learner as the final step, fit and predicted without an adapter.
Why it's separate
The argument order is a breaking change on a deadline (v1.0 API freeze); routing is additive and can land any time after. Coupling them would put a design-heavy feature on the critical path of a mechanical rename.
Acceptance
Part of #980 (v1.0 M1). Closes #854 when it lands.
Reordering
fitto(X, y, treatment, …)is necessary but not sufficient for #854.Pipeline.fit(X, y)passes exactly two things;treatmentis a third required array with nowhere to ride. After the flip a CausalML learner still can't be a Pipeline step without an adapter — the reordering just removes the first obstacle.The mechanism sklearn provides is metadata routing:
fit(X, y, **fit_params)withset_fit_request(treatment=True), so a caller writespipe.fit(X, y, treatment=treatment)and the router deliverstreatmentto the step that asked for it.Scope
treatment(andp, where learners accept propensity scores) on the meta-learners first — they are the classes users most want inside a Pipeline.sklearn.set_config(enable_metadata_routing=True), which is opt-in and off by default: does CausalML require it, or support both paths?treatmentthrough untouched, and what happens when an intermediate step resamples rows.Pipeline([...])with a CausalML learner as the final step, fit and predicted without an adapter.Why it's separate
The argument order is a breaking change on a deadline (v1.0 API freeze); routing is additive and can land any time after. Coupling them would put a design-heavy feature on the critical path of a mechanical rename.
Acceptance
Pipelinefinal step withtreatmentrouted, no adapter class.