HowSelf-supervised representation learning
CourtStyle
Discovers playing styles no one labelled.
- 3 + 4serve and rally styles discovered without any style label
- 0.748mean LLM-judge score of generated coach notes; 32 of 42 pass the rubric
- 7 matchesheld out; the style ranking is preserved on all of them
Overview
The problem
Playing style lives in accumulated behaviour: hundreds of points per match, tens of thousands per season. Analyses usually fix their descriptors in advance and let the analyst or a supervised target define the groups, so what they find follows the chosen variables. What they deliver is a table of statistics that coaches must decode themselves.
What was missing
For racket-sport match records, learning a representation of style without style supervision was little studied. Contrastive learning raises a further question: a representation that separates records may capture which player it is rather than how that player behaves.
Architecture
Swipe to see the whole diagram →
Technical details
- Serve data: 1,273 server–match records (926 matches, 87 players) from public US Open and Wimbledon statistics, 2016–2024; 41 raw columns reduced to 29. Held-out set: 42 Australian Open 2017 instances with coach notes.
- Rally data: Roland-Garros 2021 Hawk-Eye logs supplied by the FFT, 31 matches, 7,059 rallies; 93-d tokens from 31 shot variables (current shot, next shot, difference); match-level split with 7 held-out matches.
- Serve encoder: one token per column with a learned column-identity embedding, a [CLS] token, four blocks of gated multi-head attention and SwiGLU, manifold-constrained hyper-connections, no positional encoding.
- Rally encoder: one token per shot transition, sinusoidal positions, four pre-norm Transformer blocks, [CLS] pooling.
- Every solution is checked with silhouette, modularity and seed stability, and against rally length, match identity and point outcome, so the groups do not merely follow those variables.
- Of three locally hosted open-weight models, Qwen 2.5 32B was the only one that satisfied every constraint, within two generations.
What I built
- 01
One discovery protocol, two record types
Serve statistics as tabular records and rallies as ordered shot transitions, each with an encoder whose attention axis matches its structure.
- 02
Contrastive training without style labels
MoCo v3 with feature-corruption views for serves (pre-trained on 50k synthetic records, then real); SimCLR with an order-repulsion term for rallies, so shot order cannot be ignored.
- 03
Graph and centroid discovery
Leiden communities on a cosine k-NN graph for serves; K-Means for rallies, where rally-length gradients would fragment a graph.
- 04
Evidence-grounded reports
Qwen 2.5 32B receives only identified, measured statements, must cite them, and is validated and re-prompted when a check fails.
Main results
| Community | Count | Style | Key serve profile | Key outcomes |
|---|---|---|---|---|
| C0 | 484 | Low-pace Body-spread | Avg speed −0.92, Body share +0.35, Width var. +0.39 | Aces −0.45, 1st-serve pts won −0.16, Break pts faced +0.19, Break pts saved +0.10 |
| C1 | 514 | Mid-pace Wide-mix low-dispersion | Avg speed +0.23, Wide share +0.20, Width var. −0.24 | Aces +0.17, Double faults +0.06, 1st-serve pts won +0.03, Break pts faced −0.02, Break pts saved +0.00 |
| C2 | 275 | High-pace T-precision | Avg speed +1.19, 1st-serve speed var. −0.82, T share +0.45, Min 1st +0.88 | Aces +0.47, 1st-serve pts won +0.23, 2nd-serve pts won −0.19, Break pts faced −0.28, Break pts saved −0.19 |
| Community | Count | Style | Key rally profile | Key outcomes |
|---|---|---|---|---|
| C0 | 1,809 | Mid-Entry Groundstroke | Groundstroke +0.07, Rally shot +0.07, Serve stroke −0.05, Shot duration −0.04 | Rally length +0.11, Duration +0.09, Played rate +0.02, Fault rate −0.00 |
| C1 | 1,261 | Mid-Entry High-Move | Response speed −0.13, Player distance Δ +0.09, Response duration +0.13, Opponent depth +0.09, Serve stroke +0.08 | Rally length −0.13, Duration −0.10, Break pts −0.06, Played rate +0.01 |
| C2 | 1,193 | Fast-Entry Decelerating | Shot speed +0.16, Backspin +0.19, Topspin −0.19, Serve stroke +0.12, Speed Δ −0.13, Spin rate Δ +0.11 | Fault rate +0.16, Played rate −0.22, Rally length −0.19, Duration −0.18 |
| C3 | 1,330 | Slow-Entry Extended | Topspin +0.14, Spin rate +0.13, Speed Δ +0.09, Response speed +0.09, Backspin −0.10, Serve stroke −0.07 | Played rate +0.16, Fault rate −0.15, Rally length +0.15, Duration +0.14, Break pts +0.08 |


Qualitative results



Demo
Limits and next steps
Results hold at the level of the record: a serve style groups server–match records and a rally style groups rallies, so neither yet shows that a player holds a stable style. Report evaluation measures agreement with coach references, not usefulness in match preparation. Next: player-level aggregation tested against a permutation null, and a study with practising coaches.
Beyond this project
Self-supervised discovery in any event log without labels, with language-model summaries constrained to measured evidence.
Research output
Paper
CourtStyle: Unified Self-Supervised Framework for Tennis Playing Style Discovery
Ahmed Jouini, Faten Chaieb-Chakchouk, Alex Loth
KES 2026, Procedia Computer Science, Elsevier
Proceedings forthcoming.
Contact
Interested in the work?
I'm looking for AI research engineer roles in computer vision and video understanding, ideally in sports analytics, though not only. Ready to start a new journey.
Paris, France