Point survival hazard#

This study validates longitudinal TMLE with survival_model="hazard" and targeting="iterative" on a held design. The design has one baseline treatment, held over every visit, and it reads one follow-up time and one event code per unit (TimeToEvent). Each reported horizon targets the discrete cause-specific hazards of every regimen and cause on its own (Moore and van der Laan 2009, Section 4.1). The section hazard-based survival targeting states the estimator and its exact-law evidence.

The laws are the survival and competing scenarios of point-treatment survival. Every truth is an exact finite sum. Every efficiency bound is the exact standard deviation of the efficient influence function over the law’s support.

The comparator is R survtmle 1.1.1 with method = "hazard" (Benkeser, Carone and Gilbert 2018). The comparator runs are pending, so this study carries the label “Python property evidence, with comparator runs pending”. The runs are queued as Study queue row 20 in TRACKER.md. The comparison is not acceptance evidence for any claim until that row closes.

What was compared#

setting

cleverly

R survtmle

status

run and published on this page

pending. No reference process ran, and equivalence.csv has no rows

datasets

1,600 samples of 2,000 rows for each scenario

the identical rows, once the runs exist

scenarios

survival: five visits, the risks of both arms and their difference at visits 1, 3 and 5. competing: four visits and two causes, the incidences and their differences at visits 2 and 4

the same

treatment model

a logistic regression on W1 + W2

glm.trt = "W1 + W2"

censoring model

a logistic regression on the arm, W1 and W2 at each visit

one pooled glm with one intercept and three slopes for each visit, which factorises by visit into the same model

hazard model

an unpenalized logistic regression on W1, W2 and the arm at each node and cause

one pooled glm with the same terms for each visit and cause

targeting

targeting="iterative", all causes fluctuated together in a multinomial logistic submodel, stopped at a relative score of 1e-10

one cause at a time in a logistic submodel, stopped at `max

intervals

pointwise 95% Wald from the influence curve

the same

The pending runs read under the default margins. The two targeting loops differ by construction. The runner declares tol = 1/n and maxIter = 100. The survtmle default tol = 1/sqrt(n) stops before any targeting step at the laws of this study.

Accuracy against known truth#

law

estimand

what was tested

implementation

bias (99% interval)

coverage

SE ratio

result

four visits, two competing causes, a held binary treatment, visit dropout

ate_regimen[arm1 vs arm0, death @ t=2]

difference in cumulative incidence of death between the plans “assign arm 1 at baseline and hold it” against “assign arm 0 at baseline and hold it” at horizon t = 2

cleverly

-0.000415 to 0.0013

0.9544

1.0251

pass

four visits, two competing causes, a held binary treatment, visit dropout

ate_regimen[arm1 vs arm0, death @ t=4]

difference in cumulative incidence of death between the plans “assign arm 1 at baseline and hold it” against “assign arm 0 at baseline and hold it” at horizon t = 4

cleverly

-0.000787 to 0.0016

0.9519

0.9928

pass

four visits, two competing causes, a held binary treatment, visit dropout

ate_regimen[arm1 vs arm0, relapse @ t=2]

difference in cumulative incidence of relapse between the plans “assign arm 1 at baseline and hold it” against “assign arm 0 at baseline and hold it” at horizon t = 2

cleverly

-0.000912 to 0.0010

0.9519

1.0157

pass

four visits, two competing causes, a held binary treatment, visit dropout

ate_regimen[arm1 vs arm0, relapse @ t=4]

difference in cumulative incidence of relapse between the plans “assign arm 1 at baseline and hold it” against “assign arm 0 at baseline and hold it” at horizon t = 4

cleverly

-0.0013 to 0.0014

0.9475

0.9847

pass

four visits, two competing causes, a held binary treatment, visit dropout

cif_regimen[arm0, death @ t=2]

cumulative incidence of death under the plan assign arm 0 at baseline and hold it at horizon t = 2

cleverly

-0.000980 to 0.000460

0.9494

1.0075

pass

four visits, two competing causes, a held binary treatment, visit dropout

cif_regimen[arm0, death @ t=4]

cumulative incidence of death under the plan assign arm 0 at baseline and hold it at horizon t = 4

cleverly

-0.0011 to 0.000869

0.9431

0.9768

pass

four visits, two competing causes, a held binary treatment, visit dropout

cif_regimen[arm0, relapse @ t=2]

cumulative incidence of relapse under the plan assign arm 0 at baseline and hold it at horizon t = 2

cleverly

-0.000696 to 0.000665

0.9519

1.0255

pass

four visits, two competing causes, a held binary treatment, visit dropout

cif_regimen[arm0, relapse @ t=4]

cumulative incidence of relapse under the plan assign arm 0 at baseline and hold it at horizon t = 4

cleverly

-0.000883 to 0.000929

0.9500

1.0063

pass

four visits, two competing causes, a held binary treatment, visit dropout

cif_regimen[arm1, death @ t=2]

cumulative incidence of death under the plan assign arm 1 at baseline and hold it at horizon t = 2

cleverly

-0.000304 to 0.000656

0.9500

1.0170

pass

four visits, two competing causes, a held binary treatment, visit dropout

cif_regimen[arm1, death @ t=4]

cumulative incidence of death under the plan assign arm 1 at baseline and hold it at horizon t = 4

cleverly

-0.000387 to 0.000968

0.9519

1.0169

pass

four visits, two competing causes, a held binary treatment, visit dropout

cif_regimen[arm1, relapse @ t=2]

cumulative incidence of relapse under the plan assign arm 1 at baseline and hold it at horizon t = 2

cleverly

-0.000655 to 0.000727

0.9487

0.9937

pass

four visits, two competing causes, a held binary treatment, visit dropout

cif_regimen[arm1, relapse @ t=4]

cumulative incidence of relapse under the plan assign arm 1 at baseline and hold it at horizon t = 4

cleverly

-0.000883 to 0.0010

0.9456

0.9692

pass

five visits, a binary baseline treatment held over every node, visit dropout

ate_regimen[arm1 vs arm0 @ t=1]

difference in cumulative risk between the plans “assign arm 1 at baseline and hold it” against “assign arm 0 at baseline and hold it” at horizon t = 1

cleverly

-0.000617 to 0.0012

0.9619

1.0254

pass

five visits, a binary baseline treatment held over every node, visit dropout

ate_regimen[arm1 vs arm0 @ t=3]

difference in cumulative risk between the plans “assign arm 1 at baseline and hold it” against “assign arm 0 at baseline and hold it” at horizon t = 3

cleverly

-0.000543 to 0.0023

0.9506

0.9945

pass

five visits, a binary baseline treatment held over every node, visit dropout

ate_regimen[arm1 vs arm0 @ t=5]

difference in cumulative risk between the plans “assign arm 1 at baseline and hold it” against “assign arm 0 at baseline and hold it” at horizon t = 5

cleverly

-0.0013 to 0.0019

0.9487

1.0009

pass

five visits, a binary baseline treatment held over every node, visit dropout

risk_regimen[arm0 @ t=1]

cumulative risk under the plan assign arm 0 at baseline and hold it at horizon t = 1

cleverly

-0.000909 to 0.000506

0.9519

1.0091

pass

five visits, a binary baseline treatment held over every node, visit dropout

risk_regimen[arm0 @ t=3]

cumulative risk under the plan assign arm 0 at baseline and hold it at horizon t = 3

cleverly

-0.0019 to 0.000165

0.9537

0.9877

pass

five visits, a binary baseline treatment held over every node, visit dropout

risk_regimen[arm0 @ t=5]

cumulative risk under the plan assign arm 0 at baseline and hold it at horizon t = 5

cleverly

-0.0017 to 0.000440

0.9525

1.0147

pass

five visits, a binary baseline treatment held over every node, visit dropout

risk_regimen[arm1 @ t=1]

cumulative risk under the plan assign arm 1 at baseline and hold it at horizon t = 1

cleverly

-0.000521 to 0.000688

0.9431

0.9757

pass

five visits, a binary baseline treatment held over every node, visit dropout

risk_regimen[arm1 @ t=3]

cumulative risk under the plan assign arm 1 at baseline and hold it at horizon t = 3

cleverly

-0.000956 to 0.000924

0.9594

1.0152

pass

five visits, a binary baseline treatment held over every node, visit dropout

risk_regimen[arm1 @ t=5]

cumulative risk under the plan assign arm 1 at baseline and hold it at horizon t = 5

cleverly

-0.0014 to 0.000779

0.9531

1.0188

pass

All 21 implementation-estimand tests pass. No replication raised an error, so no cell lost a replicate.

Theory properties#

property

cell

role

what was tested

what must hold

measured

result

double_robustness

survival_t5__both_correct

positive

difference of arm 1 and arm 0 at visit 5, five-visit held law: both the outcome regression and the treatment mechanism are correctly specified

bias interval inside the equivalence margin, with the reported standard error on the scale of the empirical spread

bias -0.0024 to 0.0013, margin 0.0062, SE ratio 0.9823

pass

double_robustness

survival_t5__both_wrong

control

difference of arm 1 and arm 0 at visit 5, five-visit held law: both nuisances are misspecified

bias interval must fall entirely outside the margin, with the reported standard error still on the scale of the empirical spread

bias 0.0330 to 0.0366, margin 0.0060, SE ratio 1.0075

pass

double_robustness

survival_t5__mechanism_correct

positive

difference of arm 1 and arm 0 at visit 5, five-visit held law: only the treatment and censoring mechanisms are correctly specified

bias interval inside the equivalence margin, with the reported standard error on the scale of the empirical spread

bias -0.0027 to 0.000933, margin 0.0060, SE ratio 1.0206

pass

double_robustness

survival_t5__outcome_correct

positive

difference of arm 1 and arm 0 at visit 5, five-visit held law: only the outcome regression is correctly specified

bias interval inside the equivalence margin, with the reported standard error on the scale of the empirical spread

bias -0.000803 to 0.0028, margin 0.0061, SE ratio 0.9720

pass

interval_calibration

competing_t4__correctly_specified

positive

difference in the death incidence at visit 4, two causes: both nuisances are correctly specified with an independently computed efficiency bound

SE ratio and coverage intervals both inside their calibration bands, with both efficiency-ratio intervals inside their bands

coverage 0.9371 to 0.9541, SE ratio 0.9745 to 1.0264, empirical efficiency ratio 0.9740 to 1.0257, reported efficiency ratio 0.9986 to 1.0004

pass

interval_calibration

survival_t5__correctly_specified

positive

difference of arm 1 and arm 0 at visit 5, five-visit held law: both nuisances are correctly specified with an independently computed efficiency bound

SE ratio and coverage intervals both inside their calibration bands, with both efficiency-ratio intervals inside their bands

coverage 0.9445 to 0.9560, SE ratio 0.9859 to 1.0221, empirical efficiency ratio 0.9803 to 1.0162, reported efficiency ratio 1.0015 to 1.0021

pass

interval_calibration

survival_t5__noise_control

control

difference of arm 1 and arm 0 at visit 5, five-visit held law: one efficiency-bound unit of independent noise is added to each estimate

the empirical efficiency ratio must rise above the band

coverage 0.8268 to 0.8464, SE ratio 0.6965 to 0.7223, empirical efficiency ratio 1.3868 to 1.4384, reported efficiency ratio 1.0015 to 1.0021

pass

interval_calibration

survival_t5__shrunken_se_control

control

difference of arm 1 and arm 0 at visit 5, five-visit held law: the reported standard errors are multiplied by a declared factor below one

the SE-ratio interval must fall below the calibration band

coverage 0.8252 to 0.8448, SE ratio 0.6892 to 0.7157, empirical efficiency ratio 0.9798 to 1.0175, reported efficiency ratio 0.7011 to 0.7015

pass

power

survival_t5__alternative

positive

difference of arm 1 and arm 0 at visit 5, five-visit held law: the same test applied to a law with a real effect

rejection lower bound clears the minimum power

rejection 1, 0.9934 to 1

pass

root_n_and_efficiency

survival_t5__n_1000

control

difference of arm 1 and arm 0 at visit 5, five-visit held law: bias, coverage and SE calibration at n = 1,000

coverage interval lies below nominal or clears the declared floor

bias -0.0022, coverage 0.9371 to 0.9747, SE ratio 1.0186

pass

root_n_and_efficiency

survival_t5__n_2000

positive

difference of arm 1 and arm 0 at visit 5, five-visit held law: bias, coverage and SE calibration at n = 2,000

bias inside the margin, coverage clears the floor, SE ratio inside the sanity band

bias -0.000720, coverage 0.9311 to 0.9708, SE ratio 1.0110

pass

root_n_and_efficiency

survival_t5__n_8000

positive

difference of arm 1 and arm 0 at visit 5, five-visit held law: bias, coverage and SE calibration at n = 8,000

bias inside the margin, coverage clears the floor, SE ratio inside the sanity band

bias 0.000264, coverage 0.9252 to 0.9667, SE ratio 0.9897

pass

root_n_rate

survival_t5__empirical_sd

positive

difference of arm 1 and arm 0 at visit 5, five-visit held law: log empirical spread of the estimates regressed on log n across three sizes

slope interval inside the root-n band and excluding -1/4

slope -0.5286 to -0.4436

pass

root_n_rate

survival_t5__reported_se

positive

difference of arm 1 and arm 0 at visit 5, five-visit held law: the same regression applied to the mean reported standard error

slope interval inside the root-n band and excluding -1/4

slope -0.5019 to -0.5005

pass

simultaneous_coverage

all_reported__pointwise_joint_control

control

every parameter the calibration fit reports: the pointwise 95% intervals of the same fits, read jointly

joint coverage upper endpoint must fall below the nominal rate

joint coverage 0.6522 to 0.6772

pass

simultaneous_coverage

all_reported__simultaneous_band

positive

every parameter the calibration fit reports: the max-t multiplier band over every estimand the law reports, from the same-row centered influence curves

joint coverage interval inside the calibration coverage band

joint coverage 0.9392 to 0.9512

pass

targeting_necessity

survival_t5__targeted

positive

difference of arm 1 and arm 0 at visit 5, five-visit held law: the estimator fluctuates a misspecified outcome model, so targeting does all the adjusting

bias interval inside the equivalence margin

bias -0.0014 to 0.0025, margin 0.0064

pass

targeting_necessity

survival_t5__untargeted

control

difference of arm 1 and arm 0 at visit 5, five-visit held law: the identical fit with every fluctuation step removed

bias interval must fall entirely outside the margin

bias 0.1405 to 0.1405, margin 0

pass

All 18 property cells pass. Each positive cell has a control that fails the same instrument in the opposite direction.

family

positive cells

control that must fail

interval_calibration

the visit-5 difference on survival, and the death incidence difference at visit 4 on competing

reported standard errors scaled by 0.7, and one efficiency-bound unit of added noise

double_robustness

the hazard correct, the mechanism correct, or both

both wrong

targeting_necessity

the targeted estimate with a wrong hazard and the correct mechanism

the plug-in of the same fit

root_n_and_efficiency

n = 2,000 and 8,000

n = 1,000

root_n_rate

the empirical spread and the reported standard error

none. The slope interval must exclude -0.25

power

the alternative on survival

none

simultaneous_coverage

the band over the fifteen reported parameters

the pointwise intervals read as a joint set

The correct mechanism learners are the saturated cell fits. The correct hazard learner is an additive logistic fit on survival, which targeting moves, and the saturated cell fit on competing. A saturated hazard fitted in sample is the maximum-likelihood estimate, so its initial score is zero and targeting does not move it. The untargeted control predicts one hazard for each node and both arms, so its plug-in contrast is zero in every sample. The necessity verdict rests on the targeted cell and on its displacement from the plug-in.

Measured values#

Names beginning margin: are thresholds declared before the run. Everything else is measured from the committed results and checked at the precision printed.

quantity

value

source

replicates

1600

primary replications per scenario

n

2000

observations per primary replication

independent_tests_total

21

implementation-estimand tests against the truth

independent_tests_passed

21

of those, passing

property_cells_total

18

repeated-sampling property cells

property_cells_passed

18

cells whose own and family verdicts pass

max_standardized_bias

0.0543

largest absolute primary bias in empirical standard deviations

min_coverage

0.9431

lowest measured primary-study coverage

min_se_ratio_ci_lower

0.9287

lowest bootstrap primary SE-ratio endpoint

max_se_ratio_ci_upper

1.0758

highest bootstrap primary SE-ratio endpoint

margin:alpha

0.0500

nominal size of the reported intervals, and the family level of the rule

margin:bootstrap_replicates

10000

resamples behind every bootstrap interval

margin:calibration_coverage_lower

0.9200

calibration-cell coverage band, lower limit. No cell of this study reads it

margin:calibration_coverage_upper

0.9800

calibration-cell coverage band, upper limit. No cell of this study reads it

margin:calibration_noninferiority

0.0500

largest external-comparison calibration excess bound

margin:calibration_se_ratio_lower

0.9300

calibration-cell SE-ratio band, lower limit. No cell of this study reads it

margin:calibration_se_ratio_upper

1.0700

calibration-cell SE-ratio band, upper limit. No cell of this study reads it

margin:confidence_level

0.9900

confidence level of every Monte Carlo interval

margin:coverage_floor

0.9000

validity floor the coverage lower endpoint must clear

margin:coverage_noninferiority

-0.0250

smallest external-comparison coverage difference bound

margin:efficiency_ratio_lower

0.9000

efficiency-ratio lower bound

margin:efficiency_ratio_upper

1.1000

efficiency-ratio upper bound

margin:excluded_slope

-0.2500

slower rate a root-n interval must exclude

margin:minimum_power

0.8000

rejection lower bound a power cell must clear

margin:nominal_coverage

0.9500

nominal coverage those intervals claim

margin:over_coverage_ceiling

0.9900

above this, coverage is conservative rather than invalid

margin:paired_difference

0.1500

paired similarity margin, in pooled empirical standard deviations

margin:rmse_noninferiority

1.1000

largest external-comparison RMSE ratio bound

margin:root_n_slope

-0.5000

contraction rate root-n asymptotics predict

margin:root_n_slope_lower

-0.6250

accepted root-n slope band, lower limit

margin:root_n_slope_upper

-0.3750

accepted root-n slope band, upper limit

margin:se_ratio_sanity_lower

0.8000

SE-ratio screen, lower limit

margin:se_ratio_sanity_upper

1.2000

SE-ratio screen, upper limit

margin:shrunken_se_factor

0.7000

negative-control SE multiplier

margin:standardized_bias

0.2500

bias equivalence margin, in empirical standard deviations

margin:targeting_displacement

0.2500

least targeting must move the estimate

margin:type_i_ceiling

0.1000

the rate a positive cell must bound and a control must exceed

margin:union_model_se_lower

0.1000

union-model SE-ratio screen, lower limit

margin:union_model_se_upper

10

union-model SE-ratio screen, upper limit

Limitations#

limit

what it means for use

the comparator runs are pending

no survtmle output is compared. The survtmle rows of Study queue row 20 follow, and this page is Python property evidence until then

per-horizon targeting only

targeting="one_step" and the monotone whole-curve estimate are outside this study

finite laws with discrete covariates

the evidence covers correct or misspecified low-dimensional logistic and saturated learners. A flexible learner is outside it

the declared survtmle settings differ

survtmle fluctuates one cause at a time. The pending pairs read under the default margins and not as an exactness check

no cross-fitting, weights or clusters

each is a separate composition and needs its own row

Reproduction#

The manifest records the seeds, the margins, the estimator configuration, the source hashes and the result hashes. It records the comparator as pending, with the runner and the image source hashes. Run python -m tests.canonical.point_survival_hazard.regenerate to regenerate the artifacts. The replications and the property results carry every published row.