cleverly.assessment.DiagnosticsFacade#

class cleverly.assessment.DiagnosticsFacade(result: Any)[source]#

Access diagnostics supported by a fitted causal result.

Parameters:
resultTMLEResult or LongitudinalResult

Fitted point-treatment or longitudinal result.

See also

SensitivityFacade

The analyses that ask what would overturn the estimate.

cleverly.AssessmentCapability

One row of capabilities.

cleverly.DiagnosticReport

What run_all() returns.

Notes

Access this facade through result.diagnostics. Inspect capabilities before optional or potentially expensive operations.

Examples

>>> from sklearn.linear_model import LinearRegression, LogisticRegression
>>> from cleverly import ATE, CausalStudy, PointTreatment
>>> from cleverly.datasets import make_linear_ate
>>> frame, _ = make_linear_ate(n=200, seed=0)
>>> study = CausalStudy(
...     frame,
...     design=PointTreatment(
...         outcome="Y", treatment="A", adjustment=("W1", "W2", "W3", "W4")
...     ),
... )
>>> result = study.identify(ATE()).estimate(
...     outcome_learner=LinearRegression(),
...     treatment_learner=LogisticRegression(max_iter=1000),
...     cross_fit=False,
...     random_state=0,
... )
>>> support = result.diagnostics.support()
>>> support.n
200

Methods#

DiagnosticsFacade.corrections(*, tolerance: float = 0.001, identity_tolerance: float = 1e-12) → Any[source]#

Return correction-equation checks for a DRTMLE fit.

Parameters:
tolerancefloat

Tolerance for the reduced correction score.

identity_tolerancefloat

Tolerance for the correction identity.

Returns:
CorrectionCheck

Correction diagnostics for the fitted result.

Raises:
CapabilityError

If the fitted method does not use the correction system.

DiagnosticsFacade.influence() → Any[source]#

How few rows carry each estimate’s influence curve.

A direct call only. The operation is not part of run_all() or the assessment battery, so adding it moves no combined report. The fit already warns with SparseInfluenceWarning when a Wald fit needs it. With clusters every measure reads the cluster sums of the curve.

Returns:
InfluenceReport

One row per estimate (cleverly.inference.sparse): the Kish count, the skewness, the raw kurtosis, the relative SD of the variance estimate, the Edgeworth-predicted Wald coverage loss, and, with an attached bootstrap, the BCa bias correction and acceleration.

Examples

>>> from sklearn.linear_model import LinearRegression, LogisticRegression
>>> from cleverly.datasets import make_longitudinal
>>> from cleverly.longitudinal import LTMLE
>>> frame, _ = make_longitudinal(n=200, seed=0)
>>> result = LTMLE(
...     {"always": 1, "never": 0},
...     outcome_learner=LinearRegression(),
...     treatment_learner=LogisticRegression(max_iter=1000),
...     censoring_learner=LogisticRegression(max_iter=1000),
... ).fit(
...     frame,
...     outcome="Y",
...     treatment=["A1", "A2"],
...     baseline=["W1", "W2"],
...     time_varying=[[], ["L2"]],
...     censoring=["C1", "C2"],
... )
>>> report = result.diagnostics.influence()
>>> report.sparse
('ey_regimen[always]', 'ey_regimen[never]', 'ate_regimen[never vs always]')
DiagnosticsFacade.nuisance_models() → Any[source]#

Return method-aware held-out nuisance and split diagnostics.

Returns:
NuisanceDiagnostics or LongitudinalNuisanceDiagnostics

Held-out diagnostics for point or sequential nuisance models. Point-treatment reports also retain C-TMLE selection state and pair repeated-split spread with each reported standard error when those artifacts exist.

DiagnosticsFacade.refute(**kwargs: Any) → Any[source]#

Refit the analysis under the requested data perturbations.

Parameters:
**kwargs

Options forwarded to cleverly.validation.refute().

Returns:
RefutationResult

Refutation results for each requested perturbation.

Raises:
TypeError

If an argument is not one cleverly.validation.refute() takes.

ValueError

If a test name is unknown, n_replicates is invalid, or the requested negative-control test has no outcome. These checks precede every refusal.

CapabilityError

If the fitted estimator cannot be reconstructed, or the row this request resolves to is refused. A fit given split_plan= refuses subset, and the natural-course mean refuses placebo, so each row defers on tests. A call that omits tests raises the deferral with the refused test’s sentence, and a call that names tests without that test runs.

DiagnosticsFacade.run_all(*, include_refits: bool = False, include_retargets: bool = False, arguments: Mapping[str, Mapping[str, Any]] | None = None, random_state: int | None = None) → DiagnosticReport[source]#

Run available diagnostics that need no new arguments.

Parameters:
include_refitsbool

Include operations that refit nuisance models.

include_retargetsbool

Include moderate retargets; cheap E-value retargets run by default.

argumentsmapping or None

Per-operation keyword arguments.

random_stateint or None

