cleverly.ParameterEstimate#

class cleverly.ParameterEstimate(name: str, psi: float, influence_curve: ndarray[tuple[Any, ...], dtype[float64]], variance: float, n: int, n_clusters: int, scale: Literal['level', 'difference', 'ratio', 'fraction'] = 'difference', alpha: float = 0.05, log_psi: float | None = None, bootstrap: BootstrapSummary | None = None, covariance_rule: Literal['centered', 'second_moment'] = 'centered', inference: Literal['influence_curve', 'working_mechanism_plugin', 'generated_design_plugin', 'estimated_weight_plugin', 'adaptive_baseline_plugin', 'no_cluster_variance_plugin', 'few_cluster_plugin', 'constant_node_plugin', 'stack_failure_plugin'] = 'influence_curve', transform: Transform | None = None, reference_df: int | None = None, support: Support = Support(label='experimental', reason='This estimate was built outside a classified fit.', evidence=(), row=None, limits=()))[source]#

A point estimate with everything needed to do inference on it.

Parameters:
namestr

Stable alias of the estimand.

psifloat

The estimate, on the outcome’s original scale.

influence_curvendarray

Per-observation influence curve on the inference scale – the original outcome scale for levels and differences, the log scale for ratios.

variancefloat

Variance on the inference scale.

nint

Number of observations behind the estimate.

n_clustersint

Independent clusters behind it, which is what the variance divides by.

scale{“level”, “difference”, “ratio”, “fraction”}

Scale the estimate is reported on, which decides how the interval is built.

alphafloat

Significance level of ci.

log_psifloat or None

Present for ratios only: the estimate on the log scale.

bootstrapBootstrapSummary or None

Bootstrap summary, when n_bootstrap > 0 was requested.

covariance_rule{“centered”, “second_moment”}

How joint covariance and delta-method contrasts are computed from the influence curve. "centered" uses the sample covariance at the observation or cluster unit, which can differ from variance on a fold-evaluated or repeated fit. "second_moment" uses the raw second moment that the stacked cross-fitted natural-course mean reports as its variance.

inferencestr

Whether the package supplies inference for this estimate. One of InferenceStatus. The inference reference lists each status and its reason. "influence_curve" is the ordinary case, and std_error, ci and pvalue answer. A status whose record shows its interval answers the same three accessors, and the estimate carries the experimental label. At any other status those three accessors raise with the status’s reason, and plugin_std_error and plugin_interval report the retained diagnostic.

transformTransform or None

A monotone map that the interval and the test are computed on, set by contrast(..., transform=). None for every estimate a fit reports.

reference_dfint or None

Degrees of freedom of the Student t reference of ci, pvalue and plugin_interval, or None for the normal reference. A clustered fit with fewer than 40 clusters with positive weight mass sets it to the cluster count minus 2, per estimate.

supportSupport

What the package states about the evidence behind this estimate: the label "supported" or "experimental", the reason, the evidence and the support row. A fit sets it from its classification. An estimate built outside a classified fit is experimental. repr and summary() print the word experimental for an experimental estimate.

Attributes:
std_errorfloat

Standard error on the inference scale.

plugin_std_errorfloat

Plug-in standard error of the reported curve, at every inference status.

inference_valuefloat

Return the estimate on the scale used by its influence curve.

cituple of float

Confidence interval at level 1 - alpha.

plugin_intervaltuple of float

Wald interval of the plug-in curve, at level 1 - alpha.

pvaluefloat

Two-sided p-value against the null of no effect.

supplies_inferencebool

Whether the package supplies inference for this estimate.

See also

cleverly.estimators.TMLEResult

The mapping these are read out of.

cleverly.inference.influence_variance

The variance an estimate is given.

cleverly.inference.simultaneous_bands

Joint bands over several of these.

cleverly.inference.WaldTest

What wald_test() returns at a declared null.

Examples

Read an estimate from a fitted result:

>>> 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,
... )
>>> estimate = result["ate"]
>>> estimate.name, estimate.n
('ate', 80)
>>> estimate.ci[0] < estimate.ci[1]
True

Test the estimate against a declared null value:

>>> test = estimate.wald_test(null=1.0)
>>> test.null, test.pvalue < 1.0
(1.0, True)

Methods#

ParameterEstimate.spread_columns(*, pvalue: bool = True) → dict[str, float][source]#

The standard error, interval and p-value, each under its status-appropriate name.

An estimate the package supplies inference for returns std_err, ci_lower, ci_upper and p_value. A diagnostic estimate returns the same standard error and interval under the names spread_name() gives them, and no p-value. The numbers are the bodies plugin_std_error and plugin_interval read, so they are identical under either status.

Parameters:
pvaluebool, default=True

Whether to include p_value for an estimate that supplies inference. A frame with no p-value column passes False.

Returns:
dict of str to float

The columns, in the order to_dict publishes them.

ParameterEstimate.to_dict() → dict[str, Any][source]#

Return a JSON-compatible representation.

