Prompt
How do I set up a recovery scoring engine for measuring engagement and trend changes from wearable data?
Latest observation
Here’s a practical way to set up a recovery scoring engine for wearable data that measures engagement and trend changes over time.
1) Define what “recovery” means
First decide what your score should represent. Common components are:
- Physiological recovery: sleep quality, resting heart rate, HRV, respiration, temperature deviation
- Activity recovery: strain, steps, training load, time inactive
- Behavioral recovery: consistency of sleep/wake times, late-night activity, alcohol proxies, etc.
- Engagement: how often the user wears the device, syncs data, responds to nudges, and data completeness
A good recovery engine usually produces:
- Daily recovery score
- Confidence score based on data availability/quality
- Trend score showing change over days/weeks
- Engagement score showing whether the data is reliable and the user is active
2) Choose input signals
Typical wearable inputs:
Core signals
- HRV: nightly average, RMSSD, SDNN, or device-specific metric
- Resting heart rate
- Sleep duration
- Sleep efficiency
- Sleep timing consistency
- Respiration rate
- Skin temperature deviation
- Activity / strain / training load
- Steps
- Idle time / sedentary time
Optional signals
- Menstrual cycle data
- Subjective readiness / soreness / stress
- Alcohol, caffeine, illness flags
- Work schedule / travel / time zone changes
3) Clean and normalize the data
Wearable data is noisy and missing often, so this is critical.
Data cleaning steps
- Remove impossible values
- Handle missing data with:
- forward-fill only where appropriate
- rolling averages
- imputation flags
- Align data to a daily window, usually based on sleep night or calendar day
- Detect outliers using robust methods like:
- z-score on rolling baseline
- median absolute deviation
- percent-change thresholds
Normalization
Because people differ a lot, use personal baselines:
- 7-day baseline for short-term changes
- 28-day baseline for stable recovery patterns
- Z-score, percentile, or min-max relative to personal history
Example:
- Higher HRV than baseline = better
- Lower resting HR than baseline = better
- Longer sleep than baseline = better
- Higher strain than baseline = worse
4) Build a feature layer
Create engineered features from raw wearable data.
Example features
For each day:
hrv_pct_change_vs_28d_baselinerhr_pct_change_vs_7d_baselinesleep_duration_delta_vs_baselinesleep_efficiencystrain_last_24hsteps_last_24hsleep_debt_7dsleep_timing_variance_14dtemp_deviationdata_completeness_pctwear_time_hours
Trend features
To detect changes over time:
- 3-day rolling average
- 7-day rolling average
- slope over last 7/14/28 days
- exponentially weighted moving average
- change-point detection
5) Create the recovery score
You can start with a weighted composite score before moving to ML.
Simple formula
Normalize each feature to 0–1 or 0–100, then combine:
Recovery Score =
0.30 * HRV_score
+ 0.20 * Sleep_score
+ 0.20 * RestingHR_score
+ 0.15 * Strain_recovery_score
+ 0.10 * Respiration_temp_score
+ 0.05 * Consistency_score
Scoring direction
- HRV: higher is better
- Resting HR: lower is better
- Sleep duration/efficiency: higher is better up to a point
- Strain: lower after heavy load may indicate recovery issues
- Temperature deviation: too far from baseline may indicate illness or stress
Practical scaling
Map each feature against baseline:
- 100 = very favorable vs baseline
- 50 = near baseline
- 0 = significantly worse than baseline
Example for HRV:
score = 50 + 10 * z_hrv- cap at 0 and 100
6) Add confidence and engagement scoring
A recovery score is only useful if you know how trustworthy it is.
Engagement score
Measure user/device participation:
- wear time today
- sync frequency
- percent days with valid data in last 7/30 days
- response rate to prompts or check-ins
Example:
Engagement Score =
0.40 * wear_time_score
+ 0.30 * sync_score
+ 0.20 * recent_data_completeness
+ 0.10 * check_in_response_rate
Confidence score
This estimates how reliable the recovery score is:
- missing key signals?
- partial night data?
- unusual gaps?
- too little personal history?
Example:
- 0–100 confidence
- lower confidence when sleep or HRV missing
- lower confidence if user history < 14 days
You can then display:
- Recovery: 78
- Confidence: High
- Engagement: 92
7) Detect trend changes
You want to know when recovery is improving or worsening.
Methods
A. Rolling trend
Compare averages:
- 7-day average vs previous 7-day average
- 14-day slope
- 28-day trend line
B. Change-point detection
Identify abrupt shifts:
- CUSUM
- Bayesian change point detection
- ruptures library methods
- EWMA control charts
C. Baseline drift detection
Track whether the user’s normal state changes:
- sustained HRV drop
- sustained RHR increase
- reduced sleep consistency for > 1 week
Example trend labels
- Improving
- Stable
- Declining
- Volatile
- Insufficient data
8) Consider labels if you want ML
If you want a smarter engine, train a model to predict recovery or readiness using outcomes like:
- self-reported readiness
- next-day performance
- illness onset
- training quality
- soreness/fatigue score
Possible models
- Logistic regression for interpretable classification
- Random forest / XGBoost for stronger tabular performance
- Time-series models for sequence patterns
- Bayesian hierarchical models for personalized baselines
Important
Even with ML, keep:
- explainability
- per-user baselines
- confidence estimates
9) Recommended architecture
A simple production setup:
Data pipeline
- Ingest wearable API data
- Validate and clean
- Aggregate into daily records
- Compute baselines and features
- Score recovery
- Score engagement/confidence
- Detect trends and anomalies
- Store results and expose via API/dashboard
Storage tables
raw_sensor_eventsdaily_metricsuser_baselinesrecovery_scoresengagement_scorestrend_events
10) Example scoring logic
A practical starting point:
Step 1: compute feature sub-scores
- HRV subscore
- Sleep subscore
- RHR subscore
- Load subscore
- Consistency subscore
Step 2: weight them
recovery = 0.3*hrv + 0.25*sleep + 0.2*rhr + 0.15*load + 0.1*consistency
Step 3: adjust by confidence
final_recovery = recovery * confidence_factor
Where confidence factor might be:
- 1.0 for high quality data
- 0.8 for moderate quality
- 0.5 for poor quality
Step 4: classify
- 80–100: strong recovery
- 60–79: moderate
- 40–59: low
- <40: poor
11) Validate the engine
Test whether the score is useful.
Evaluate against outcomes
- Does it correlate with self-reported readiness?
- Can it predict bad days, illness, or poor training response?
- Is it stable when the user is healthy?
- Does it detect recovery improvement after rest?
Metrics
- correlation with labels
- AUC for classification
- calibration
- test-retest reliability
- false alert rate
12) Start simple, then iterate
Best practice:
- Start with a rule-based weighted model
- Add confidence and engagement scoring
- Add trend detection
- Personalize weights per user
- Optionally train ML model from labeled outcomes
Example pseudo-implementation
def compute_daily_recovery(user_id, day_data, baseline):
hrv_score = score_higher_better(day_data["hrv"], baseline["hrv"])
sleep_score = score_sleep(day_data["sleep_duration"], day_data["sleep_efficiency"], baseline)
rhr_score = score_lower_better(day_data["rhr"], baseline["rhr"])
load_score = score_lower_better(day_data["strain"], baseline["strain"])
consistency_score = score_consistency(day_data["sleep_variance"], baseline["sleep_variance"])
raw_recovery = (
0.30 * hrv_score +
0.25 * sleep_score +
0.20 * rhr_score +
0.15 * load_score +
0.10 * consistency_score
)
confidence = compute_confidence(day_data)
engagement = compute_engagement(day_data)
final_recovery = raw_recovery * confidence / 100.0
trend = compute_trend(user_id)
return {
"recovery_score": round(final_recovery, 1),
"confidence": round(confidence, 1),
"engagement": round(engagement, 1),
"trend": trend
}
If you want, I can also help you with:
- a database schema
- a Python scoring implementation
- a feature list for HRV/sleep/recovery
- or a full ML design for personalized recovery prediction