Common seed for stochastic refit operations.

Returns:
DiagnosticReport

One item for every diagnostic operation included in the combined report.

See also

cleverly.DiagnosticReport

The combined operation statuses.

DiagnosticsFacade.capabilities

Declare availability and cost before execution.

Examples

>>> from sklearn.linear_model import LinearRegression, LogisticRegression
>>> from cleverly import ATE, CausalStudy, PointTreatment
>>> from cleverly.datasets import make_linear_ate
>>> frame, _ = make_linear_ate(n=80, seed=1)
>>> study = CausalStudy(
...     frame,
...     design=PointTreatment(
...         outcome="Y", treatment="A", adjustment=("W1", "W2", "W3", "W4")
...     ),
... )
>>> result = study.identify(ATE()).estimate(
...     outcome_learner=LinearRegression(),
...     treatment_learner=LogisticRegression(max_iter=1000),
...     cross_fit=False,
...     random_state=0,
... )
>>> report = result.diagnostics.run_all()
>>> report.include_refits, report.include_retargets
(False, False)
DiagnosticsFacade.score_equations(*, tolerance: float = 0.001) → Any[source]#

Whether targeting solved the score equations this fit relies on.

Parameters:
tolerancefloat

Relative tolerance used to evaluate the fitted score equations.

Returns:
ScoreCheck or LongitudinalScoreDiagnostics

Score-equation checks for the fitted result family.

Notes

tolerance gates both families but on the scale each one’s score lives on, and the two are not interchangeable. A point-treatment fit compares the score in the outcome’s own units against tolerance * se / sqrt(n) (DEFAULT_TOLERANCE says why that shape). A longitudinal fit bounds each node’s relative score – the largest component as a fraction of its maximum possible magnitude – which is the quantity the sequential targeting loop gates on, and it can only tighten a node’s verdict beyond the fit’s own convergence flag.

A cross-fitted longitudinal fit gets one row per node, as a single-fold fit does, or one per node and term on a working model. Its one pooled fluctuation per node solves the node’s score over every follower, so the "solver" row gates that score with tolerance.

DiagnosticsFacade.support() → Any[source]#

Return the support diagnostic for the fitted intervention.

Returns:
PositivityReport or LongitudinalDiagnostics or SupportReport or dict

Support diagnostic specialized for arms, regimens, shifts, or incremental interventions.

DiagnosticsFacade.truncation_curve(bounds: Sequence[float] | Sequence[float | tuple[float, float]] | None = None, *, estimands: Sequence[str] | None = None, mechanism: bool | None = None) → Any[source]#

Evaluate fitted estimates across a sequence of mechanism bounds.

Point-treatment and longitudinal results intentionally have different contracts. A point-treatment curve retargets the stored nuisance fits. A longitudinal curve repeats the complete backward recursion while reusing the fitted treatment/censoring mechanism, folds, prepared data, scaler, and frozen resolved regimen plans.

A longitudinal fit refuses mechanism=True. It has one cumulative treatment-and-censoring bound, so there is no separate observation mechanism for a second axis to vary. It also requires an explicit bounds grid, because it has no per-parameter fitted pair to build a default grid around.

Parameters:
boundssequence of float or cumulative bound pairs, or None

For a point-treatment result, lower bounds to evaluate; treatment-mechanism scalars use symmetric (bound, 1 - bound) bounds, while observation- and intermediate-mechanism scalars use (bound, 1). Point-treatment defaults, including each requested parameter’s exact fitted pair, are used when omitted. A longitudinal result requires an explicit, non-empty sequence. Each longitudinal scalar b is cumulative (b, 1) shorthand and each (lower, upper) pair is preserved exactly.

estimandssequence of str or None

Reported estimands to include. All compatible estimands are the default.

mechanismbool or None

Vary the observation mechanism rather than treatment. None resolves to the only axis the fit has: the observation mechanism for a missing-outcome NaturalCourseMean fit, which estimates no treatment law, and treatment for every other fit. Passing False explicitly on a natural-course fit names an axis that fit does not have, and is refused rather than redirected. An incremental fit refuses the treatment axis, because its estimand contains the propensity. Its row defers on mechanism when the fit also estimated an observation mechanism, and reads unavailable when it did not.

Returns:
dataframe

Point-treatment output contains retargeted estimates and uncertainty at each requested bound. Longitudinal output is descriptive only: replayed point estimates, the exact fitted reference and movement from it, and score-cell truncation counts; it contains no standard errors or confidence intervals.

Raises:
CapabilityError

If the requested curve changes the estimand, names an axis the fit does not have, or cannot be replayed. The sentence is the one cleverly.sensitivity.positivity.truncation_refusal returns. A longitudinal result also refuses an omitted bounds grid and mechanism=True, which are the two requests its contract above has no answer to. On a declared known mechanism, either family refuses an explicit bound pair that the fit itself refuses, because that pair would truncate a declared value. The point-treatment default grid omits such a pair.

Attributes#