cleverly.CollaborativeTMLEMethod#

class cleverly.CollaborativeTMLEMethod(models: ModelSpec = ModelSpec(outcome_learner=None, treatment_learner=None, missingness_learner=None, intermediate_learner=None, pseudo_learner=None, censoring_learner=None, density_bins=None, ratio='density', screen_treatment=False, screen_threshold=0.1, min_retain=None, outcome_by_arm=False, survival_model='iterated_mean'), cross_fitting: CrossFitting = CrossFitting(enabled=True, n_folds=10, learner_folds=5, repeats=1, stratify_by='none', targeting_scheme='pooled', fold_evaluation=False, split_plan=None), targeting: Targeting = Targeting(fluctuation='logistic', algorithm='iterative', g_bounds='auto', q_bounds=None, nuisance_bound=0.01, submodel_alpha=0.9995, target_weights=False, step_size=0.001, max_iter=20, tol=1e-10, stopping='relative', step_bound=None, step_search=True, iterate='last', isotonic=False), inference: Inference = Inference(alpha=0.05, n_bootstrap=0, bootstrap_resampling='auto', simultaneous=True, n_multiplier='auto', multiplier_kind='rademacher'), runtime: Runtime = Runtime(random_state=None, run_id=None, n_jobs=1), name: str = 'collaborative_tmle', strategy: str = 'greedy', preorder: str | None = None, ordering: tuple[str, ...] | None = None, candidates: tuple[tuple[str, ...], ...] | None = None, selection_folds: int = 5, selection_inner_folds: int = 2, loss: str = 'auto', penalty: bool = True, selection_estimand: str = 'ate', oat_design: str | None = None, lambdas: tuple[float, ...] | None = None, treatment_candidates: tuple[Any, ...] | None = None, selection_split: tuple[int, ...] | None = None, patience: int | None = None)[source]#

Configure collaborative treatment-mechanism selection.

Parameters:
modelsModelSpec

Nuisance learners and related model settings.

cross_fittingCrossFitting

Sample-splitting settings.

targetingTargeting

Fluctuation and solver settings.

inferenceInference

Interval and resampling settings.

runtimeRuntime

Seed, run identifier, and parallelism.

namestr

Stable method name.

strategy{“greedy”, “ordered”, “discrete”, “lasso”, “learners”, “derivative”, “oat”}, default=”greedy”

Collaborative search strategy. "greedy", "ordered", "discrete", "lasso" and "learners" report no confidence interval, no p-value and no standard error, with two exceptions that the Notes state. F18 in the roadmap holds the reason. "oat" reports no interval, for the reason F19 holds, except on a per-arm fit with ParametricOutcome and ParametricMechanism that cleverly.estimators.ctmle.per_arm_parametric_support admits (X58), in sample or cross-fitted, with any number of arms and with observation weights. That fit reports pointwise intervals and a simultaneous band. "derivative" is C-TMLE0. It selects nothing and reports the ordinary TMLE interval.

preorder{“logistic”, “partial_correlation”} or None, default=None

Preordering rule for candidate covariates.

orderingtuple of str or None, default=None

Explicit covariate order.

candidatestuple of tuple of str or None, default=None

Explicit nested adjustment candidates.

selection_foldsint, default=5

Outer folds used to select a candidate.

selection_inner_foldsint, default=2

Inner folds used to evaluate learners during selection.

loss{“auto”, “loglik”, “squared”}, default=”auto”

Candidate-selection loss.

penaltybool, default=True

Whether to apply the collaborative complexity penalty.

selection_estimandstr, default=”ate”

Estimand used by the selector.

oat_design{“per_arm”, “shared”} or None, default=None

The treatment design of strategy="oat". None resolves to "per_arm". "shared" fits the one categorical mechanism of ctmle3 and reports no interval, for the reason F19 in the roadmap holds. "per_arm" reports an interval only on the fits that the strategy entry names.

lambdastuple of float or None, default=None

The penalty grid of strategy="lasso": two or more penalties, strictly decreasing, with 0 allowed only as the last value. None uses glmnet’s default grid with 0 appended. Under strategy="derivative", the pair (mechanism, partner) of two different penalties, or None to choose the mechanism penalty by cross-validation.

