COURTDNA

How It Works

How COURT DNA works

Data source

Player-season statistics from Basketball-Reference.com, NBA regular seasons 1996-97 through 2025-26. COURT DNA begins with the 1996-97 season, the starting point for the historical advanced-stat coverage used by this model; it is not an all-time NBA history. ABA/BAA-era leagues are excluded — they ceased to exist decades before this window, so no non-NBA rows appear in the dataset at all. Six primary tables are combined: Advanced, Per 100 Possessions, Player Shooting, Player Per Game, Player Season Info, and Player Career Info.

Canonical player-season rule

A player traded mid-season appears in the raw data as an aggregate row (team code “2TM”, “3TM”, etc.) plus one row per individual team. COURT DNA uses the aggregate row as that player’s single canonical full-season statistical profile whenever one exists; the individual team rows are kept separately only to show which teams a player suited up for that season, never re-used in the statistical calculation. This produces exactly one profile per (player, season) — verified automatically for every one of … canonical player-seasons.

Qualification thresholds

  • Comparison / Player Map pool: at least 500 minutes and 20 games in the season.
  • Player detail / career display: at least 250 minutes — below the comparison bar, a season still gets a detail page but is visibly flagged “small sample” and is never used as a candidate in someone else’s closest matches.
  • The same thresholds apply to every season, including the lockout-shortened 1998-99 season, which therefore has a smaller qualified pool.

Features and season-relative normalization

League environments changed substantially between 1996-97 and 2025-26 — three-point rate alone roughly tripled. Every similarity feature is therefore winsorized at the 1st/99th percentile and standardized (z-scored) within its own season, against that season’s qualified pool only — never against the full multi-season history. A player is only ever compared to how unusual their number was in their own league environment. This measures playing-style similarity, not equal quality, and raw values from different eras are not necessarily directly comparable — shot-distance levels in particular shift around 1999-00 / 2000-01, which season-relative standardization is designed to absorb.

Similarity formula

Six feature groups, each divided evenly across its listed features:

Feature groups, their weights and the features in each
GroupWeightFeatures
Scoring load20%pts_per_100_poss, usg_percent
Efficiency10%ts_percent
Shot profile25%f_tr, avg_dist_fga, percent_fga_from_x0_3_range, percent_fga_from_x3p_range
Playmaking / turnover style20%ast_percent, tov_percent
Rebounding10%trb_percent
Defensive activity15%stl_percent, blk_percent

A weighted RMS distance is calculated between two players’ standardized vectors, then converted to a 0–100 Similarity Index: Similarity Index = max(0, 100 − 20 × weighted_RMS_distance). A score of 91 means 91/100 on this project’s statistical similarity index — not a 91% probability that two players are alike. Awards, popularity, Hall of Fame status, draft position, names, and team reputation never factor into this calculation.

Explain the match

Every comparison’s “where they match” and “where they separate” language comes from fixed templates selected by which features have the smallest or largest weighted gap between two players’ vectors — never from a language model or invented narrative. No causal explanation (coaching, injury, role change, effort) is ever generated; only what the numbers show.

Traits and archetypes

Seven percentile trait dimensions (Scoring, Efficiency, Playmaking, Rebounding, Defensive Activity, Rim Pressure, Perimeter Profile) are each a weighted average of standardized features, converted to a season-relative percentile. Archetypes are assigned by an ordered set of deterministic rules against those percentiles plus a coarse position group (Guard/Wing/Big) — never by text generation. A “Balanced [Position]” fallback applies when no specific rule matches.

Court Print

The signature graphic is a direct visualization of the seven trait percentiles above: seven spokes at fixed angles, each spoke’s length equal to that dimension’s percentile, connected by a smooth curve. Nothing about its shape is random or decorative.

Shooting Profile

A half-court of distance zones: 0–3 ft, 3–10 ft, 10–16 ft, 16 ft to the three-point line, three-pointers, and (where shot locations exist) deep threes, meaning three-point attempts 30 feet or more from the basket. Hover or focus a zone for its makes, attempts and shooting %; click to keep it selected. For every regular season from 1996–97 on, counts come from each recorded shot’s location (a stats.nba.com shot-chart dataset matched to Basketball-Reference players); “Show shots” plots them. A season without shot locations falls back to Basketball-Reference’s distance-range shares with estimated counts and no deep-three split. Shot locations do not affect any similarity score. Details: the “About this data” note under the court.

Player Map and PCA

The Player Map plots each season’s qualified pool in 2D using deterministic PCA (fixed random state) on the same standardized features used everywhere else. This is for visualization only — proximity in the 2D projection is approximate, and the app’s actual similarity rankings always use the full 12-dimensional formula above, never 2D distance.

How lineup scores are calculated

