PyHealth 2.0.2 #1226
jhnwu3
announced in
Announcements
PyHealth 2.0.2
#1226
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Changelog
All notable changes to PyHealth are documented here. Versions follow the
major.minor.patchscheme; see thereleases page for the
corresponding tags and wheels.
2.0.2 — 2026-09-02
The first release since 2.0.1 (2026-03-30). It adds four datasets, a synthetic-EHR
generation and evaluation stack, several new models and interpretability methods, and
a large batch of correctness fixes across models, tasks, metrics, and calibration.
No public API was removed or renamed — 2.0.1 code continues to work unchanged.
New datasets
MEDSDatasetplus a typed Parquet scan path onBaseDataset..parquet/
.pqfiles, globs, and directories now route through a typed_scan_parquetscanner, with a datetime fast path that skips the string round-trip. Includes the
in_hospital_mortality_medstask. (#1179)pyhealth/datasets/fhir/, including aMIMIC-IV-on-FHIR dataset. (#1155)
deid_ner), and theTransformerDeIDmodel. (#981)New models
pyhealth/models/generators/: HALO, MedGAN, CorGAN,PromptEHR, and a GPT-2 generator, with the
generate_ehrtask. (#1148)fitbeforeinference. (#999)
static_keysupport fordemographic features. (#905)
New tasks and metrics
DrugRecommendationOMOP— a class-based OMOP drug recommendation task. (#1203)pyhealth/metrics/generative/scores syntheticEHR data on privacy (NNAAR, membership inference, discriminator privacy), utility,
and statistical fidelity. (#1148)
2020) in the new
pyhealth/calib/predictionset/scores.py, with a dynamicscore_typeon conformal methods (#1189),plus additional conformal methods and example scripts (#942).
Restored from 1.x
code_mapping—SequenceProcessoraccepts an optionalcode_mappingthatcollapses granular codes into grouped vocabularies (ICD9CM→CCSCM, ICD9PROC→CCSPROC,
NDC→ATC) before building the embedding table, and
BaseTask.__init__accepts itdirectly so schemas no longer have to be patched by hand. Closes the functional gap
left by the 1.x→2.0 rewrite. (#905, ref #535)
Fixes
Data leakage and label correctness
procedure codes are timestamped at
dischtime, so for the admission being predictedthey are only known at or after the outcome, and labs were pulled through
discharge/death. Those codes are now excluded for that admission and its labs capped
to the first 48 hours. (#1205)
drug_recommendation_omop_fnnever excluded the current visit's own drugs fromdrugs_all, making the last history entry identical to the prediction target. (#1203)event.drug(drug names, e.g. "Aspirin"), which produce zeromatches in the NDC→ATC CrossMap; they now extract
event.ndc. (#905)Models
CNNcrashed on 1-D tensor and multi-hot inputs:forwardhardcoded a 3-Dexpectation for
spatial_dim=1, butMultiHotProcessorand 1-DTensorProcessorinputs embed to
[batch, embedding_dim]with no sequence axis. Now treated as alength-1 sequence. (#1208)
TCNcrashed on tuple-schema features by passing raw kwargs (includingStageNetProcessor's(time, value)tuples) to the embedding model; it now unwrapsthe
valuetensor first, like its sibling sequence models. (#1212)BIOThardcodednn.Embedding(n_channels, 256)for channel tokens, crashing forany
emb_size != 256. (#1213)MoleRec's no-SMILES fallback predictor was created lazily insideforward, so anoptimizer built from
model.parameters()beforehand never saw its parameters and itnever trained. It is now created in
__init__. (#1214)SdohClassifierwas annn.Moduledecorated with@dataclass, whose generated__init__never callednn.Module.__init__, leaving the module without_parameters/_modulesand unusable in torch. (#1209)SinusoidalTimeEmbeddingdivided frequency indices byhalf - 1, sodim=2gave0/0 and every embedding was NaN. Clamped to at least 1. (#1216)
AdaCare. (#1139)RNNLayerandConCarecrashed on zero-length sequences and onbatch_size=1;GRASPcollapsed its hidden state atbatch_size=1and raised whencluster_num > batch_size. (#905)collate_fnbuilt output keys from only the first sample in a batch, so abatch mixing samples with and without a mined hard negative (
s_n) either raisedKeyErroror silently produced a misaligned list; keys are now unioned across thebatch. (#1222)
Datasets and tasks
patient_id. (#1193)SampleDatasetsubset mappings were wrong. (#1211)PatientLinkageMIMIC3Task'sinput_schemanamed"integer"/"string"/"datetime"processors, none of which are registered, soset_task()failedimmediately with
ValueError: Unknown processor. (#1204)Metrics, calibration, and interpretability
ece_confidence_binaryindexedprob[:, 0]/label[:, 0], requiring 2-D arrays,but its only caller passes 1-D positive-class probabilities and 1-D 0/1 labels — so
ECEandECE_adaptalways raisedIndexErroron binary tasks. (#1215)disparate_impactandstatistical_parity_differencereturnednanfor emptysubgroups instead of raising: the rate was a numpy 0/0, and since
nan == 0isalways
Falsethe existing zero guard never caught it (and only ever checked theunprotected group). (#1199)
fairness_metrics_fnwas commented out ofpyhealth.metrics; re-enabled and addedto
__all__. (#1200)original_class_probstoy_probsand negated negative-class entries in place, flipping the sign on every iteration of
the percentage loop — a sample's score depended on where its percentage sat in the
list. (#1196)
target_class_idxhandling, argument naming, and sample-classfiltering. (#926)
and Algorithm 2 of the paper and the already-correct class-specific loss in the same
file; fixed in both the Python and Cython paths, along with a
fill_maxinferencegap. (#1190)
Examples and docs
code_mapping,dev, andrefresh_cachearguments fromREADME.rst, example scripts, and leaderboard utilities — the 2.0MIMIC3Dataset/MIMIC4Datasetno longer accept them. (#935, fixes #535)SyntaxErrorinexamples/benchmark_perf/loc/minimal_los.py, a missing__main__guard that hungreadmission_mimic3_fairness.pyunder multiprocessing,and a stale
Transformer(...)call. (#1200)Colab notebooks. (#1143, #1146)
Infrastructure
pyhealth/(
tools/check_pr_rules.py). (#1176)RNNandMultimodalRNN. (#936)tools/bump_version.pynow keepspyhealth.__version__in sync withpyproject.toml, rewrites only the[project]version line, and no longer hangswhen bumping from a non-pre-release version.
Full Changelog: v2.0.1...v2.0.2
This discussion was created from the release PyHealth 2.0.2.
All reactions