Detecting stress from wearable sensors — in people the model has never seen
A chest sensor records heartbeat (ECG), sweat response (EDA), muscle activity, temperature and breathing. I built a pipeline that turns 60 seconds of these noisy signals into a prediction of the wearer's state, and evaluated it the strict way: every result is on a person whose data was never used in training.
Leave-one-subject-out evaluation on all 15 people of the WESAD study: hold one person out, train on the rest, test on that person, repeat 15 times. Deep models are 5-seed ensembles.
Show as a table
Clean the signals
Anti-aliased resampling from 700 Hz to 100 Hz, then per-person normalisation — skin conductance and body temperature differ more between people than between moods.
Two views of each 60 s window
Physiological features (heart rate, HRV, sweat-response count, breathing rate) and the raw waveform, compressed 64× by a 1-D CNN before a bidirectional LSTM with attention.
Fuse and classify
The hybrid model concatenates both views. Features are standardised using training people only, so nothing about the test person leaks in.
- Evaluation design matters more than the model. My first LSTM scored 19% — worse than guessing. The fixes were per-person normalisation and a CNN front-end, not a bigger network.
- More regularisation did not help. Lower learning rate, dropout, label smoothing, crop and channel-drop augmentation all scored at or below the baseline: the gap is person-to-person variation, not classic overfitting.
- Single runs lie. The same CNN-LSTM varied by ±0.05 macro-F1 from the random seed alone, so the final numbers are 5-seed ensembles. Validating on one person per fold was too noisy to tune on: it would have picked a setting that did worse on test, so I kept the defaults and publish both scores.
- Simple features win on average; deep models fail more gracefully. The Random Forest has the best 4-state score (0.76 macro-F1) but collapses on one person (0.22). The hybrid's worst person still scores 0.52, and adding features lifted the CNN-LSTM from 0.68 to 0.70.