support is always present, and is "supported" or "experimental". An experimental estimate adds support_reason and support_evidence, the evidence joined by ;, and an estimate whose support states limits adds support_limits. inference is present for every status except "influence_curve", and names it. An estimate the package supplies inference for, either at "influence_curve" or at a status that shows its interval, emits std_err, ci_lower, ci_upper and p_value. One whose supplies_inference is False emits plugin_std_err, plugin_interval_lower and plugin_interval_upper in their place, and no p_value. Its bootstrap columns are bootstrap_sd, bootstrap_range_lower and bootstrap_range_upper rather than bootstrap_std_err, bootstrap_ci_lower and bootstrap_ci_upper. The bootstrap columns take the same diagnostic names when bootstrap_is_diagnostic() is True. A fit with a bootstrap adds bootstrap_support, the label of the bootstrap summary. A transformed estimate adds transform and transform_psi, the estimate on the transform’s scale. An estimate with a Student t reference adds reference_df, and its bootstrap columns take the diagnostic names. std_err is present exactly when supplies_inference is True, so a programmatic consumer has a total test.

Returns:
dict

A JSON-compatible mapping of every reported field.

ParameterEstimate.wald_test(null: float | None = None) → WaldTest[source]#

Test the estimate against a declared null value.

The statistic is computed on the inference scale. A ratio’s null is mapped to the log scale, and a transformed estimate’s null is mapped through its transform.

Parameters:
nullfloat or None, default=None

The null value on the reported scale. None takes the scale’s default: zero for a level, difference or fraction, and one for a ratio.

Returns:
WaldTest

The statistic and its two-sided p-value. At null=None its p-value is pvalue.

Raises:
CapabilityError

When supplies_inference is False. The fit reports no test.

ValueError

When a ratio-scale null is not positive, or a transformed estimate’s null has no value under its transform.

Examples

>>> import numpy as np
>>> from cleverly.inference import make_estimate
>>> estimate = make_estimate("ey1", 0.4, np.array([0.1, -0.1, 0.2, -0.2]), n=4)
>>> test = estimate.wald_test(null=0.4)
>>> test.statistic, test.pvalue
(0.0, 1.0)
ParameterEstimate.with_bootstrap(summary: BootstrapSummary) → ParameterEstimate[source]#

Return a copy with bootstrap inference attached.

Parameters:
summaryBootstrapSummary

Percentile interval and bootstrap standard error to attach.

Returns:
ParameterEstimate

A copy carrying that summary. The analytic interval is unchanged.

Attributes#

ParameterEstimate.alpha: float = 0.05#
ParameterEstimate.bootstrap: BootstrapSummary | None = None#
ParameterEstimate.ci#

Confidence interval at level 1 - alpha.

Raises:
CapabilityError

When supplies_inference is False. Read plugin_interval for the retained diagnostic.

ParameterEstimate.covariance_rule: Literal['centered', 'second_moment'] = 'centered'#
ParameterEstimate.inference: Literal['influence_curve', 'working_mechanism_plugin', 'generated_design_plugin', 'estimated_weight_plugin', 'adaptive_baseline_plugin', 'no_cluster_variance_plugin', 'few_cluster_plugin', 'constant_node_plugin', 'stack_failure_plugin'] = 'influence_curve'#
ParameterEstimate.inference_value#

Return the estimate on the scale used by its influence curve.

ParameterEstimate.log_psi: float | None = None#
ParameterEstimate.plugin_interval#

Wald interval of the plug-in curve, at level 1 - alpha.

A diagnostic and not a confidence interval. It is the interval ci builds, read through a name that makes no coverage claim, so a fit whose inference the package refuses can still report the spread of the curve it computed. At a non-inferential status the coverage of this interval is unestablished, for the reason the inference reference gives. The registered selector studies measure it and report it as a diagnostic.

ParameterEstimate.plugin_std_error#

Plug-in standard error of the reported curve, at every inference status.

A diagnostic and not a standard error for an estimate whose supplies_inference is False. On an ordinary estimate it is std_error under a name that makes no coverage claim.

ParameterEstimate.pvalue#

Two-sided p-value against the null of no effect.

The null is zero for a level, difference or fraction and one for a ratio (i.e. zero on the log scale). A transformed estimate maps that null through its transform. The value is wald_test().pvalue, from the same body.

Raises:
CapabilityError

When supplies_inference is False. This fit reports no p-value.

ParameterEstimate.reference_df: int | None = None#
ParameterEstimate.scale: Literal['level', 'difference', 'ratio', 'fraction'] = 'difference'#
ParameterEstimate.score#

Mean of the influence curve.

Targeting is supposed to drive this to zero; cleverly.validation.score compares it against the standard error to decide whether it did.

ParameterEstimate.std_error#

Standard error on the inference scale.

Raises:
CapabilityError

When supplies_inference is False. Read plugin_std_error for the retained diagnostic.

ParameterEstimate.supplies_inference#

Whether the package supplies inference for this estimate.

True when inference is "influence_curve" or a status that shows its interval, which is when std_error, ci and pvalue answer.

ParameterEstimate.support: Support = Support(label='experimental', reason='This estimate was built outside a classified fit.', evidence=(), row=None, limits=())#
ParameterEstimate.transform: Transform | None = None#
ParameterEstimate.name: str#
ParameterEstimate.psi: float#
ParameterEstimate.influence_curve: ndarray[tuple[Any, ...], dtype[float64]]#
ParameterEstimate.variance: float#
ParameterEstimate.n: int#
ParameterEstimate.n_clusters: int#