← Blog/blog/sleep-apnea-auc-missing-folds

The sleep-apnea detector with 29 missing ROC curves

A mattress can listen to breathing without a wearable. Tiny pressure changes—called a ballistocardiogram, or BCG—carry respiratory motion, heartbeat, posture, and movement. Campero Jurado and colleagues turn those mixed signals into a strong sleep-apnea event detector.

The headline is excellent: Histogram Gradient Boosting reaches 0.969 ROC AUC while holding out one patient at a time. The evaluation detail that should travel with that number is less prominent: 29 held-out patients had no clean windows, so their ROC curves did not exist.

01

Turn the bed into six breathing signals

The authors record 512 pressure sensors at 50 Hz. They sum the whole mat and three body regions, average five sensors with strong respiratory periodicity, and build one adaptively preprocessed channel. That last channel high-pass filters drift, selects sensors by autocorrelation and spectral concentration, flips sensors with opposite polarity, and averages them.

Study detailValueWhy it matters
Participants155Each patient held out once
Pressure sensors51216 × 32 capacitive mat at 50 Hz
Event windows28,786Expert-scored respiratory events
Clean windows21,088At least 30 s from an event
Features191Ten groups across six signal channels
ROC-ineligible folds29No clean windows after filtering
Paper-reported cohort, sensing, feature, and fold counts.
02

A breath leaves a spectral fingerprint

Normal adult breathing concentrates pressure variation near 0.1–0.4 Hz—roughly 6–24 breaths per minute. The implementation computes a discrete Fourier transform directly, squares each complex magnitude, and integrates power inside that band. No signal-processing or ML library is involved.

regular breathinginterrupted breathing
Seed-free illustrative signals computed by the tested core. The orange toy window removes a 16-second stretch of a 0.25 Hz breath; these are not patient recordings.
Illustrative 0.1–0.4 Hz band power from the same core-generated windows. The interruption disperses and reduces periodic breathing energy.

In the clinical data, breathing-band power alone receives 30.3% of total Random Forest impurity importance across six channels. Six FFT shape descriptors on the preprocessed channel add 15.1%. Simple area and curve-length features supply another 21.5%.

Paper-reported Random Forest mean-decrease-in-impurity shares. The six largest groups are shown; shares are descriptive model importances, not causal effects.
03

Why one-class patients have no ROC curve

ROC AUC has a wonderfully concrete meaning: choose one positive and one negative example at random; AUC is the probability that the model ranks the positive higher, with half credit for a tie. The tested implementation below uses that definition directly.

def roc_auc(labels, scores):
    pos = [s for y, s in zip(labels, scores) if y == 1]
    neg = [s for y, s in zip(labels, scores) if y == 0]
    if not pos or not neg:
        return None
    wins = 0.0
    for p in pos:
        for n in neg:
            wins += 1.0 if p > n else 0.5 if p == n else 0.0
    return wins / (len(pos) * len(neg))

The four-example toy scores produce AUC 1. But when a held-out patient contributes only respiratory-event windows, there is no negative to pair with a positive. The result is therefore null, not zero, one, or 0.5.

Paper-reported fold eligibility reconstructed from 155 patients: 29 folds contained no clean window after the 30-second event-exclusion buffer. Percentages are computed by the tested core.
ClassifierROC AUCPR AUCF1
Logistic regression0.7970.8790.838
Random Forest0.9670.9770.905
Histogram GBT0.9690.9790.915
Paper-reported mean leave-one-patient-out metrics. ROC AUC is undefined for the 29 one-class test folds.
04

The feature ranking is not an ablation

The title says spectral features “dominate,” but the ranking uses Random Forest mean decrease in impurity (MDI). Correlated versions of the same breathing-band feature appear across six channels, and continuous features offer many split candidates. MDI can distribute or inflate credit under both conditions. The authors explicitly warn that it can favor high-cardinality features and does not measure causal importance.

That distinction matters for the proposed compact detector. “These 48 features receive 67% of MDI” does not prove that removing the other 143 preserves 90% of predictive performance. A grouped ablation—retraining without each family inside every patient-held-out fold—would answer the engineering question directly.

05

What to probe next

  • Publish each fold's class counts and the exact denominator for every metric.
  • Report macro averages over metrics defined for one-class folds, plus pooled patient-level confusion counts.
  • Replace MDI-only ranking with grouped permutation tests and nested leave-group-out retraining.
  • Separate obstructive, hypopneic, central, and mixed events instead of pooling them.
  • Repeat across homes, mattress types, body positions, and co-sleeping conditions.

The Random Forest and LightGBM pages explain the two nonlinear model families behind the result. The broader lesson is about clinical metrics: before admiring an average, count who was mathematically able to enter it.

References

  1. Israel Campero Jurado, Zoe Bousraou, Lara Benning, Sara Padilla Neira, Alexander Breuss, Robert Riener, Esther Irene Schwarz, Elisabeth Wilhelm (2026). Spectral Features Dominate BCG Respiratory-Event Detection: A Large-Scale Patient-Independent Comparison of Feature Groups in Sleep Apnea Patients. Biomedical Signal Processing and Control; arXiv preprint
  2. Leo Breiman (2001). Random Forests. Machine Learning 45