Skip to content

nihalkabir/Fantasy-Basketball-PPG-Predictor

Repository files navigation

Fantasy Basketball Draft Rankings: Proposal

1) Introduction/Background

Our project aims to predict next‑season fantasy points per game (FPPG) for NBA players from last season’s stats and a bit of context, then turn those predictions into an overall draft board and positional ranks.

We’ll use a public NBA stats file (Kaggle or a Basketball‑Reference API). Our dataset has typical columns: points, rebounds, assists, steals, blocks, turnovers, made threes, FG%, FT%, games played, minutes, age, and a rough team‑pace signal. The Kaggle dataset (https://www.kaggle.com/datasets/wyattowalsh/basketball) is extremely thorough, hosting data dating back to the initial 1947 NBA season.

We found 3 relevant academic papers in the field of AI/ML and basketball:

  • Kannan et al. (2018) looked at basketball performance with common ML tools like logistic/linear models, SVM, and Random Forest. The big takeaway for us was that tree‑based methods often beat simple linear baselines on tabular basketball data, and basic cross‑validation plus a little tuning goes a long way.
  • Chandru et al. (2025) ran regression and gradient‑boosting style models to estimate player performance. They showed that with clean features and small, careful tuning, you can get solid accuracy without deep learning, which is interesting as we initially considered neural networks (a hot topic in the ML/DL field).
  • Yao et al. (2025) studied aging and career trends with autoencoders, clustering, and LSTMs. That’s more advanced than we need and frankly was hard to understand, but the simple idea we’ll borrow is: age and recent‑form features help. We’ll capture the spirit with age (and maybe age²).

2) Problem definition

Our task is to train on season Y–1 (Y is the year) stats (inputs) to predict season Y FPPG (output). We will also sort predictions to produce overall and positional draft rankings.
Our motivation for this problem stems in the fact that this is a relevant project, as many college students are invested in sports. Overall, we think the project will be fun and keep us interested, as we apply what we learn throughout the semester.

3) Methods

