cleverly 0.1.3#
This alpha release adds sequentially doubly robust estimation, longitudinal incremental interventions, and long-panel input. It extends outcome-adaptive C-TMLE point estimates and narrows several inference claims. These are the changes since 0.1.2.
Upgrade notes#
Review these changes before refitting an analysis under 0.1.3.
Set oat_design="shared" to retain the previous CTMLE(strategy="oat") construction.
The default is now "per_arm", which fits a separate treatment mechanism on each arm’s outcome
prediction. CollaborativeTMLEMethod accepts the same option. Both designs withhold inferential
standard errors, confidence intervals, and p-values.
(#279)
Treat full-refit bootstrap output as diagnostic for DRTMLE, every CTMLE strategy, and
cross-fitted point-treatment TMLE. Their summaries now report bootstrap sd and a
percentile range. Their to_frame() output uses bootstrap_sd, bootstrap_range_lower,
and bootstrap_range_upper instead of the inferential bootstrap columns.
(#298)
Reassess DR-TMLE intervals that relied on consistency of only one nuisance estimator.
The corrected contract does not establish interval validity from that condition alone.
The fit retains its influence_curve status because it cannot determine which nuisance
conditions hold. Point-estimate double robustness remains unchanged.
(#278,
#291)
Record survival events before censoring. For an event at a node, use censoring 1 and event 1. For censoring after an event-free interval, use censoring 0 and a missing event.
LongitudinalData.from_frame() now refuses event values at or after censoring on an event-free trajectory.
It raises DataError where earlier versions discarded those values.
(#297)
Update simulation error handling if it relied on every exception becoming a failed replication.
CoverageStudy now propagates programming errors, unsupported configurations, and errors while
drawing a sample. It retains supported numerical and fitting failures as ReplicationFailure
records.
(#285)
Refit analyses when migrating saved results to 0.1.3. Loading another package version’s result
emits VersionMismatchWarning; the loader does not migrate the result and loading may fail.
For results containing objects saved by value, use the same Python minor version that saved them.
(#297)
Added#
Longitudinal estimators#
cleverly.longitudinal.SDR and CausalStudy(...).estimate(method="sdr") add sequentially
doubly robust estimation. Consistency requires, at each node, a consistent mechanism ratio or
a consistent regression of the transformed outcome. This consistency property alone does not
establish valid confidence intervals; inference requires additional rate and regularity conditions.
(#284)
SDR supports cross-fitting through a separate recursion within each training fold. Its registered evidence covers two decision nodes and reports finite-sample coverage shortfalls in two declared cells. (#284, #293)
cleverly.longitudinal.IPSI estimates incremental interventions on binary treatments over time.
Use IncrementalEffect with method="ipsi" through CausalStudy.
Each Incremental(delta) multiplies treatment odds at the declared nodes.
The estimator supports dropout, survival and competing-risk horizons, and contrasts between plans.
(#286)
IPSI requires no treatment positivity at a tilt node, but it requires a consistent treatment mechanism there. It is not doubly robust. Dropout still requires observation positivity, and fixed-arm nodes retain their positivity requirements. The registered longitudinal incremental studies have not yet run. (#286)
SDR and IPSI report computed estimates even when they leave the outcome range.
Such estimates emit ParameterSpaceWarning; derived ratios refuse an undefined scale.
(#284,
#286)
Long-panel data and reusable rules#
LongitudinalData.from_long_panel() accepts one row per unit and decision time.
LongPanel supplies the matching CausalStudy design, and to_long_panel() exports an adapted
container. The reader checks temporal ordering, duplicate rows, gaps, late entry, censoring,
and unit-level declarations before fitting learners.
(#297)
each_node(rule, n_times) creates one dynamic rule per decision node.
Each rule receives its node index and the history available at that node.
(#297)
Outcome-adaptive C-TMLE#
The per-arm outcome-adaptive design accepts baseline strata, missing outcomes, and in-sample missing treatments. With missing outcomes, it also supports natural-course means and population attributable risk and fraction. Missing-treatment fits still refuse those natural-course targets and cross-fitting. (#283)
These fits report point estimates and plug-in diagnostics under generated_design_plugin.
Their registered studies identify standard-error deficits, so neither per-arm nor shared
outcome-adaptive fits supply inferential intervals.
(#279,
#280,
#294)
Resumable simulation#
CoverageStudy(checkpoint=DirectoryCheckpoint(...)) saves each completed replication and
resumes unfinished work. ReplicationCheckpoint defines the interface for other storage.
Use a separate checkpoint directory for each study configuration: stored seeds are checked,
but the data-generating process and estimator configuration are not.
(#285)
Changed#
Inference documentation#
The DR-TMLE reference now distinguishes conditions that establish an interval from cases where a first-order remainder remains. A new witness study measures these cases, and the tutorial uses a declared treatment mechanism. The reference also explains the observed bias with a gradient-boosting mechanism and an incorrect outcome regression. (#278, #282, #291)
Among point-treatment fits, only in-sample ordinary TMLE retains an inferential full-refit
bootstrap interval. Its registered evidence uses correctly specified nuisances.
The documentation identifies the remaining evidence gap for data-adaptive learners.
(#298)
Fixed#
Saved inline policies#
result.save() now preserves lambdas, closures, and objects defined in notebooks or __main__
by value through cloudpickle. Loaded results can evaluate these rules, policy densities,
and maps in a new interpreter. Importable functions and classes still require their modules
on the loading machine.
(#297)
Compatibility#
cleverly supports Python 3.11, 3.12, and 3.13 with pandas or Polars dataframes.
cloudpickle>=3.0 is now a core dependency.
(#297)
This remains an alpha release. The package does not promise compatibility for public APIs,
CausalStudy objects, pickled objects, or saved results. Follow the upgrade notes when moving
an analysis to 0.1.3.
Full changelog: v0.1.2…v0.1.3