Repository navigation
Conversation
…me on every cache build The cached event table is written by a parallel sort on patient_id only, so a patient's rows came out in a different order on each build, and Patient sorted by timestamp alone with an unstable sort. Events sharing a timestamp (tied admissions, all diagnoses of an admission, same-day prescriptions) therefore changed order between builds: four fresh builds of synthetic MIMIC-III gave four different MortalityPredictionMIMIC3 sample sets, and diagnoses lost their seq_num order. load_table now numbers each table's rows in file order (_source_row), and Patient sorts by (timestamp, event_type, _source_row), falling back to a stable sort when the column is absent. EVENT_FORMAT joins the dataset cache key so older caches are rebuilt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Building the same dataset twice gives different
set_taskresults. Four fresh cache builds of synthetic MIMIC-III, identical in content, gave four differentMortalityPredictionMIMIC3sample sets:With a cache held fixed,
set_taskitself is deterministic: six fresh processes, with 1 and 4 workers, gave byte-identical samples. The variation comes from the cache build.Cause
_event_transformwrites the event table with a parallelsort_values("patient_id"). Each build has exactly the same rows, but the order of a patient's rows differs between builds.Patientsorts bytimestampalone, with polars' default unstable sort. Events that share a timestamp come out in whatever order the build produced.Ties are common:
seq_numpriority (primary diagnosis first) is lost.Fix
As proposed in #1261: carry each row's source-file order through the build and use it as the tie-breaker. Breaking ties by column values would be wrong, because it would sort MIMIC diagnoses by code rather than by
seq_num.load_tablenumbers each table's rows in file order (_source_row), right after reading and before preprocessing and joins. It uses a globalcumsum, which is ordered across partitions, the same trick the build already uses for tables without a patient id. If apreprocess_<table>hook drops the column, it is added again.Patientsorts by(timestamp, event_type, _source_row). Without the column (aPatientbuilt by hand, orMIMICExtractDataset), it falls back to a stable sort that keeps the input order.EVENT_FORMAT = 2, so caches written before this change are rebuilt instead of keeping their scrambled order. This costs a one-time rebuild per dataset. I chose it over silently keeping old caches, because a wrong diagnosis order is easy to miss._source_rowhas notable/prefix, so it never appears as an event attribute.Results
set_taskDIAGNOSES_ICD.csv(317 admissions)Tests
tests/core/test_event_tie_order.py, synthetic data only:Patientin 5 shuffled orders always come out in source order. This fails on master._source_row, the input order is kept._source_rowis not an event attribute._source_row, and changingEVENT_FORMATchanges the cache directory.examples/event_tie_order.pyshows three fresh builds giving the same priority order.docs/api/data/pyhealth.data.Patient.rsthas a short "Event order" section, andPatienthas a docstring example.Full core suite: 1,496 tests; the only error is
test_sdoh, which also fails on master when the suite is run fromtests/(it looks for its CSV relative to the repo root).Note
For a given dataset, sample order and some samples change compared with earlier caches, because ties now resolve to source order. The order before was arbitrary and differed per build, so no earlier result depended on it reproducibly.
Closes the underlying issue described in #1261.
🤖 Generated with Claude Code