In Build a Lineup, each of the six scores is the plain average, across the selected players, of that stat for the season you chose. Five are trait percentiles from 0 to 100, each measured against the other qualified players in the same season: Passing & Creation, Three-Point Shooting, Attacking the Basket, Rebounding and Defensive box-score signals (built from steals and blocks only, not defensive rebounds or complete defensive impact). “How Much They Handle the Ball” comes from the usage rate, standardized within its season and turned into a 0 to 100 value.

  • Positions don’t affect scores. PG, SG, SF, PF and C only help you arrange the lineup. Moving or swapping the same player-seasons gives the same scores.
  • Missing stats. If a selected player-season has no value for a stat, that score shows “Unavailable”. It is never counted as zero and never averaged without that player.
  • Small samples. A season with fewer than 500 minutes or 20 games (but at least 250 minutes) is labeled “Small sample”. It is averaged like any other season, but its stats come from limited playing time and may be less reliable. Its percentiles are measured against that season’s qualified players, which it did not help set.
  • Not a prediction. The scores describe combined playing style from past statistics. They aren’t used to predict wins, and the observations are simple notes triggered by fixed thresholds on these stats. The Simulate panel uses a separate model (see below).

Simulate and season honors

  • What it does. Simulate uses what players did over a completed season to estimate how a hypothetical team would have done: an 82-game season, a seven-game series, or a historical playoff bracket (1996–97 to 2025–26). It is not a preseason forecast. It uses a separate model fitted to real team results, not the six scores above. In a bracket replay, series that really happened keep their real host; a new matchup is hosted by the team with the better regular-season record, then by the team that won an uneven season series, and otherwise by a labelled assumption you can change (default: better point differential, which is not an official NBA rule). Seeds are published seeds, shown for display only.
  • Assumptions. Each starter plays standard minutes, the rest go to an average bench, coaching is average and everyone is healthy. Five players share one ball, so shot volume is scaled down. The schedule is a balanced hypothetical one. Positions never change a result.
  • Support check. Before showing numbers, Simulate asks whether the lineup resembles real teams the model was fitted on. If it is too different, you see the assessment but no wins, series odds or title odds, with the message “This lineup is too different from the teams used to test the model.” Being inside the range of real teams doesn’t prove a custom lineup is accurately estimated. Small samples and lineups that mix distant eras are flagged as limited.
  • How reliable. On real teams the 82-game estimate beat last season’s record. For a custom five plus an average bench it did not (RMSE 10.50 against 10.12 on the newest test seasons), so treat it as rough. Series and bracket results are always Experimental. Expected defensive rating isn’t shown because testing found it too weak; the “Defensive box-score signals” are rebounds, steals and blocks, not measured defense.
  • Two kinds of uncertainty. Game luck is what a season or series can swing by chance; more simulated runs settle it. Model uncertainty is how far the model can be off; more runs never remove it. No 80% claim is made for custom lineups.
  • Season honors. Awards for the selected season only, from published winner lists, plus championship membership (“appeared in a playoff game for the champion”). Voting placements aren’t wins. Finals MVP and the 2025–26 awards are confirmed by more than one source; awards for earlier seasons come from one source. Full championship rosters aren’t available, so only Finals MVP winners show “On the championship roster”. Honors are never used in similarity, scores or simulations.

Limitations

These comparisons use recorded statistics. They miss off-ball impact and much of defense. A high Similarity Index means the measured profiles are close; it does not establish equal ability or identical playing styles.

What data is used, and what is missing?
  • Source and coverage: Basketball-Reference season statistics (via a public Kaggle dataset), regular season only, 1996–97 to the present. The 12 similarity features are the same for every player-season in that range.
  • Shooting Profile: shows distance zones (0–3, 3–10, 10–16, 16 ft–3PT, 3PT, and deep threes of 30+ ft where locations exist). Real shot locations (regular season) exist for every season from 1996–97 on; any season without them shows distance zones with estimated makes and attempts.
  • Not measured: screening, spacing gravity, communication, off-ball movement, and most defense. Steals, blocks and rebounds capture only part of defensive activity.
  • Not included: playoff shot locations, hustle statistics, play types and defensive tracking. These were not integrated in this version, so they do not affect any score and there is no “detailed comparison” mode.
  • Statistical closeness is not causation and does not show that two players have equal ability or play alike.
  • Box-score and rate statistics cannot capture every part of basketball performance — screening, spacing gravity, communication, and other off-ball value are not measured here.
  • Steals and blocks are the only defensive box-score signals available; they are an incomplete measure of defensive activity, not a complete one.
  • Correlation in a statistical profile is not causation, and a high Similarity Index is not a claim that two players play alike in ways beyond what these specific features measure.
  • Player photos are sourced only from Wikimedia Commons with verified license metadata; most players use a fallback graphic rather than a guessed or unverified image — see Photo Credits.