We will first need to do some preprocessing on our data since the core dataset is extremely large and on its own would be too noisy.

  1. Season splits: Build (Y–1 to Y) pairs and always test on a future season (this will avoid the problem that if we are training to predict on year Y we don't provide data from year Y so our model is not biased)
  2. Cleaning: Fill rare missing values and cap extreme outliers
  3. Add features: This includes Age, Age^2, and minutes played per games

We will try and do PCA to find overlapping features and choose the best ones as well (this can be dropped since unsupervised learning is not required for undergrad).

Models we’ll try:

  • Baseline: last year’s FPPG. This is our “sanity check.” If we can’t beat it we cannot consider our model to be successful.
  • Ridge Regression: A simple linear regression method that adds a small penalty so no single input dominates.
  • Lasso Regression: Similar to Ridge, but it can drop unhelpful inputs by setting their weights to zero.
  • Random Forest: Many small decision trees averaged together. This will be good for non‑linear patterns. We also get feature importance w/ RF so we can see which stats mattered.

Data Collection

We used the dataset from Github called NBA-Data-2010-2024 (https://github.com/NocturneBear/NBA-Data-2010-2024) to get base stats for every player from the 2010-2024 seasons. This dataset contains per-game statistics for each player in each season.

We also combined this with the nba_api (https://github.com/swar/nba_api) to get additional player metadata and team performance data.

Data Aggregation and Filtering

  • Player Selection: We filtered to top 150 players per season based on current-season FPPG to focus on fantasy-relevant players
  • Game Threshold: We required a minimum of 20 games played in both current and target seasons to ensure that players had sufficient data for reliable statistics.
  • Time Series Structure: We split the data into season pair format (e.g. (2010-2011), (2011-2012), etc. so that we could predict fantasy points of the next season based on the previous season.

Feature Engineering

Base Statistical Features (Per-Game Conversion)

We converted raw season totals to per-game averages for consistency by dividing by games_i (games played in season i):

  • Shooting: 3PM, FGA, FGM, FTA, FTM per game
  • Other Stats: Rebounds, assists, steals, blocks, turnovers per game
  • Minutes: Minutes per game (MPG)

Fantasy Points Calculation

Fantasy scoring system applied to season totals, then converted to per-game:

Scoring Weights:

  • Points: +1
  • 3-Pointers Made (3PM): +1
  • Field Goals Made (FGM): +2
  • Field Goals Attempted (FGA): -1
  • Free Throws Made (FTM): +1
  • Free Throws Attempted (FTA): -1
  • Rebounds (REB): +1
  • Assists (AST): +2
  • Steals (STL): +4
  • Blocks (BLK): +4
  • Turnovers (TOV): -2

Formula:

FPPG = (Points + 3PM + 2×FGM + FTM + REB + 2×AST + 4×STL + 4×BLK) 
       - (FGA + FTA + 2×TOV) / Games Played

Enhanced Features from NBA API

  • Age: Player age at season start (October 1st), computed from birth date
  • Age²: squared age term to capture non-linear aging effects
  • Team Wins: Regular season wins for player's primary team
  • Position: One-hot encoded categories (Center(C), Forward(F), Guard(G), UNK) based on most frequent position

Model 1 - Ridge Regression:

Model Selection Reasoning

We selected Ridge regression for several reasons:

  1. Regularization: L2 penalty prevents overfitting with multiple correlated basketball statistics
  2. Baseline Performance: Establishes strong baseline for more complex models
  3. Robustness: Less sensitive to outliers compared to ordinary least squares

Model Configuration

  • Cross-Validation: 5-fold CV for hyperparameter tuning
  • Alpha Search: Grid search over [0.1, 1.0, 5.0, 10.0, 50.0] for optimal regularization
  • Feature Set: 15 total features (11 per-game stats + MPG + age + age² + wins + position)
  • Target: Next-season fantasy points per game (continuous regression)

Training Methodology

  • Preprocessing Pipeline: Automated feature scaling and encoding within sklearn Pipeline
  • Validation Strategy: Cross-validation during hyperparameter selection
  • Baseline Comparison: Simple persistence model (current FPPG = next FPPG) for performance context

Model 2 – Random Forest Regressor

Model Selection Reasoning

We selected Random Forest for several reasons:

  1. Non-Linear Relationships: Captures interaction effects between stats (e.g., usage × efficiency).
  2. Tree-Based Stability: Less sensitive to scaling, skewed features, and outliers.
  3. Model Diagnostics: Provides feature-importance estimates that aid interpretability.

Model Configuration

  • Trees: 100 decision trees in the ensemble
  • Maximum Depth: 14 (deeper trees showed minimal additional benefit)
  • Feature Set: Same 15-feature vector used across all learned models
  • Target: Next-season fantasy points per game (continuous regression)

Training Methodology

  • Fitting Procedure: Standard sklearn RandomForestRegressor training on historical seasons
  • Temporal Split: Train on seasons ending 2011–2021, evaluate on 2022–2023
  • Baseline Comparison: Evaluated against Ridge and the persistence model for performance context

Model 3 – XGBoost Regressor

Model Selection Reasoning

We selected XGBoost for several reasons:

  1. High Performance on Tabular Data: Boosted trees typically outperform linear and bagged models on structured features.
  2. Regularization Control: Strong L2 penalty (λ = 10) helps prevent overfitting on noisy season-level stats.
  3. Fine-Grained Learning: Gradient boosting allows the model to capture subtle thresholds and interaction patterns.

Model Configuration

  • Estimators: 500 estimators
  • Learning Rate: 0.05 (trades off stability and model depth)
  • Max Depth: 4 (shallow trees to prevent overfitting across seasons)
  • Regularization: L2 regularization, λ = 10, plus row and column subsampling
  • Subsampling: Both row and feature subsampling enabled for generalization
  • Hyperparameter Scaffold: Commented grid-search ranges included for future tuning
  • Feature Set: Same 15-feature input vector
  • Target: Next-season fantasy points per game

Training Methodology

  • Gradient Boosting Process: Sequential training with shrinkage and subsampling to reduce error iteratively
  • Temporal Evaluation: Train on 2011–2021 seasons, test on 2022–2023
  • Baseline Comparison: Directly compared against Ridge, Random Forest, and the persistence baseline

4)Results and Discussion

Quantative means to measure our success:

  • Average absolute error (MAE): This will answer on average, how many fantasy points per game are we off by?
  • Root mean squared error (RMSE): Similar to MAE, but it will penalizes big misses more. This is important because we hope to have people use our model for their drafts and big misses can be very constly for someone's fantasy season :(
  • R^2: This is a metric between 0 and 1. If it’s 0.70, we’re explaining about 70% of the differences in FPPG.

To measure our draft rankings we'll use the following quntative metrics:

  • Rank agreement (Spearman’s rho): Measures how similar our ranking is to the true end‑of‑season ranking (1.0 being perfect).
  • “Top list” quality (NDCG@K or normalized discounted cumulative gain for K items): This is a single number that rewards us for getting the right players near the top (like a draft top‑50).

For our project beating the baseline by ~10% lower RMSE and getting decent rank agreement on the top‑120 players would be extremely successful. Also show what the models learned on (coefficients for linear models; feature importance for trees) and where they struggled (rookies, injury‑return players).

Limitations and ethics. We’re not modeling injuries or trades. Some misses will come from sudden role changes. We don't see any negative ethical implications of our project. This is meant to be a fun learning experience that other students and fantasy players can hopefully use.

Model 1 - Ridge Regression Results

Overall, our ridge regression model beat our expectations. This was one of the more simpler models we considered. Our metrics for the 2023-24 test season are as follows:

  • MAE: 4.099
  • RMSE: 5.250
  • R^2: 0.7164

We achieved an R^2 score of 71.64% which beats our expectation of 70%. Our mae and rmse scores are about 5 Fantasy Points Per Game, which is represents our average residual, as shown below.

Residuals Histogram
In this graph, we plot our residuals for the 2023-24 season for each player. We see that on average, we are predicting within 5 points of actual FPPG. The prediction follows closely to a gaussian distribution. At worst we are 10 to 15 points off the actual FPPG.

Ridge Regression Chart
In this chart, we map True Fantasy Points Per Game (FPPG) vs Predicted FPPG for the 2023-24 season. We see a decent regression line with not too high bias and pointing in the direction of highest variance.

2011-12 Ranking_Predictions
This dataframe shows our top 10 predictions for the 2011-12 test season trained on the previous season (2010-11). The predictions are very similar to the actual data, except for the 8th rank (outlier).

Model 2 – Random Forest Results

Our Random Forest model delivered the strongest performance among all approaches we tested. Despite its simplicity relative to boosting methods, the ensemble of moderately deep trees captured non-linear relationships between player statistics and next-season fantasy performance remarkably well.

For the 2022–23 test season (training on 2011–2021), our evaluation metrics are:

  • MAE: 4.4331
  • RMSE: 5.5811
  • R^2: 0.7863

With an R^2 of 78.63%, Random Forest exceeded our expectations and outperformed both Ridge regression and XGBoost. Errors remained in the 4–6 FPPG range, which is strong given the variance in year-to-year NBA performance. The distribution of residuals was tighter than that of Ridge, with fewer extreme errors, reflecting the model’s ability to capture interaction effects such as usage x efficiency and minutes x age.

random_forest_gaussian
Similar to Ridge, the Random Forest residuals for 2022–23 (shown above) form a roughly Gaussian shape, but with a slightly lighter tail—indicating improved handling of outliers. Most predictions fall within ±5 points of actual FPPG, with only a small number of players exceeding 10–12 point errors.

random_forest_scatterplot
The true-vs-predicted plot shows a strong diagonal structure with noticeably less spread than the linear model. Predictions for high-performing players remain more stable, showing that the ensemble effectively generalizes nonlinear thresholds (e.g., “star-level minute load” or “elite shooting seasons”).

Model 3 – XGBoost Results

XGBoost produced performance very close to Random Forest, validating gradient boosting as a powerful method for modeling tabular basketball statistics. Although RF narrowly outperformed it in our temporal evaluation, XGBoost showed consistent accuracy and strong generalization across seasons.

For the 2022–23 test season, we obtained:

  • MAE: 4.4731
  • RMSE: 5.6257
  • R^2: 0.7829

An R^2 of 78.29% places XGBoost just behind Random Forest but ahead of the linear Ridge model. Errors remain clustered tightly around ~4.5 FPPG, reflecting the model’s strong performance in next-season prediction despite regularization and conservative depth constraints (depth = 4). Boosting was especially effective at modeling subtle player-specific patterns like low-minute efficiency spikes or late-career decline trajectories.

xgboost_gaussian
Residuals again follow a bell-shaped curve centered near zero, with slightly heavier tails than the Random Forest. This is consistent with boosted trees’ tendency to overfit subtle signals compared to bagged ensembles—especially given year-to-year variance in player roles.

xgboost_scatterplot
The true-vs-predicted scatter plot shows a strong diagonal trend, very similar to Random Forest but with slightly more spread in the upper-FPPG region. High-usage stars with volatile seasons (injury changes or role shifts) contribute most to the larger residuals.

Comparison

These comparative results align with our modeling intuition. Ridge offers interpretability and stability but is limited in representing strong interactions (for example, high minutes amplifying the effect of efficiency, or defensive awareness translating non‑linearly to fantasy value). Random Forest is robust to monotonic transformations and captures piecewise relationships and interactions with limited tuning; its feature‑importance plots help identify dominant drivers, which in our setting include minutes per game, efficiency/points per minute, and awareness‑related contributions. XGBoost balances flexibility and regularization, and with additional tuning it often surpasses Random Forest on tabular tasks; in our current configuration, it lands slightly behind Random Forest yet clearly ahead of the linear benchmark.

Error patterns reflect familiar domain challenges: rookies and low‑minute players present weak priors; trades, injuries, and role changes are difficult to anticipate from prior‑season features alone; and era shifts can alter statistical distributions. Our design mitigates these issues by normalizing per game, incorporating age and team strength, and preventing temporal leakage, but rank‑focused diagnostics should be added explicitly to quantify drafting utility.

Next Steps

While all three models performed well, there is still room to tighten error margins beyond the current ~4–5 FPPG MAE achieved by Random Forest and XGBoost. Incorporating richer features—such as role changes, injury history, lineup context, or advanced tracking metrics—may help reduce the larger residuals seen in high-variance players. More aggressive hyperparameter tuning, especially for XGBoost’s depth and regularization settings, could further close the gap between the models. Finally, expanding the temporal window or introducing rolling-window retraining may better capture evolving league trends and improve stability across seasons.

References

[1] Kannan et al., “Predicting NBA Success: A Machine Learning Approach,” SMU Data Science Review, 2018.
[2] “Enhancing Basketball Team Strategies Through Predictive Analytics of Player Performance,” MDPI Electronics, 2025.
[3] “Aging Decline in Basketball Career Trend Prediction Based on Autoencoder, K‑means and LSTM,” arXiv:2509.25858, 2025.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors