The Framework

HOW APEX WORKS

APEX blends five independently weighted pillars into one 0–100 score. Each pillar captures a distinct dimension of player value. None can be derived from the others.

Offensive Impact
O-EPM · O-LEBRON · OBPM
32%
Shot Quality
Rel TS+ · USG% (interaction)
14%
Defensive Impact
D-LEBRON · D-EPM · DBPM
28%
Creation & Playmaking
AST% · AST/TOV · invTOV · FTA/FGA
16%
Physical Contribution
REB%
10%

K-means archetype normalization (v3.0): Shot Quality, Creation & Playmaking, and Physical Contribution z-scored within 8 data-driven peer groups. Defensive Impact retains BBall-Index defRole grouping. Offensive Impact is full-pool. GP^0.75 availability curve and NOI/CV consistency modifier (±5% cap) applied. DWS, STL%, BLK% removed in v1.7 (Jewell et al., JQAS — null significance at high minutes loads).

Process

THREE STEPS

01
Collect
Raw metrics from Basketball-Reference (scraped), BBall-Index (O-LEBRON, D-LEBRON, Relative TS+), and Dunks & Threes (O-EPM, D-EPM). 12 scored metrics across five independent pillars.
02
Normalize
Shot Quality, Creation & Playmaking, and Physical Contribution z-scored within K-means archetype peer groups (8 clusters). Defensive Impact within BBall-Index defRole groups. Offensive Impact full-pool. Clamped at ±3.5 standard deviations. Scaled to 0–100. Era-neutral by construction.
03
Score
Weighted across five pillars. GP^0.75 availability curve applied. USG-efficiency interaction penalizes high-volume, low-efficiency seasons.
Changelog

VERSION HISTORY

VersionChanges & Rationale
v4.5
  • Lab expansion — five new tools: Movers & Shakers (lab/movers/), Statistical Twinsies (lab/twinsies/), Goldfish Tank (lab/goldfish/), Team Picker (lab/team-picker/), 6 Degrees of NBA Separation (lab/six-degrees/)
  • Twinsies similarity metric corrected from cosine to Euclidean distance (normalized by observed pillar ranges across all 10 seasons) — eliminates fringe player matches
  • Goldfish Tank: ceiling vs. floor scatter across 516 career dots; four quadrant split at median floor/ceiling; concept credited to r/nbadiscussion
  • 6 Degrees: BFS shortest-chain search across 1,451 players and 64,570 teammate pairs from 2015-16 through 2024-25; max 6 hops; puzzle section with pre-set challenges
  • Morning Briefing (/briefing/) — daily NBA digest generated at 7 AM ET via Netlify Scheduled Function; fetches ESPN scores, NBA headlines, and podcast drops; stored as dated JSON blobs; archive at /briefing/archive/

Lab expansion adds exploratory tools that use the multi-season dataset without modifying the scoring engine. Six Degrees surfaces the team-context web that partially explains APEX's on/off metric limitations. Morning Briefing provides daily utility alongside the static reference content.

v4.4
  • Site-wide audit: legibility fixes across multiple pages; typography and table header color corrections
  • Player Profiles hub rewritten — static 4-card grid replaced with season selector dropdown and dynamic top-10 grid; engine loaded dynamically to avoid const PLAYERS global collision; ?season=YYYY-YY URL param; defaults to 2024–25

Player hub now reflects all 10 seasons rather than hardcoding four profiles, making the section useful for any historical lookup rather than just current stars.

v4.3
  • Nickname Grader lab tool added (lab/nickname-grader/): 22 player nickname pages + hub with grade filter
  • Each nickname audited across 4 rubric categories (Literal Accuracy, APEX Confirmation, Proportionality, Originality); grades S through F
  • APEX-specific irony angles documented (e.g. STL% removal makes Grand Theft Alvarado invisible; FTA/FGA scoring makes Free Throw Merchant accidentally analytical)

Nicknames make implicit analytical claims. Testing them against the model surfaces APEX's own blind spots — Stifle Tower gets a B because deterrence is unscored; The Process gets a C because Embiid never reached #1 under a model that values availability.

v4.2
  • 10-season expansion: 2015-16 through 2024-25 — six new seasons added (2015-16, 2016-17, 2017-18, 2018-19, 2019-20, 2020-21)
  • COVID seasons use proportional minute thresholds (2020-21: 878 min / 72 games; 2019-20: 793 min / 65 games)
  • rankings.html hub expanded to 10-card 3×3 grid; nav Rankings dropdown updated to list all 10 seasons
  • Notable divergences: 2015-16 (Kawhi #1, Curry wins unanimous MVP); 2016-17 (Draymond #1, Westbrook wins)

Ten years of data turns APEX from a single-season snapshot into a longitudinal record. The 2015-16 and 2016-17 divergences are the most analytically significant: both trace directly to the model's deliberate exclusion of win-total and counting-stats narrative from the scoring engine.

v4.1
  • Site-wide design overhaul — light mode (warm white #F7F6F3 background replacing near-black)
  • Five pillar colors redesigned for light-background legibility; all five are genuinely distinct hues
  • Typography: DM Mono removed from all UI contexts; Barlow Condensed 600 for labels/headers, DM Sans + tabular-nums for all numeric data cells
  • Team logos (NBA CDN SVGs) added to all rankings tables; rank #1 in Bebas Neue orange

The dark-mode design was developed before the full player pool and multi-season scope were established. Light mode better suits a reference tool used in reading contexts. Typography overhaul prioritizes data legibility over aesthetic novelty.

v4.0
  • Qualification threshold lowered: ≥1,500 min → ≥1,000 min AND ≥20 GP
  • Pool sizes expand: 2024-25 268 players (was 178); 2023-24 264 (was 219); 2022-23 261 (was 222); 2021-22 270 (was 234)
  • GP^0.75 availability modifier already penalizes low playing time continuously — a binary floor above ~800 min was redundant
  • K-means archetype centroids refit on expanded pools for all four seasons

Other leading models (EPM, LEBRON) qualify at 500–800 min. The 1,500-min floor was excluding injury-shortened starters and legitimate rotation contributors — introducing a selection bias into the normalization pool without any coverage benefit not already provided by the GP^0.75 modifier.

v3.8
  • MVP Case Builder added (lab/mvp-case/): analytical PRO/CON brief for any player + season
  • Lab hub restructured: lab/index.html is now a hub; Model Builder moved to lab/model-builder.html
  • Pillar verdict strip (ELITE/STRONG/AVERAGE/WEAK), algorithmic consensus panel, Vote Signal section, H2H dropdown

The MVP Case Builder surfaces the same analytical reasoning used in backtesting — making it accessible interactively rather than requiring users to read the full backtest table.

v3.7
  • APEX Trend section added to all four player profile pages
  • Dual-axis SVG chart: five pillar lines on left axis + APEX Total on zoomed right axis; interactive column highlights with YoY delta tooltip

Single-season scores lose context without the multi-season arc. Giannis's V-shaped arc (2022-23 low, +13.2 pt recovery in 2023-24) and Embiid's two-season window are both invisible in the rankings table alone.

v3.6
  • Compare page UI redesign: two-column sticky grid, radar chart + player panels side by side
  • Player B color changed to blue (#5B9CF6); dynamic subtitle updates on every render
  • Metric table redesign with pillar section headers and color-coded win highlights

The original vertical-stack layout required excessive scrolling to compare pillar breakdowns. The sticky radar + panels layout keeps the visual comparison in view while the metric table scrolls.

v3.5
  • Divergence page: "How Other Metrics Rank Him" section added — Jokić's rank across APEX, EPM, LEBRON, BPM, WS/48, VORP, PIE for 2021-22 through 2024-25
  • Consensus badge + per-season explanatory text; season switching re-renders dynamically

The MVP-voters comparison shows where APEX diverges from human voters. The algorithmic consensus section shows where APEX aligns or diverges from other analytics models — a distinct and complementary data point.

v3.4
  • Shared APEX card component (player-card.js): renderApexCard() and makeApexPentagonSVG()
  • Pentagon radar SVG centralised; pillar max values encoded as PILLAR_MAX constants
  • Wired into Preference Game and Players hub; CSS injected idempotently

Before v3.4, pentagon radar SVG logic was duplicated across four pages. Centralizing it ensures all card renderings stay in sync as the model evolves.

v3.3
  • Learn > Podcasts section added: hub + 9 individual show pages
  • Live RSS episode feed via shared podcast-feed.js (CORS proxy, 5 most recent episodes, graceful fallback)

Basketball analytics is taught as much through podcasts as papers. Curating the highest-signal shows provides contextual depth alongside the model's numerical outputs.

v3.2
  • Ringer NBA 100 comparison removed from Divergence page (tab UI stripped)
  • Model page version history reversed to descending chronological order
  • Methodology scored/removed metrics tables restructured to 2-column card layout
  • Model Builder: proportional redistribution on pillar sliders (total always = 100%); rank columns sort ascending on first click
  • Player Comparison tool added (lab/compare/): side-by-side pillar breakdown, APEX score delta, full metric table

Proportional redistribution on pillar sliders removes the friction of manually re-balancing weights after every adjustment. The ascending default sort on rank columns reflects that rank 1 is the primary result of interest.

v3.1
  • Learn > Archetypes section added: hub + 8 individual archetype explainer pages
  • Each page covers statistical fingerprint (6 K-means variables), APEX treatment, representative players, within-archetype elite differentiators

K-means archetypes are central to how Shot Quality and Playmaking normalize — publishing the archetype definitions makes the normalization transparent and gives users a vocabulary for understanding why similar-looking players rank differently.

v3.0
  • Pillar restructure: genuinely independent pillars via offensive-only composites
  • Impact pillar renamed Offensive Impact; EPM/LEBRON/BPM replaced with O-EPM (40%), O-LEBRON (35%), OBPM (25%)
  • Defensive Impact weight raised 20% → 28% (corrects prior double-counting suppression)
  • Raw TS% dropped from Shot Quality (already encoded in composites); Rel TS+ raised to 60%
  • FTA/FGA moved from Shot Quality to Creation & Playmaking; TOV% renamed invTOV at 15%
  • Versatility renamed Physical Contribution; weight raised 8% → 10%
  • Backtest accuracy: 25/40 = 62.5% (2 new accepted misses vs. v2.6)

Full two-way EPM, LEBRON, and BPM each internally encode scoring, playmaking, and defense. Using them in an Offensive Impact pillar while independently scoring those same domains caused effective triple-counting of offensive traits (~55% effective offensive weight vs. stated 39%). Switching to offensive-only variants makes each pillar genuinely independent per the Franks et al. (2016) independence criterion. The 2-point accuracy drop is the structural cost of eliminating the architectural flaw.

v2.7
  • Documentation and website overhaul — no model weight changes
  • Version history expanded with explicit rationale per entry; scored metrics section restructured to 5-column format with full academic citations
  • Removed Metrics section added (DWS, STL%, BLK%, DefOnOff, DARKO DPM)
  • Site-wide font legibility improvements via --secondary CSS variable

Transparency requires not just publishing weights but explaining the evidence behind each decision. The removed metrics section addresses a reproducibility gap — readers could not previously verify why specific metrics were excluded.

v2.6
  • Scoring weights: TS% 40%, Rel TS+ 40%, FTA/FGA 10%, USG interaction 10% (was TS% 50%, Rel TS+ 30%)
  • Defense weights: D-LEBRON 47%, D-EPM 43%, DBPM 10% (was 55%, 35%, 10%)
  • Score changes ≤0.3 pts for all players; backtest accuracy 67.5% unchanged

Scoring: Weighting raw TS% above difficulty-adjusted Relative TS+ was internally inconsistent — Rel TS+ specifically corrects for shot selection quality and opponent context that TS% cannot see. Equal weighting reflects equal methodological validity under current literature.
Defense: HoopsHype survey of NBA scouts (2024) rates D-EPM as the most-trusted public defensive metric among non-anchor roles, above D-LEBRON. Narrowing the gap from 55/35 to 47/43 reflects this growing external validation while preserving D-LEBRON's luck-adjustment advantage.

v2.5
  • D-EPM added to Defense pillar from Dunks & Threes
  • Defense weights: D-LEBRON 55%, D-EPM 35%, DBPM 10% (was D-LEBRON 90%, DBPM 10%)
  • D-EPM normalized within BBall-Index defRole groups
  • Backtest accuracy 67.5% unchanged; no top-4 reordering

D-LEBRON is susceptible to team-context inflation for anchor bigs (Gobert, Lopez) — players whose defensive reputation elevates team-level ratings without proportional individual impact. D-EPM's RAPM-based framework is more resistant to this assignment effect (Terner & Franks, 2021). Adding D-EPM reduces dependence on a single defensive estimator without disrupting existing rankings.

v2.4
  • Pipeline fully parameterized with --season flag
  • Historical ranking pages added for 2021-22, 2022-23, 2023-24
  • Rankings hub page introduced
  • Per-season K-means archetype name maps added
  • No model weight changes

Cross-season archives provide the longitudinal context needed to validate APEX accuracy (67.5% backtest) and identify systematic voter divergence patterns. Each season requires independent K-means re-fitting because archetype boundaries shift as the league evolves.

v2.3
  • BBall-Index offRole peer groups replaced with 8 data-driven K-means clusters
  • Cluster features: USG%, TS%, FTA rate, AST%, TOV%, REB% (6 playing-style markers)
  • Scoring, Playmaking, Versatility normalize within K-means groups; Defense retains BBall-Index defRole
  • ROLE_MERGE_MAP removed
  • Resolved: Filipowski Versatility overrating; Barnes/Durant/SGA peer group mismatch

BBall-Index offRole categories had inconsistent granularity — Barnes and Durant shared a group despite radically different playing styles. K-means derives empirically from actual performance markers, not editorial labels. The six-feature cluster space captures the axes most relevant to within-role scoring differences.

v2.2
  • Scoring, Defense, Playmaking, and Versatility z-scored within BBall-Index functional role peer groups (offRole + defRole)
  • Rankings page adds archetype filter pills and role labels
  • Rim-running big overrating from v2.0 resolved

Full-pool z-scoring made rim-running bigs appear elite by comparing their rebounding against perimeter players who structurally do not rebound. Role-based peer groups ensure comparison against players with similar structural responsibilities, isolating quality from role assignment.

v2.1
  • EPM re-integrated via Dunks & Threes scraping (40% of Impact pillar)
  • Impact weights: EPM 40% / LEBRON 35% / BPM 25%
  • Z-score clamp raised ±2.5 → ±3.5 standard deviations

EPM's RAPM-based approach provides more stable estimates than box BPM, particularly for high-usage defensive players. The tighter ±2.5 clamp was compressing genuine multi-sigma outliers (Jokić 2021-22) inappropriately; ±3.5 allows the model to distinguish them from the pack without unbounded inflation.

v2.0
  • Live automated data pipeline replaces hand-curated top-25 player dataset
  • Full 177-player qualified pool (≥1,500 min, ≥20 GP)
  • Impact: LEBRON 65% + BPM 35% (EPM integration deferred pending API access)
  • Defense: D-LEBRON 90% + DBPM 10%
  • Limitation identified: rim-running bigs overrated under full-pool z-scoring due to position concentration effects

Moving to a full qualified pool was essential for competitive rigor — hand-curation introduced selection bias into the normalization pool. The rim-running big limitation surfaced immediately in v2.0 rankings and motivated the v2.2 archetype normalization overhaul.

v1.9
  • Franks et al. (2016, Annals of Applied Statistics) formalized as theoretical basis for five-pillar independence design
  • VORP retained as display-only after ML SHAP analysis confirmed zero marginal contribution to APEX score
  • GP^0.75 availability curve grounded empirically via Deshpande & Jensen (2016)
  • No model weight changes

Documenting academic grounding strengthens reproducibility and clarifies which design decisions are evidence-based vs. heuristic. SHAP evidence for VORP's null contribution justified keeping it off the scoring stack while retaining it for reader familiarity.

v1.8
  • Divergence page added: five-season APEX vs. MVP voter outcomes
  • No model weight changes

Voter divergence analysis provides external validity evidence and surfaces the narrative and availability biases that analytics-based models like APEX do not account for.

v1.7
  • DWS, STL%, BLK% removed from Defense pillar
  • DefOnOff raised 85% → 90% of Defense pillar
  • Playmaking weight: 17% → 19%
  • Versatility weight: 10% → 8% (REB% only retained)
  • AST% retained after live backtest confirmed net positive contribution over removal

Jewell et al. (JQAS) demonstrate null predictive significance for DWS, STL%, and BLK% at high minutes loads — these metrics primarily reflect opportunity and defensive assignment rather than individual impact. DefOnOff compensates. Playmaking increase reflects the underweighting identified in backtest miss analysis. Versatility reduction reflects that rebounding at guard/wing positions is structurally determined by role, not quality.

v1.6
  • USG-efficiency interaction penalty added to Scoring: high-volume seasons with below-average TS% face a multiplier reduction
  • NOI/CV consistency modifier: ±5% cap based on game-to-game variance
  • DefOnOff at 85% of Defense pillar weight
  • Voter-adjusted prediction layer added as a separate display output — does not alter APEX scores

Without the USG-efficiency interaction, volume scorers accumulated high Scoring pillar scores on below-average efficiency. The consistency modifier captures performance variance that season averages mask. The voter-adjusted output was specifically separated from APEX to preserve the model's descriptive integrity.

v1.5
  • Multi-year blending introduced as optional output mode: 60% current / 30% prior / 10% two seasons back
  • DARKO DPM replaces DRAYMOND in Defense pillar

Temporal blending reduces noise in partial or injury-shortened seasons. Optional rather than default to preserve single-season purity for MVP comparison. DARKO DPM offered better stabilization across different defensive role types than DRAYMOND.

v1.4
  • Binary games threshold (≥65 GP required) replaced with GP^0.75 continuous availability curve
  • FTA/FGA (free-throw attempt rate) added to Scoring pillar

The binary threshold created a cliff effect — players one game short of the cutoff received zero credit. The fractional curve produces proportional credit aligned with actual availability (Deshpande & Jensen, 2016). FTA/FGA captures the ability to draw fouls, a repeatable skill that TS% does not directly reward.

v1.3
  • DRAYMOND metric added to Defense pillar
  • Note: subsequently replaced by DARKO DPM in v1.5 after validation issues

First attempt to include a dedicated defensive impact estimator beyond box-score DBPM. DRAYMOND was the most accessible non-box public option at the time but showed instability across small samples.

v1.2
  • Z-scores computed within positional peer groups (PG/SG/SF/PF/C) rather than the full pool

Full-pool scoring structurally penalized guards for low rebounding and centers for low assist rates — positions differ in role, not in quality. Peer-group normalization isolates player impact from positional baselines.

v1.1
  • EPM (Luck-Adjusted Player Ratings) added to Overall Impact
  • Impact weight increased 25% → 33% to reflect stronger predictive validity vs. box-only BPM
  • Z-score normalization introduced, replacing percentile ranking
  • Hand-tuned ceiling removed — normalization supersedes editorial thresholds

EPM adjusts for opponent strength and teammate context that raw BPM ignores. Z-scores provide cross-season comparability on a fixed scale. Removing the ceiling lets the math govern outliers rather than imposing an arbitrary cap.

v1.0
  • Initial five-pillar architecture: Impact, Scoring, Defense, Playmaking, Versatility
  • Box score metrics only: TS%, BPM, AST%, REB%, DBPM
  • Hand-tuned defense ceiling applied above a performance threshold

Establish a working baseline to validate pillar independence before introducing proprietary or scraped metrics. The hand-tuned ceiling was a temporary editorial guard against outlier inflation.

Version numbers track structural changes to the scoring formula. Data refreshes within a version are not separately versioned.