Skip to content

DifferenceInDifferences mutates fit_intercept on user models #664

@drbenvincent

Description

@drbenvincent

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

  1. Create a sklearn regressor with fit_intercept=True.
  2. Pass it into DifferenceInDifferences.
  3. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions