cleverly.IdentifiedEffect#

class cleverly.IdentifiedEffect(estimand: ATE | ATT | ATC | CounterfactualMean | NaturalCourseMean | PopulationAttributableRisk | PopulationAttributableFraction | RiskRatio | OddsRatio | RegimeMean | RegimeContrast | LearnedRuleValue | ModifiedTreatmentPolicy | ModifiedTreatmentPolicyEffect | IncrementalMean | IncrementalEffect | MSMProjection | ControlledDirectEffect, functional: BackdoorMeanContrast, identification: Identification, provider: IdentificationProvider, protocol: StudyProtocol | None = None, _study: CausalStudy | None = None)[source]#

Bind an estimand to a functional and its identification assumptions.

Parameters:
estimandEstimand

Typed causal quantity.

functionalBackdoorMeanContrast

Normalized observed-data target.

identificationIdentification

Assumptions, nuisance requirements, and remainder condition.

providerIdentificationProvider

Provider that performed identification.

protocolStudyProtocol or None

Scientific study protocol stamped by CausalStudy.

See also

CausalStudy.identify

What returns this object.

MethodAvailability

One row of available_methods().

cleverly.EstimationMethod

The configuration estimate() accepts.

Notes

_study is the bound study, kept private because it is not part of the reported causal question. An effect built without a study leaves it None, and such an effect cannot be refitted.

Examples

CausalStudy.identify() returns this object. It carries the assumptions the estimate will rest on, and it is what an estimation method is passed to.

>>> from cleverly import ATE, CausalStudy, PointTreatment
>>> from cleverly.datasets import make_linear_ate
>>> frame, _ = make_linear_ate(n=40, seed=1)
>>> study = CausalStudy(
...     frame,
...     design=PointTreatment(
...         outcome="Y", treatment="A", adjustment=("W1", "W2", "W3", "W4")
...     ),
... )
>>> effect = study.identify(ATE())
>>> effect.estimand.name
'ate'
>>> sorted(method.name for method in effect.available_methods())[:2]
['collaborative_tmle', 'drtmle']

Methods#

IdentifiedEffect.available_methods() → tuple[MethodAvailability, ...][source]#

Report estimation methods available for this functional.

Returns:
tuple of MethodAvailability

One capability record for each named method, including refusal reasons.

Notes

The result includes unavailable methods and their refusal reasons. Selecting one raises CapabilityError before nuisance fitting starts.

available is per method name. A configuration of an available method can still refuse before any learner. For LearnedRuleValue, the default TMLEMethod() refuses (X11 (e) in docs/roadmap.md), and TMLEMethod(cross_fitting=CrossFitting(fold_evaluation=True)) fits.

IdentifiedEffect.estimate(method: str | EstimationMethod = 'tmle', **overrides: Any) → TMLEResult | LongitudinalResult[source]#

Estimate the identified functional.

Parameters:
methodstr or EstimationMethod

Named method or configured method object.

**overridesAny

Method fields overridden for this fit.

Returns:
TMLEResult or LongitudinalResult

Fitted result matching the study design.

Raises:
CapabilityError

If the method is unavailable or the effect has no bound study.

MethodConfigurationError

If method does not satisfy the estimation-method contract.

See also

IdentifiedEffect.available_methods

Report supported methods before fitting.

TMLEMethod

Configure the default estimation method.

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")
...     ),
... )
>>> effect = study.identify(ATE())
>>> result = effect.estimate(
...     outcome_learner=LinearRegression(),
...     treatment_learner=LogisticRegression(max_iter=1000),
...     cross_fit=False,
...     random_state=0,
... )
>>> sorted(result.estimates)
['ate']
IdentifiedEffect.summary(*, protocol: Literal['full', 'fingerprint'] = 'full') → str[source]#

Return a readable identification summary.

Parameters:
protocol{“full”, “fingerprint”}

"full" prints every field of the protocol record. "fingerprint" prints only its schema and fingerprint, for a reader who has the record already.

Returns:
str

A printable block naming the estimand, the functional, and the assumptions.

IdentifiedEffect.summary_lines(*, protocol: Literal['full', 'fingerprint'] = 'full') → tuple[str, ...][source]#

Return identification facts for inclusion in result summaries.

Parameters:
protocol{“full”, “fingerprint”}

"full" gives every field of the protocol record. "fingerprint" gives only its schema and fingerprint.

Returns:
tuple of str

The same facts as lines, for a result summary to append.

Attributes#

IdentifiedEffect.protocol: StudyProtocol | None = None#
IdentifiedEffect.estimand: ATE | ATT | ATC | CounterfactualMean | NaturalCourseMean | PopulationAttributableRisk | PopulationAttributableFraction | RiskRatio | OddsRatio | RegimeMean | RegimeContrast | LearnedRuleValue | ModifiedTreatmentPolicy | ModifiedTreatmentPolicyEffect | IncrementalMean | IncrementalEffect | MSMProjection | ControlledDirectEffect#
IdentifiedEffect.functional: BackdoorMeanContrast#
IdentifiedEffect.identification: Identification#
IdentifiedEffect.provider: IdentificationProvider#