Machine Learning · CSCI 4622
Running Form Analyzer
A computer-vision pipeline that watches a runner from the side, tracks 33 body keypoints in real time, and learns to flag form faults like overstriding and excessive trunk lean.
Why I built it
I'm a marathon runner with a history of recurring injuries, and I've learned firsthand that subtle differences in mechanics, like overstriding, heavy heel striking, or poor trunk lean, are major contributors to injury risk. Most runners have no easy way to get objective feedback on their form. I wanted a tool where anyone could point a camera at themselves and get an honest read on what their body is actually doing.
How it works
The system is a full pipeline from raw webcam video to a trained classifier:
- Pose estimation. MediaPipe's pose landmarker pulls 33 body keypoints from each frame of side-view video.
- Feature engineering. Four form-relevant features are computed per frame: knee angle, trunk lean, foot offset, and cadence (steps per minute).
- Confidence gating. Per-landmark visibility is checked before any metric is trusted. A green/red border tells you at a glance whether the current frame is usable.
- Labeled data collection. Bulk CSV recording stamps a form label (good, overstride, or excessive lean) onto every row, optionally baking an overlay MP4 alongside it.
- Classification. A random-forest classifier trains on the labeled frames and reports per-class precision, recall, F1, a confusion matrix, and feature importances.
The interesting part: how I evaluated it
The first model looked incredible: a stratified 80/20 split over all rows hit 99.7% accuracy. That number is a trap. With only a handful of recording sessions per label, a random row split leaks session identity into the test set, so the model quietly learns "which video is this" rather than "what form is this."
Re-running with leave-one-session-out cross-validation (holding out an entire session at a time) told the real story: accuracy fell to ~44%. excessive lean stayed cleanly separable because trunk posture is a stable, robust signal, but good and overstride were nearly indistinguishable.
| Evaluation protocol | Accuracy | overstride F1 | excessive lean F1 |
|---|---|---|---|
| Naive 80/20 row split | 99.7% | n/a | n/a |
| Leave-one-session-out (v1 data) | 43.5% | 0.11 | 0.86 |
| Leave-one-session-out (v2 data) | 47.0% | 0.43 | 0.50 |
I diagnosed the failure: the foot_offset feature was
averaged across the whole gait cycle, but the foot swings forward
and backward every stride, so its per-session mean sits near
zero regardless of overstriding. The real overstride signal lives at
the instant of foot contact, and averaging erased it.
The single biggest improvement came not from a fancier model or cleverer features, but from better data collection. Re-recording with more deliberate form and cleaner camera setups lifted overstride F1 from 0.11 to 0.43, a ~4× gain with no change to the algorithm at all.
What I took away
- Session-level cross-validation is non-negotiable with few sessions: a row-level split overstated true accuracy by 50+ points.
- Aggregating across a signal cycle can destroy the very phase-specific information that separates the classes you care about.
- Data quality beats feature engineering at this scale: the cleanest dataset outperformed every model and feature change layered on top of it.
- "Combine everything" isn't free. Correlated features increased a small-data random forest's variance without adding information. The bias-variance tradeoff, observed in the wild.
Where it's headed
Next steps are more sessions per class to stabilize the cross-validation variance, a proper streaming foot-strike detector for genuine real-time feedback, and a comparison against a small neural network. The end goal is unchanged: point a camera at any runner and hand them feedback worth acting on.
Timeline
-
March 1, 2026
Started
Set out to build an objective running-form feedback tool after years of overuse injuries from training.
-
March 8, 2026
First working pipeline
MediaPipe pose tracking, the four engineered features, and confidence gating all working end to end; began recording and labeling sessions.
-
March 15, 2026
Caught the evaluation trap
A naive 80/20 split showed a misleading 99.7% accuracy; switching to leave-one-session-out cross-validation revealed the real number, ~44%.
-
March 22, 2026
Data-quality breakthrough
Re-recorded with more deliberate form and cleaner setups; overstride F1 jumped ~4× with no change to the model itself.
-
March 29, 2026
Current state
Pipeline complete and evaluated end to end; next up is a streaming foot-strike detector and a small neural-net comparison.