The Approach
We simulate the rest of the NBA season 10,000 times. For each remaining game, an XGBoost model evaluates 26 factors to estimate win probability. We flip a weighted coin, record the result, rank teams using official NBA tiebreaker rules, and repeat. The distribution across all 10,000 simulations tells you how likely each team is to land at each seed.
The model was trained on 11,500+ NBA games across 10 seasons (2015-16 through 2024-25) using leave-one-season-out cross-validation with zero data leakage. Every prediction uses only information available before that game was played.
What Goes Into Each Prediction
The model evaluates 26 features for every game, grouped into seven categories:
| Category | What it captures |
|---|---|
| Form | Recent wins and scoring margin using exponentially weighted averages that prioritize the last few games over early-season results. |
| Home court | Home court advantage is learned by the model from historical data. Altitude effects at Denver and Utah are captured as a separate feature. |
| Matchup | Dean Oliver's Four Factors (eFG%, turnover rate, offensive rebound rate, free throw rate) capture how teams score, not just how much. Head-to-head season record between the two teams. |
| Players | For playoff projections, per-player impact scores (NBA estimated net rating weighted by minutes share) are used to adjust team strength when key players are injured long-term. Regular season predictions capture player impact indirectly through team-level net rating and Four Factors. |
| Rest & travel | Days of rest (2 days is optimal, 4+ creates rust), age-adjusted B2B fatigue, travel distance and timezone crossing, schedule density, and road trip length. |
| Motivation | Tanking detection (comparing first-half vs. second-half performance), clinch resting (teams that have locked in a seed may sit starters), and season progress. |
| Team strength | Season-long net rating (points per 100 possessions differential) and Vegas closing moneyline odds via The Odds API. Market odds capture information our model doesn't have (private injury intel, sharp money, etc.). |
Realistic championship odds: To prevent over-concentration (where one team gets 80%+ title odds), each of the 10,000 simulations draws a random strength perturbation per team -- modeling real uncertainty in team quality. The noise level was calibrated on 149 historical playoff series across 10 seasons, improving series prediction accuracy by 17%.
Injury adjustments: Long-term injuries (surgery, multi-week) reduce a team's effective net rating using per-player impact scores from NBA estimated metrics. Game-day scratches are filtered out since playoff projections look weeks ahead.
Series length: Predicted series length is computed analytically using the negative binomial distribution, returning the most likely number of games (4-7) for each matchup.
Data Sources
| Source | Used for |
|---|---|
| NBA.com Stats API via nba_api | Standings, schedule, team and player stats, game logs |
| ESPN | Injury reports |
| FiveThirtyEight RAPTOR | Archived player ratings for cross-season priors |
| Kaggle NBA Betting Data | Historical moneyline odds (2007-2025) |
Influences
| Project | What we learned |
|---|---|
| FiveThirtyEight NBA | Elo methodology, RAPTOR player ratings, Monte Carlo season simulation |
| EPM (Dunks & Threes) | Exponentially weighted decay for player evaluation |
| Harvard Sports Analysis | K-factor decay and Elo improvements |
| Travel & Circadian Research | Travel distance and timezone effects on performance |
| Karpathy's autoresearch | Automated parameter optimization methodology |
| NBA_AI, nba-prediction | Open-source NBA prediction approaches and feature engineering |
Calibration: Are Our Probabilities Honest?
When we say a team has a 70% chance to win, they should actually win about 70% of the time. The chart below compares our predicted probabilities to actual outcomes this season.
Known Limitations
- Injury data is a daily snapshot and can't predict future injuries or surprise returns
- Player ratings use public box score data, not proprietary player tracking (Second Spectrum)
- Mid-season trades take 10-15 games to fully reflect in player ratings
- The model is re-trained nightly, not in real-time during games