Inspiration
Wearables like WHOOP collect heart rate, HRV and skin temperature every night, but they judge each metric on its own, one night at a time. If several signals shift a little together and stay shifted, which is often what early illness or overload looks like, there's no combined signal. And no wearable maker publishes how often its health flags are right or wrong.
We wanted a flag that looks at signals together, waits for change to persist, explains itself in plain language, and comes with its error rate measured.
What it does
Our pipeline turns wrist-worn wearable signals into severity-rated, explained flags:
- Learns your resting normal for each signal from a rest period
- Scores how unusual each moment is in your own terms (signed z-scores: heart rate up, HRV down, skin temperature either way)
- Combines the signals, so several small shifts add up to one meaningful signal
- Waits for persistence, so a flag only fires if the combined score stays high (2 of the last 3 windows)
- Rates severity as Watch, Notable or Strong, and drops a tier if the accelerometer shows movement explains it
- Explains each flag in real units, e.g. "heart rate +18 bpm vs your rest"
A timeline view shows each person's signals, combined score, tier bands and flag explanations.
How we built it
- Data: the open PhysioNet dataset Wearable Physiological Signals under Acute Stress and Exercise Conditions (Empatica E4 wristband): 36 stress-task, 30 aerobic and 31 anaerobic participants. Timed protocol tags tell us exactly when each stressor starts, and participants self-reported stress from 1 to 10, giving us ground truth that everyday wearable data never has.
- WHOOP-equivalent signals only: heart rate, HRV (RMSSD from beat intervals) and skin temperature feed the score. The accelerometer is used only for the movement check, and electrodermal activity is excluded because WHOOP doesn't measure it.
- Method: Python, one module per pipeline step (
data/,flag/,eval/,app/). Per-person baselines use median/MAD with empirical-Bayes shrinkage toward the cohort. We compare a directional sum against a Mahalanobis distance. - Evaluation: thresholds tuned with leave-one-subject-out cross-validation, compared against a WHOOP-style single-signal rule on sensitivity, false alarms per hour of rest, detection delay, tier agreement with self-reported stress, and movement attribution.
Challenges we ran into
- Short stressors: some stress tasks last only 30 seconds, so we score every 10 seconds on rolling 30-second windows.
- Sparse heartbeat data: the E4 only logs beats it's confident about (roughly 15–30% of the time in our first session), so HRV needed longer 120-second windows.
- Messy real data: duplicated signals, a dock covering the sensors, split recordings and early stops all had to be cleaned using the dataset's documented constraints.
- No baseline for some sessions: older-protocol exercise sessions have no quiet rest period, so we reused each person's stress-session baseline.
Accomplishments
- A full end-to-end pipeline, from raw wristband CSVs to explained, tiered flags
- Measuring our own false alarms instead of hiding them, which is the number wearable makers don't publish
- Plain-language explanations a non-expert can act on
- We also ran the same pipeline on one teammate's nightly WHOOP data via the WHOOP API (
read:recovery,read:sleep), with their consent.
What we learned
- After combining the signals, another problem that arose was keeping the false alarm flags to a minimum to maintain the reliability of the flags.
- Wording is part of the design. After the FDA's 2025 warning letter to WHOOP over a color-coded feature, we use neutral tiers and say "sustained change," never "you may be sick."
- Being honest about limits makes the result more credible, not less.
Ethics and limitations
- Not a medical device. A flag at any tier means "sustained change," not a diagnosis.
- Built on open, de-identified data, cited under its ODC-By license. Raw recordings are not redistributed.
- Participants were healthy 18–30-year-olds in short lab sessions, so results show acute, induced change, not illness or multi-day drift.
- Applying the method to nightly WHOOP data is a transfer we argue for. Our WHOOP example is one person, an illustration rather than a validation.
What's next
- Run the pipeline on WHOOP nightly summaries at scale
- Export Tier 2–3 flags as FHIR observations or a CMS-style care update a clinician could review
Data citation: PhysioNet, DOI 10.13026/he0v-tf17 · Hongn et al., Scientific Data (2025) · ODC-By
Log in or sign up for Devpost to join the conversation.