cleverly.datasets.make_missing_outcome_bounded#

cleverly.datasets.make_missing_outcome_bounded(n: int = 1000, *, seed: int | Generator | None = None, strength: float = 2.0, backend: Literal['pandas', 'polars'] | str | None = None) → tuple[Any, dict[str, float]][source]#

Missing outcomes on the known support (0, 1), with a nonlinear outcome mean.

Parameters:
nint

Number of observations.

seedint, Generator, or None

Seed or NumPy random generator.

strengthfloat

The strength of make_missing_outcome(). See its Notes.

backend{“pandas”, “polars”, “pyarrow”} or None, default=None

Dataframe backend. None uses pandas when installed, then the first available backend.

Returns:
dataframe

Simulated observations with a proportion outcome that holds missing values.

truthdict of str to float

Exact causal parameters for the data-generating process.

See also

cleverly.datasets.make_missing_outcome

The same mechanisms with an unbounded outcome.

Notes

The outcome is a proportion. Its known support is the open interval (0, 1), so a cross-fitted fit can declare q_bounds=(0, 1). The bounds come from the law, not from the observed outcomes. missing_outcome_bounded_dgp() gives the outcome mean.

At the default strength=2 the effect varies with W1, and the response probability falls as W1 rises. The effect standardized to the respondents’ covariates therefore differs from the ATE.

Examples

>>> from cleverly.datasets import make_missing_outcome_bounded
>>> frame, truth = make_missing_outcome_bounded(n=200, seed=1)
>>> list(frame.columns)
['Y', 'A', 'W1', 'W2', 'W3', 'Delta']
>>> observed = frame["Y"].dropna()
>>> bool(observed.between(0.0, 1.0, inclusive="neither").all())
True