Here is the finalized, submission-ready project description, perfectly formatted using standard Markdown and properly rendered LaTeX for the math components.InspirationRight now, baseball teams rely on radar guns and post-game soreness to guess when a pitcher is fatiguing. But by the time a player complains of a "dead arm," the structural damage is already compounding.Approaching this strictly as an engineering problem, we realized that predicting an elbow blowout (like a UCL tear) is structurally the exact same challenge as detecting early cardiac arrhythmia in an ECG. Both rely on isolating a multi-channel time-series signal and spotting the instability riding on top of a normal baseline. Pitchers mask fatigue through micro-compensations; we wanted to build a system that catches those mechanical warning signs before a ligament actually snaps.What it doesKineSignal is an early-warning biomechanical pipeline that predicts structural pitching injuries. It ingests open-source Statcast data (release point, velocity, spin rate, extension) and treats a pitcher's mechanics as a multi-channel signal.Instead of looking at basic averages, KineSignal evaluates personalized mechanical degradation by separating two distinct variables:Jitter (High-Frequency): Pitch-to-pitch micro-compensations (often indicating blister pain or grip changes).Drift (Low-Frequency): The slow, systemic decay in arm slot and stride extension that signals catastrophic elbow/shoulder fatigue.By scoring these deviations against a pitcher's own early-season baseline, KineSignal flags outings as STABLE, WATCH, or ELEVATED weeks before an injury occurs.How we built itThe core backend is built in Python and served via a dynamically configurable FastAPI endpoint. We utilize pybaseball to pull pitch-by-pitch Statcast data.To process the data, we implemented a Discrete Wavelet Transform (DWT). We used a Daubechies 4 (db4) wavelet to separate the signal into approximation (drift) and detail (jitter) coefficients. To prevent single-outing variance from creating false positives, we utilize a Median Absolute Deviation (MAD) for robust, small-sample baselining.The composite risk score is calculated via a clinically weighted matrix:$$\text{Risk Score} = \sum_{i} \left( \frac{X_i - \tilde{X}{\text{base}}}{\text{MAD}(X{\text{base}})} \right) \times W_i$$Where $X_i$ is the current outing's feature value, $\tilde{X}_{\text{base}}$ is the pitcher's baseline median, and $W_i$ represents the biomechanical weight [^1].Core Feature WeightsFeature VariableSignal TypeClinical RelevanceWeight (Wi)release_extensionDriftLeg/Core fatigue (stride decay)0.25release_pos_zDriftShoulder fatigue (dropping slot)0.15release_pos_xJitterLateral trunk tilt compensation0.15release_speedDriftSystemic muscular fatigue0.10Challenges we ran intoWe hit two massive roadblocks when transitioning from synthetic validation to real, messy MLB data:The "Short Outing" Blindspot: When backtesting against Shohei Ohtani's 2023 UCL tear, the model completely zeroed out on the day he got hurt. Because he left the game after 26 pitches, we didn't have the required 8-pitch minimum to run the db4 wavelet. We solved this by building cross-outing rolling memory buffers—stitching a pitcher's short outing to their previous start to preserve the cumulative fatigue signal, while adaptively downgrading to a db2 wavelet for smaller samples.The Jitter vs. Drift Paradox: Initially, we only extracted the high-frequency jitter. This brilliantly caught Ohtani's blister issues in June, but completely missed his UCL tear in August. We realized that tissue fatigue doesn't make a pitcher erratic; it makes them lazy (shorter strides, dropping slots). We had to rewrite the feature extractor to capture and heavily weight low-frequency drift to catch dead-arm fatigue.Accomplishments that we're proud ofValidating against ground truth: We successfully backtested KineSignal against historical injury data, proving that the model's smoothed risk score consistently breaches the WATCH and ELEVATED thresholds weeks before documented UCL failures.Co-channel phase alignment: We successfully engineered the pipeline to compute wavelets per pitch type before aggregating them. This ensures the model doesn't falsely flag a pitcher as "mechanically erratic" just because they threw more sliders (which have a naturally different release point) in a given inning.Dynamic configuration: We decoupled the risk thresholds and feature weights from the core logic, allowing end-users to tweak the pipeline's sensitivity dynamically via API query parameters:JSON{ "watch_threshold": 1.50, "elevated_threshold": 2.75, "buffer_size": 15 } What we learnedMathematical theory must bend to biological reality. We learned that fatigue is cumulative; a pitcher's arm does not magically reset to a 0% fatigue state the moment a game ends. Treating each game as an isolated mathematical island was biologically flawed, which fundamentally changed how we structured our data ingestion and memory arrays.What's next for KineSignalFrontend Dashboard: Building a React-based UI to visualize the dual-axis trend lines (Smoothed Risk vs. Time) for at-a-glance decision support.Cohort Calibration: Scaling our backtesting across a much larger cohort of healthy and injured pitchers to perfectly dial in the default WATCH and ELEVATED thresholds.Contextual Weather Shifts: Implementing a localized weather-adjustment to our baselines, ensuring the natural velocity climb from April to July isn't misinterpreted by the model.
Log in or sign up for Devpost to join the conversation.