cleverly.longitudinal.LongitudinalResult#
- class cleverly.longitudinal.LongitudinalResult(estimates: dict[str, ~cleverly.inference.influence.ParameterEstimate], fits: dict[str, ~cleverly.longitudinal.sequential.RegimenFit], data: ~cleverly.longitudinal.data.LongitudinalData, config: ~cleverly.longitudinal.estimator.LongitudinalConfig, scaler: ~cleverly.utils.bounds.OutcomeScaler, mechanism: ~cleverly.longitudinal.sequential.Mechanism, folds: ~cleverly.learners.crossfit.Folds, provenance: ~cleverly.provenance.Provenance, simultaneous: ~cleverly.inference.multiplier.SimultaneousBands | None = None, parameter_index: dict[str, tuple[str, str | None, int]] | None = None, msm: ~cleverly.longitudinal.msm.RegimenMSM | None = None, msm_fits: tuple[~cleverly.longitudinal.msm.MSMRegimenFit, ...] = (), identified_effect: ~typing.Any = None, method: ~typing.Any = None, parameter_keys: dict[str, ~typing.Any] = <factory>, fitted_method: str = 'tmle', bootstrap: ~cleverly.inference.bootstrap.BootstrapResult | None = None, bootstrap_band: ~cleverly.inference.bootstrap.BootstrapBand | None = None, isotonic_moves: tuple[tuple[str, str | None, int, float, float], ...] = (), initial_hazards: ~cleverly.longitudinal.hazard.InitialHazards | None = None, *, simulation: ~cleverly.longitudinal.gformula.GFormulaReport | None = None, fold_mechanisms: tuple[~cleverly.longitudinal.sdr.FoldMechanism, ...] = (), replay_recipe: ~cleverly.longitudinal.estimator._LongitudinalReplayRecipe)[source]#
Store estimates and fitted artifacts for longitudinal regimens.
Behaves as a mapping from parameter name to
ParameterEstimate, soresult["ey_regimen[always]"]andfor name in resultboth work.- Parameters:
- estimates
dictofstrtoParameterEstimate Estimates keyed by stable parameter alias. Each declares the fit status, which
inference_statusreturns, or a parameter status such as"constant_node_plugin".- fits
dictofstrtoRegimenFit Sequential fits by regimen, cause, and horizon.
- data
LongitudinalData Validated time-ordered study data.
- config
LongitudinalConfig Normalized sequential-estimator configuration.
- scaler
OutcomeScaler Transformation between observed and targeting scales.
- mechanism
Mechanism Fitted treatment and observation mechanisms.
- folds
Folds Realized outer-fold assignment.
- provenance
Provenance Runtime, dependency, and data fingerprints.
- simultaneous
SimultaneousBandsorNone Joint confidence bands.
Noneon a fit whose status supplies no inference.- parameter_index
dictorNone Structured regimen, cause, and horizon index.
- msm
RegimenMSMorNone Evaluated working model. Its
functions_kindrecords whether the source design and projection weights passed their declaration checks.- msm_fits
tupleofMSMRegimenFit Projection fits by cause.
- identified_effect
IdentifiedEffectorNone Causal question and identifying assumptions.
- method
EstimationMethodorNone Typed public method configuration.
- parameter_keys
dictofstrtoParameterKey Structured identities for reported aliases.
- fitted_method
str Method identity stamped by the estimator.
- bootstrap
BootstrapResultorNone The full-refit bootstrap draws, when
n_bootstrap > 0was requested.- bootstrap_band
BootstrapBandorNone The studentized bootstrap sup-t band over the estimates that supply inference.
Nonewithout a bootstrap, withsimultaneous=False, or with fewer than two such estimates.- isotonic_moves
tupleoftuple The levels an
isotonic=Trueprojection moved, as(regimen, cause, horizon, before, after).- initial_hazards
InitialHazardsorNone The initial cause-specific hazards of a
survival_model="hazard"fit.- fold_mechanisms
tupleofFoldMechanism Each outer fold’s own mechanism on a cross-fitted SDR fit, empty otherwise. Keyword-only.
- replay_recipe
object Unfitted recursive learner templates and resolved plans for deterministic refits. Keyword-only.
- simulation
GFormulaReportorNone On a
ParametricGFormulafit, what the forward simulation drew: the draws, the models, the Monte Carlo share of each parameter and the fixed-dose model reliance.Noneon every other fit. Keyword-only.
- estimates
- Attributes:
- assessment_cache
dict Saved diagnostic and sensitivity outputs. Not a constructor argument, so every constructed result owns its own cache. Persistence restores the mapping without the constructor.
inference_statusstrThe inference status of the fit.
- assessment_cache
See also
cleverly.estimators.TMLEResultThe same contract for a point-treatment fit.
cleverly.RegimeContrastThe estimand a study declares to get this contrast.
cleverly.LongitudinalTreatmentThe design that names these nodes.
LongitudinalResult.ratioThe risk ratio or odds ratio of two regimens.
LongitudinalResult.rmstThe restricted mean survival time of a regimen.
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}, ... n_folds=2, ... random_state=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"], ... )
The regimen means and their contrast are keyed by the labels the regimens were declared under:
>>> sorted(result.estimates) ['ate_regimen[never vs always]', 'ey_regimen[always]', 'ey_regimen[never]'] >>> low, high = result["ey_regimen[always]"].ci >>> low < high True
Methods#
- LongitudinalResult.assess(*, include_refits: bool = False, include_retargets: bool = False, arguments: Mapping[str, Mapping[str, Any]] | None = None, random_state: int | None = None) AssessmentReport[source]#
Run the applicable post-fit assessment battery.
- Parameters:
- Returns:
cleverly.AssessmentReportValidation, diagnostics, and sensitivity in one report.
See also
LongitudinalResult.validateRun stored-artifact validation.
cleverly.assessment.DiagnosticsFacade.run_allRun diagnostics alone.
- LongitudinalResult.coefficients(scale: str = 'link') Any[source]#
A working model’s coefficients, on the link scale or exponentiated.
The same view
cleverly.estimators.base.TMLEResult.coefficients()is at one time point, and it means the same things.scale="link"reports \(\hat\beta\) with a Wald interval on the scale the model is linear on;scale="ratio"reports \(e^{\hat\beta}\) with the interval exponentiated from that scale. What the exponential is depends on the link – a risk ratio under"log"and an odds ratio under"logit"– and the intercept is a third thing again, a baseline mean or a baseline odds rather than a ratio of anything, so thescalecolumn names which each row is. An intercept is found by its column being constant one, not by its name.Refused on an identity-link fit, where \(e^\beta\) of a risk difference is not a quantity, and on a fit with no working model. Nothing is re-estimated.
- Parameters:
- scale{“link”, “ratio”}
Coefficient scale to report.
- Returns:
dataframeOne row per working-model coefficient in the input backend.
- LongitudinalResult.contrast(function: Callable[[ndarray[tuple[Any, ...], dtype[float64]]], float], names: Sequence[str], *, name: str | None = None, scale: Literal['level', 'difference', 'ratio', 'fraction'] = 'difference', gradient: Callable[[ndarray[tuple[Any, ...], dtype[float64]]], ndarray[tuple[Any, ...], dtype[float64]]] | None = None, transform: Transform | None = None) ParameterEstimate[source]#
Return a smooth contrast with joint delta-method inference.
- Parameters:
- function
callable() Smooth scalar function of the selected estimates.
- namessequence
ofstr Aliases passed to
functionin order.- name
strorNone Alias for the derived estimate.
- scale
str Reported scale of the derived estimate. With
transform=it must be"level"or"difference".- gradient
callable()orNone Analytic gradient.
Noneuses central differences.- transform
TransformorNone The map the interval and the test are computed on, as for
cleverly.estimators.TMLEResult.contrast().
- function
- Returns:
ParameterEstimateDerived estimate. It inherits the inference status of the selected estimates, so on a fit that supplies no inference it reports the same diagnostic and no interval.
- LongitudinalResult.covariance(names: Sequence[str] | None = None) ndarray[tuple[Any, ...], dtype[float64]][source]#
Return joint covariance for selected estimates.
- LongitudinalResult.curve(scale: str | None = None) Any[source]#
The report as a curve: a row per parameter per horizon.
On a repeated outcome (
Repeated) the only scale is"mean": the mean \(E[Y_t^d]\) of each regimen and the difference between regimens at each horizon. A repeated outcome can return to zero, so it has no survival complement. The rest of this description is about a survival fit.scale="risk"reports what the fit estimated, the cumulative risk \(F(t)\) and the risk difference between regimens at each horizon.scale="survival"reports \(S(t) = 1 - F(t)\) instead. Theviewcolumn names the requested view; thescalecolumn keeps the vocabularyto_frame()reports,"level"or"difference", which is what separates a level row from a contrast row without reading any name.A fit that declared two or more causes refuses the survival view, because event-free survival is the complement of the sum of the cause-specific incidences and not the complement of one of them. With a single declared cause that sum is that one incidence, so the complement is event-free survival and the view is reported.
The map from one to the other is not one rule. For a level, \(S = 1 - F\): the estimate is mirrored about a half and so is its interval. For a contrast it is \(S_a - S_b = -(F_a - F_b)\): the estimate is negated and the interval negated and swapped. Applying
1 - xto a risk difference would report1 - RD, which is not a quantity, with an interval that would look perfectly reasonable – so this branches onscalerather than on the caller getting it right. The standard error is the same either way, both maps being linear with slope of modulus one.The
timecolumn lives here rather than onto_frame(), which keeps the column names a point-treatment fit reports.On
scale="survival"a level row’sestimandis not a key of this result: the complement ofrisk_regimen[always @ t=2]is reported assurvival_regimen[always @ t=2], which the fit never estimated under that name. A contrast row keeps itsate_regimen[...]name, which is a key, the difference being the same parameter up to a sign. Theparametercolumn carries the key either way, soresult[row.parameter]is defined for every row of every view andresult[row.estimand]is not.- Parameters:
- scale{“risk”, “survival”, “mean”}
orNone Outcome scale for levels and contrasts.
Nonereads"risk"on a survival fit and"mean"on a repeated outcome.
- scale{“risk”, “survival”, “mean”}
- Returns:
dataframeOne row per regimen, cause, and horizon in the input backend, with these columns.
estimandThe name of the quantity the row reports, under the requested view.
parameterThe key of the estimate the row was derived from, always in
result.estimates.regimenThe regimen of a level, or the
"a vs b"contrast string of a difference.causeThe absorbing cause, on a fit that declared its causes only.
timeThe horizon, as an integer node index, or as the grid time \(g_k\) on a fit with a time grid.
support"supported"or"experimental", the label of the estimate the row reads.supportgives its reason.inferenceThe inference status of each row, on a fit with a labelled status, shown or withheld, or with a parameter that carries one.
psi,std_err,ci_lower,ci_upperThe estimate, its standard error, and its confidence interval, under the requested view. On a fit whose status supplies no inference the three spread columns are
plugin_std_err,plugin_interval_lowerandplugin_interval_upper, a diagnostic, asto_frame()names them. On a fit that supplies inference, a row with a parameter status has NaN in the three inferential columns and its diagnostic in the three plug-in columns, which the frame then adds.scale"level"or"difference", asto_frame()reports it.view"risk","survival"or"mean", the view the caller requested.
- LongitudinalResult.incidence_total() Any[source]#
Per regimen and horizon, the incidences summed over the causes.
A unit leaves the risk set through exactly one cause or not at all, so the cumulative incidences and the event-free probability exhaust the mass: \(\sum_j F_j(k) + S(k) = 1\). That identity holds of the parameters. It does not hold of these estimates, and the difference is not a bug to fix. Each cause is a separate backward pass – its own regressions, its own fluctuation – so nothing constrains the sum, and a total above one is possible.
It is reported rather than removed, on the same reasoning as
simplex_deviation, where a multi-arm mechanism’s row is deliberately not rescaled back onto the simplex. Renormalising would buy a coherent-looking table by moving every cause’s estimate away from the one its own score equation solved, and would hide the thing worth seeing: a total far from one says the causes disagree about how much risk there was, which is a statement about the nuisance fits and not about the parameter.The
totalcolumn carries a standard error because the sum is itself a parameter with an influence curve – the sum of the causes’ curves – soexcesscan be read against it rather than eyeballed. On a fit whose status supplies no inference the column isplugin_std_err, a diagnostic, asto_frame()names the same spread. Each total takes the status of the incidences it sums. On a fit that supplies inference, a total that reads a constant-node incidence has NaN understd_err, its spread underplugin_std_err, and its status in aninferencecolumn.- Returns:
dataframeOne row per regimen and horizon, with the incidences summed over causes. The
supportcolumn holds the label of the combined incidences, and a fit with a labelled status adds theinferencecolumn.
- LongitudinalResult.psi(name: str | None = None) float[source]#
Return a point estimate by parameter alias.
- LongitudinalResult.ratio(numerator: str, denominator: str, *, kind: Literal['rr', 'or'] = 'rr', view: Literal['risk', 'survival'] = 'risk', name: str | None = None) ParameterEstimate[source]#
The risk ratio or odds ratio of two regimen levels, with log-scale inference.
The ratio of two
ey_regimenmeans, of tworisk_regimenrisks at one horizon, or of twocif_regimenincidences at one cause and horizon. The interval is computed on the log scale and exponentiated, aslmtp_contrast(type = "rr")andtype = "or"in Rlmtp1.5.4 compute it.view="survival"takes the ratio of \(1 - F\) instead of \(F\). The ratio inherits the inference status of its inputs.- Parameters:
- numerator
str The name of the level in the numerator.
- denominator
str The name of the level in the denominator.
- kind{“rr”, “or”}, default=”rr”
A ratio of the levels, or a ratio of their odds. On an end-of-study fit
"or"needs a binary outcome.- view{“risk”, “survival”}, default=”risk”
Whether to take the ratio of the risks or of the survival probabilities.
- name
strorNone, default=None The name of the derived estimate.
Nonecomposesrr_regimen[a vs b @ t=h]from the parameter index when both inputs are levels at one cause and horizon, andrr[<numerator> vs <denominator>]otherwise.
- numerator
- Returns:
ParameterEstimateThe ratio, on the
"ratio"scale.
- Raises:
CapabilityErrorWhen
kind="or"and an end-of-study outcome is not binary.ValueErrorWhen an input is not a level, when
view="survival"is requested of an end-of-study fit or of a fit with two or more causes, or when this fit reports the coefficients of a working model.
See also
cleverly.inference.ParameterEstimate.wald_testTest the ratio at a null.
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}, ... n_folds=1, ... 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"], ... ) >>> rr = result.ratio("ey_regimen[always]", "ey_regimen[never]") >>> rr.name, rr.scale ('rr_regimen[always vs never]', 'ratio')
- LongitudinalResult.rmst(regimen: str, horizon: int, *, versus: str | None = None, name: str | None = None) ParameterEstimate[source]#
The restricted mean survival time of a regimen up to a horizon.
With \(T\) the node of the first event and \(F(t)\) the reported risk,
\[\mathrm{RMST}(\tau) = E[\min(T, \tau)] = \tau - \sum_{t=1}^{\tau - 1} F(t),\]with the curve \(-\sum_{t=1}^{\tau-1} IC_{F(t)}\). The unit is the node index. For nodes spaced \(\Delta\) apart, the RMST in calendar time is \(\Delta \times \mathrm{RMST}\). On a competing-risk fit, \(F\) is the sum of the cause-specific incidences. The estimate inherits the inference status of the risks it sums.
- Parameters:
- regimen
str The regimen label.
- horizon
int The restriction time \(\tau\), an integer from 2 to
n_times + 1.- versus
strorNone, default=None A second regimen. The result is then the difference of the two RMSTs.
- name
strorNone, default=None The name of the derived estimate.
Nonegivesrmst_regimen[a @ t=tau]orrmst_regimen[a vs b @ t=tau].
- regimen
- Returns:
ParameterEstimateA
"level"estimate, or a"difference"estimate withversus=.
- Raises:
ValueErrorWhen the fit reports no survival curve, when the horizon is outside the range, or when the fit omits a horizon below it.
Examples
>>> from sklearn.linear_model import LinearRegression, LogisticRegression >>> from cleverly.datasets import make_longitudinal_survival >>> from cleverly.longitudinal import LTMLE >>> frame, _ = make_longitudinal_survival(n=300, seed=0) >>> result = LTMLE( ... {"always": 1, "never": 0}, ... n_folds=1, ... outcome_learner=LinearRegression(), ... treatment_learner=LogisticRegression(max_iter=1000), ... censoring_learner=LogisticRegression(max_iter=1000), ... ).fit( ... frame, ... outcome=["Y1", "Y2"], ... treatment=["A1", "A2"], ... baseline=["W1", "W2"], ... time_varying=[[], ["L2"]], ... censoring=["C1", "C2"], ... ) >>> rmst = result.rmst("always", 3, versus="never") >>> rmst.name, rmst.scale ('rmst_regimen[always vs never @ t=3]', 'difference')
- LongitudinalResult.rmtl(regimen: str, horizon: int, cause: str | None = None, *, versus: str | None = None, name: str | None = None) ParameterEstimate[source]#
The restricted mean time lost to one cause, up to a horizon.
With \(J\) the cause of the first event and \(F_j(t)\) its reported cumulative incidence,
\[\mathrm{RMTL}_j(\tau) = E[(\tau - \min(T, \tau)) 1\{J = j\}] = \sum_{t=1}^{\tau - 1} F_j(t),\]with the curve \(\sum_{t=1}^{\tau-1} IC_{F_j(t)}\). On a one-event fit it is \(\tau - \mathrm{RMST}(\tau)\). The unit is the node index.
- Parameters:
- regimen
str The regimen label.
- horizon
int The restriction time \(\tau\), an integer from 2 to
n_times + 1.- cause
strorNone, default=None The cause. Required on a fit with two or more causes.
- versus
strorNone, default=None A second regimen. The result is then the difference of the two RMTLs.
- name
strorNone, default=None The name of the derived estimate.
Nonegivesrmtl_regimen[a, cause @ t=tau], orrmtl_regimen[a @ t=tau]on a one-event fit.
- regimen
- Returns:
ParameterEstimateA
"level"estimate, or a"difference"estimate withversus=.
- Raises:
ValueErrorWhen the fit reports no survival curve, when the horizon is outside the range, when the fit omits a horizon below it, or when the cause is missing or unknown.
Examples
>>> from sklearn.linear_model import LinearRegression, LogisticRegression >>> from cleverly.datasets import make_longitudinal_survival >>> from cleverly.longitudinal import LTMLE >>> frame, _ = make_longitudinal_survival(n=300, seed=0) >>> result = LTMLE( ... {"always": 1, "never": 0}, ... n_folds=1, ... outcome_learner=LinearRegression(), ... treatment_learner=LogisticRegression(max_iter=1000), ... censoring_learner=LogisticRegression(max_iter=1000), ... ).fit( ... frame, ... outcome=["Y1", "Y2"], ... treatment=["A1", "A2"], ... baseline=["W1", "W2"], ... time_varying=[[], ["L2"]], ... censoring=["C1", "C2"], ... ) >>> lost = result.rmtl("always", 3) >>> rmst = result.rmst("always", 3) >>> round(lost.psi + rmst.psi, 12) 3.0
- LongitudinalResult.save(path: Any) Any[source]#
Persist the complete fitted result to a trusted joblib artifact.
The artifact records
cleverly.__version__. A load by a different version warns withVersionMismatchWarningand does not migrate the result.- Parameters:
- pathpath-like
Destination file.
- Returns:
PathThe destination path, as given.
- LongitudinalResult.summary(*, protocol: Literal['full', 'fingerprint'] = 'full') str[source]#
A printable report: the estimates, then the settings, then the leverage.
- Parameters:
- protocol{“full”, “fingerprint”}
"full"prints every field of the study protocol record."fingerprint"prints only its schema and fingerprint, for a reader who has the record already.
- Returns:
strA printable report: the estimates, the settings, then the leverage.
- LongitudinalResult.to_frame() Any[source]#
One row per reported parameter, in the backend the data came from.
Built from
to_dict(), so the columns are the ones a point-treatment fit reports under the same names. Two result objects in one library disagreeing on the name of every column is a worse cost than the one this saved.- Returns:
dataframeOne row per reported parameter, in the backend the data arrived in. A fit with a time grid adds a
timecolumn, the grid time of each parameter’s horizon.
Attributes#
- LongitudinalResult.assessment_family: ClassVar[str] = 'longitudinal'#
Which family of assessment declarations applies to this result. See
assessment_family; the method identity isfitted_method.
- LongitudinalResult.bootstrap: BootstrapResult | None = None#
The full-refit bootstrap draws,
Noneunlessn_bootstrap > 0. A replayed fit never reruns the bootstrap.
- LongitudinalResult.bootstrap_band: BootstrapBand | None = None#
The studentized bootstrap sup-t band over the estimates that supply inference, when
n_bootstrap > 0andsimultaneous=Trueand two or more estimates supply it. Itssupportsays whether a registered row lists thebootstrap_bandkind.
- LongitudinalResult.converged#
Whether every node’s targeting step reached its tolerance.
- LongitudinalResult.diagnostics#
Unified support, nuisance, score, and refutation diagnostics.
- LongitudinalResult.estimate#
The sole estimate, refusing ambiguity on a multi-parameter result.
- LongitudinalResult.fold_mechanisms: tuple[FoldMechanism, ...] = ()#
Each outer fold’s own mechanism, fitted on its training rows, on a cross-fitted SDR fit. Empty otherwise. A truncation replay reuses them.
- LongitudinalResult.identified_effect: Any = None#
Causal-workflow metadata, present on every result created through CausalStudy.
- LongitudinalResult.inference_status#
The inference status of the fit.
LTMLE.fitstamps one fit status on every estimate, and a parameter status (PARAMETER_STATUSES) on the parameters it applies to. This property is the fit status, throughreported_status(), which leaves the parameter statuses out unless every estimate carries one. So it does not say whether one estimate supplies inference: read that estimate’ssupplies_inference."influence_curve"when the fit reports no estimate, because such a fit refuses nothing. A clustered fit with few clusters takes"few_cluster_plugin", as a point-treatment fit does.
- LongitudinalResult.influence_curves#
Return influence curves by parameter alias.
- LongitudinalResult.initial_hazards: InitialHazards | None = None#
The initial cause-specific hazards of a
survival_model="hazard"fit, which the nuisance report and a truncation replay read.Noneon an iterated-mean fit.
- LongitudinalResult.isotonic_moves: tuple[tuple[str, str | None, int, float, float], ...] = ()#
(regimen, cause, horizon, before, after)of every level the isotonic projection moved, empty when it moved none orisotonic=False.
- LongitudinalResult.msm: RegimenMSM | None = None#
The working model this fit projected onto,
Noneif it declared none.
- LongitudinalResult.msm_fits: tuple[MSMRegimenFit, ...] = ()#
One per cause, in the order the causes are reported.
- LongitudinalResult.n#
Return the number of observations.
- LongitudinalResult.parameter_index: dict[str, tuple[str, str | None, int]] | None = None#
name -> (regimen, cause, horizon)for every reported parameter, composed when the name was built. Empty on an end-of-study fit, which has neither index.Noneon a working-model fit, whose parameters are indexed by term.
- LongitudinalResult.replayability#
Which assessment operations survive from the stored sequential artifacts.
- LongitudinalResult.sensitivity#
Return the sensitivity-analysis facade.
- LongitudinalResult.simulation: GFormulaReport | None = None#
On a
ParametricGFormulafit, what the forward simulation drew: the draws, the models, the Monte Carlo share of each parameter and the fixed-dose model reliance.Noneon every other fit.
- LongitudinalResult.simultaneous: SimultaneousBands | None = None#
- LongitudinalResult.estimates: dict[str, ParameterEstimate]#
- LongitudinalResult.data: LongitudinalData#
- LongitudinalResult.config: LongitudinalConfig#
- LongitudinalResult.scaler: OutcomeScaler#
- LongitudinalResult.mechanism: Mechanism#
- LongitudinalResult.provenance: Provenance#
- LongitudinalResult.assessment_cache: dict[str, Any]#
Assessment results keyed by operation and normalized arguments. Persistence writes this alongside the sequential artifacts it was computed from.
init=Falsefor the reasoncleverly.estimators.TMLEResult .assessment_cachegives: the key names the operation and its arguments and not the result, so a mapping handed to the constructor bydataclasses.replacewould answer for a fit that never produced it.
- LongitudinalResult.replay_recipe: _LongitudinalReplayRecipe#
Unfitted state for a complete bound-dependent recursion.