treatment_candidatestuple or None, default=None

The declared candidates of strategy="learners", from the least to the most adaptive: unfitted learners, or PropensityArrays pairs. treatment_learner on every covariate is appended as the last candidate. Under strategy="derivative", the pair (mechanism, partner) of two unfitted learners or two arrays of treatment probabilities.

selection_splittuple of int or None, default=None

Fold labels 0 to V - 1, one for each row, used in place of the random selection split. selection_folds must equal V.

patienceint or None, default=None

Stop the cross-validated scoring of the candidate path after this many candidates score worse than the best so far, as patience does in R ctmle. None reads the whole path. It applies to "greedy", "ordered", "discrete", "lasso" and "learners". The fit keeps its working_mechanism_plugin status.

See also

TMLEMethod

The base configuration, without covariate selection.

DRTMLEMethod

Extra score equations against one inconsistent nuisance, valid in the cases its contract lists.

cleverly.estimators.ctmle

Why selection is made against the targeted loss.

Notes

The default "greedy" strategy selects a working treatment mechanism, and so do "ordered", "discrete", "lasso" and "learners". No result shows that the reported curve is the estimator’s influence curve at that mechanism. Their estimates therefore raise CapabilityError from std_error, ci and pvalue. Each estimate keeps plugin_std_error and plugin_interval as a diagnostic, which is not a confidence statement. For an interval, use TMLEMethod. There are two exceptions. A "discrete" fit whose one declared candidate is the full adjustment set, and a "learners" fit with an empty treatment_candidates list, select nothing, equal the ordinary TMLE, and report the ordinary interval.

strategy="oat" selects nothing, and it keeps the diagnostic only on either design: condition (v) of Benkeser, Cai and van der Laan (2020), Theorem 1, fails for an estimated outcome regression.

strategy="derivative" adds a derivative column for each arm to one TMLE update. The columns contain the clever covariates, so the update solves the efficient influence curve equation, and the fit reports the ordinary TMLE interval.

Examples

>>> from cleverly import CollaborativeTMLEMethod
>>> method = CollaborativeTMLEMethod(strategy="greedy", selection_folds=3)
>>> method.name, method.selection_folds
('collaborative_tmle', 3)

Stop the scoring of the candidate path once two candidates score worse than the best so far:

>>> CollaborativeTMLEMethod(strategy="greedy", patience=2).patience
2

The collaborative fields are additions. Everything TMLEMethod configures is still configured the same way:

>>> from cleverly import CrossFitting
>>> CollaborativeTMLEMethod(cross_fitting=CrossFitting(n_folds=5)).cross_fitting.n_folds
5

Methods#

CollaborativeTMLEMethod.estimator_kwargs(*, longitudinal: bool = False) → dict[str, Any][source]#

Translate this configuration for the point-treatment CTMLE engine.

Parameters:
longitudinalbool

Must be false because no longitudinal collaborative score is supported.

Returns:
dict of str to Any

CTMLE engine keyword arguments.

Attributes#

CollaborativeTMLEMethod.candidates: tuple[tuple[str, ...], ...] | None = None#
CollaborativeTMLEMethod.lambdas: tuple[float, ...] | None = None#
CollaborativeTMLEMethod.loss: str = 'auto'#
CollaborativeTMLEMethod.name: str = 'collaborative_tmle'#
CollaborativeTMLEMethod.oat_design: str | None = None#
CollaborativeTMLEMethod.ordering: tuple[str, ...] | None = None#
CollaborativeTMLEMethod.patience: int | None = None#
CollaborativeTMLEMethod.penalty: bool = True#
CollaborativeTMLEMethod.preorder: str | None = None#
CollaborativeTMLEMethod.selection_estimand: str = 'ate'#
CollaborativeTMLEMethod.selection_folds: int = 5#
CollaborativeTMLEMethod.selection_inner_folds: int = 2#
CollaborativeTMLEMethod.selection_split: tuple[int, ...] | None = None#
CollaborativeTMLEMethod.strategy: str = 'greedy'#
CollaborativeTMLEMethod.treatment_candidates: tuple[Any, ...] | None = None#