Description
DifferenceInDifferences mutates sklearn models by forcing fit_intercept=False inside the experiment constructor. This is a hidden side effect: callers pass in a configured estimator, but the experiment overrides one of its key hyperparameters without explicit opt-in. This can be surprising in interactive workflows and makes it hard to reuse the same estimator instance across experiments because its configuration is modified in place.
Steps to Reproduce
- Create a sklearn regressor with
fit_intercept=True.
- Pass it into
DifferenceInDifferences.
- Observe that
fit_intercept has been mutated to False.
from sklearn.linear_model import LinearRegression
import causalpy as cp
model = LinearRegression(fit_intercept=True)
_ = cp.DifferenceInDifferences(..., model=model)
assert model.fit_intercept is False # mutated by experiment
Expected Behavior
Experiments should not mutate user-supplied models implicitly. If the experiment requires fit_intercept=False for correctness, it should either document this requirement, validate and raise, or create an internal copy of the estimator with the required settings.
Actual Behavior
DifferenceInDifferences sets model.fit_intercept = False without warning or user consent.
Environment
- CausalPy version: 0.7.0 (or current main)
- Python version: 3.11+
- OS: macOS (darwin)
Proposed Solution (if known)
- Preferred direction: document and validate. Require
fit_intercept=False and raise a clear error if not set.
- Clone the estimator (e.g.,
sklearn.base.clone) and adjust the copy instead of mutating the original.
- Move this behavior into
ScikitLearnAdaptor or a dedicated wrapper so the mutation is explicit and centralized.
Additional Context
Current code in DifferenceInDifferences:
if hasattr(self.model, "fit_intercept"):
self.model.fit_intercept = False
Description
DifferenceInDifferencesmutates sklearn models by forcingfit_intercept=Falseinside the experiment constructor. This is a hidden side effect: callers pass in a configured estimator, but the experiment overrides one of its key hyperparameters without explicit opt-in. This can be surprising in interactive workflows and makes it hard to reuse the same estimator instance across experiments because its configuration is modified in place.Steps to Reproduce
fit_intercept=True.DifferenceInDifferences.fit_intercepthas been mutated toFalse.Expected Behavior
Experiments should not mutate user-supplied models implicitly. If the experiment requires
fit_intercept=Falsefor correctness, it should either document this requirement, validate and raise, or create an internal copy of the estimator with the required settings.Actual Behavior
DifferenceInDifferencessetsmodel.fit_intercept = Falsewithout warning or user consent.Environment
Proposed Solution (if known)
fit_intercept=Falseand raise a clear error if not set.sklearn.base.clone) and adjust the copy instead of mutating the original.ScikitLearnAdaptoror a dedicated wrapper so the mutation is explicit and centralized.Additional Context
Current code in
DifferenceInDifferences: