Add Ascertainment model for JointAscertainment#802
Conversation
|
Thanks @cdc-mitzimorris. Before I review further, could you explain the decision to use a context layer here versus any alternative approaches you considered? |
for more information, see https://pre-commit.ci
…new into mem_777_joint_ascertainment
The main design constraint was that joint ascertainment needs to create one shared NumPyro sample site, while existing observation processes expect signal-specific I considered passing the sampled mapping explicitly through the model stack, but that would require broader plumbing/API changes. I also wanted to avoid having each signal accessor sample independently, since that would either duplicate sites or lose the intended joint dependence. Storing sampled values directly on the model object also seemed fragile for NumPyro execution, since model calls/traces should not depend on mutable object state. The context layer is intended to keep the public observation API unchanged: the joint model samples once, then the signal accessors retrieve their already-sampled values from execution-scoped context without creating additional NumPyro sites. This keeps ownership of the shared sample site centralized in the ascertainment model, while keeping observation processes focused on consuming signal-specific rates. |
There was a problem hiding this comment.
A few minor suggestions. Happy for you to merge without re-review from me if @damonbayer is satisfied that his requested changes have been made. Thanks, @cdc-mitzimorris!
damonbayer
left a comment
There was a problem hiding this comment.
I would like to review the tutorial, once it can be rendered.
|
@damonbayer - tutorial renders. |
|
Expect panache to reformat the tutorial doc. |
Co-authored-by: Damon Bayer <xum8@cdc.gov>
Summary
This PR adds model-level ascertainment support so multiple observation signals can share structured ascertainment rates instead of each observation independently sampling its own rate.
The main motivation is to support H+E-style multisignal models where hospital admissions and ED visits have distinct but related observation probabilities. The new abstraction lets those probabilities be sampled once at the model level, then passed into observation processes through signal-specific accessors without creating duplicate NumPyro sample sites.
Additions / Changes
Added a new
pyrenew.ascertainmentpackage with:AscertainmentModel, the base interface for shared ascertainment models.AscertainmentSignal, a signal-specific accessor used by observation processes.JointAscertainment, which samples correlated scalar ascertainment rates across signals on the logit scale.Extended
PyrenewBuilderwithadd_ascertainment(...), allowing shared ascertainment models to be registered alongside latent and observation components.Extended
MultiSignalModelso registered ascertainment models are sampled once before observation processes run. Observation processes then retrieve their signal-specific values from the active ascertainment context.Added unit coverage for validation, sampling behavior, context safety, duplicate-site avoidance, builder registration, and direct
MultiSignalModelvalidation.Added integration coverage for mixed-cadence hospital + ED models:
JointAscertainmentSuggested Review Order
pyrenew/ascertainment/base.pyandpyrenew/ascertainment/context.pyto understand the core abstraction and how accessors retrieve already-sampled values.pyrenew/ascertainment/joint.pypyrenew/model/pyrenew_builder.pyandpyrenew/model/multisignal_model.py.docs/tutorials/ascertainment.pytest/test_ascertainment.pyand the new builder tests intest/test_pyrenew_builder.py.test/integration/conftest.pyand the two new H+E integration test files, since those show the intended end-to-end usage.