|
|
|
|
|
""" |
|
|
Gradio App for NBA Performance Predictor on Hugging Face Spaces |
|
|
""" |
|
|
|
|
|
import gradio as gr |
|
|
import pandas as pd |
|
|
import numpy as np |
|
|
import os |
|
|
import sys |
|
|
|
|
|
|
|
|
MODEL_DIR = "nba_model" |
|
|
model = None |
|
|
model_error = None |
|
|
|
|
|
try: |
|
|
|
|
|
from huggingface_model import NBAPerformancePredictorHF |
|
|
|
|
|
if os.path.exists(MODEL_DIR): |
|
|
model = NBAPerformancePredictorHF(MODEL_DIR) |
|
|
print("โ
Model loaded successfully!") |
|
|
else: |
|
|
model_error = f"Model directory '{MODEL_DIR}' not found. Please upload the trained model." |
|
|
print(f"โ ๏ธ {model_error}") |
|
|
except ImportError as e: |
|
|
model_error = f"Cannot import huggingface_model: {e}" |
|
|
print(f"โ {model_error}") |
|
|
except Exception as e: |
|
|
model_error = f"Error loading model: {e}" |
|
|
print(f"โ {model_error}") |
|
|
|
|
|
|
|
|
def simple_prediction_fallback(pts_last_season, age, minutes_played): |
|
|
"""Simple fallback prediction when model is not available""" |
|
|
|
|
|
age_factor = 1.0 if age <= 27 else (0.95 if age <= 32 else 0.9) |
|
|
minutes_factor = min(minutes_played / 35.0, 1.0) |
|
|
|
|
|
prediction = pts_last_season * age_factor * minutes_factor |
|
|
return max(prediction, 0.0) |
|
|
|
|
|
def predict_player_performance( |
|
|
age, games, games_started, minutes_played, field_goals, field_goal_attempts, |
|
|
field_goal_percentage, position, pts_last_season, pts_two_seasons_ago, |
|
|
rebounds_last_season, assists_last_season, points_per_minute_last_season |
|
|
): |
|
|
""" |
|
|
Predict NBA player performance based on input statistics |
|
|
""" |
|
|
if model is None: |
|
|
|
|
|
prediction = simple_prediction_fallback(pts_last_season, age, minutes_played) |
|
|
|
|
|
result_text = f""" |
|
|
๐ **Predicted Points Per Game: {prediction:.1f}** *(Fallback Mode)* |
|
|
|
|
|
โ ๏ธ **Note**: Using simplified prediction model because: |
|
|
{model_error} |
|
|
|
|
|
๐ **Input Summary:** |
|
|
- Player Age: {age} |
|
|
- Games: {games} (Started: {games_started}) |
|
|
- Minutes per Game: {minutes_played:.1f} |
|
|
- Field Goal %: {field_goal_percentage:.1f}% |
|
|
- Position: {position} |
|
|
|
|
|
๐ **Historical Performance:** |
|
|
- Last Season PPG: {pts_last_season:.1f} |
|
|
- Two Seasons Ago PPG: {pts_two_seasons_ago:.1f} |
|
|
|
|
|
๐ง **Fallback Method**: Basic heuristic using age and last season performance |
|
|
""" |
|
|
|
|
|
|
|
|
if prediction < 8: |
|
|
category = "๐ต Role Player (Estimated)" |
|
|
elif prediction < 15: |
|
|
category = "๐ข Solid Contributor (Estimated)" |
|
|
elif prediction < 20: |
|
|
category = "๐ก Good Scorer (Estimated)" |
|
|
elif prediction < 25: |
|
|
category = "๐ Star Player (Estimated)" |
|
|
else: |
|
|
category = "๐ด Superstar (Estimated)" |
|
|
|
|
|
return result_text, category |
|
|
|
|
|
try: |
|
|
|
|
|
position_encoding = { |
|
|
"Point Guard": 0, |
|
|
"Shooting Guard": 1, |
|
|
"Small Forward": 2, |
|
|
"Power Forward": 3, |
|
|
"Center": 4 |
|
|
} |
|
|
|
|
|
|
|
|
age_category = 0 if age <= 23 else (1 if age <= 27 else (2 if age <= 32 else 3)) |
|
|
|
|
|
|
|
|
player_stats = { |
|
|
'Age': age, |
|
|
'G': games, |
|
|
'GS': games_started, |
|
|
'MP': minutes_played, |
|
|
'FG': field_goals, |
|
|
'FGA': field_goal_attempts, |
|
|
'FG_1': field_goal_percentage / 100.0, |
|
|
'Pos_encoded': position_encoding.get(position, 2), |
|
|
'Team_encoded': 15, |
|
|
'Age_category_encoded': age_category, |
|
|
'PTS_lag_1': pts_last_season, |
|
|
'PTS_lag_2': pts_two_seasons_ago, |
|
|
'TRB_lag_1': rebounds_last_season, |
|
|
'AST_lag_1': assists_last_season, |
|
|
'Points_per_minute_lag_1': points_per_minute_last_season, |
|
|
'Efficiency_lag_1': (pts_last_season + rebounds_last_season + assists_last_season) / minutes_played if minutes_played > 0 else 0 |
|
|
} |
|
|
|
|
|
|
|
|
prediction = model.predict(player_stats) |
|
|
|
|
|
|
|
|
result_text = f""" |
|
|
๐ **Predicted Points Per Game: {prediction:.1f}** |
|
|
|
|
|
๐ **Input Summary:** |
|
|
- Player Age: {age} |
|
|
- Games: {games} (Started: {games_started}) |
|
|
- Minutes per Game: {minutes_played:.1f} |
|
|
- Field Goal %: {field_goal_percentage:.1f}% |
|
|
- Position: {position} |
|
|
|
|
|
๐ **Historical Performance:** |
|
|
- Last Season PPG: {pts_last_season:.1f} |
|
|
- Two Seasons Ago PPG: {pts_two_seasons_ago:.1f} |
|
|
- Last Season RPG: {rebounds_last_season:.1f} |
|
|
- Last Season APG: {assists_last_season:.1f} |
|
|
|
|
|
๐ฏ **Prediction Confidence:** |
|
|
{"High" if abs(prediction - pts_last_season) < 3 else "Medium" if abs(prediction - pts_last_season) < 6 else "Low"} |
|
|
""" |
|
|
|
|
|
|
|
|
if prediction < 8: |
|
|
category = "๐ต Role Player" |
|
|
elif prediction < 15: |
|
|
category = "๐ข Solid Contributor" |
|
|
elif prediction < 20: |
|
|
category = "๐ก Good Scorer" |
|
|
elif prediction < 25: |
|
|
category = "๐ Star Player" |
|
|
else: |
|
|
category = "๐ด Superstar" |
|
|
|
|
|
return result_text, category |
|
|
|
|
|
except Exception as e: |
|
|
return f"โ Error making prediction: {str(e)}", "" |
|
|
|
|
|
def load_example_player(player_name): |
|
|
"""Load example player data""" |
|
|
examples = { |
|
|
"LeBron James (Prime)": [27, 75, 75, 38.0, 9.5, 19.0, 50.0, "Small Forward", 27.1, 25.3, 7.4, 7.4, 0.71], |
|
|
"Stephen Curry (Peak)": [28, 79, 79, 34.0, 10.2, 20.2, 50.4, "Point Guard", 30.1, 23.8, 5.4, 6.7, 0.88], |
|
|
"Rookie Player": [22, 65, 15, 18.0, 3.2, 7.8, 41.0, "Shooting Guard", 8.5, 0.0, 2.8, 1.5, 0.47], |
|
|
"Veteran Role Player": [32, 70, 25, 22.0, 4.1, 9.2, 44.6, "Power Forward", 11.2, 12.8, 5.2, 1.8, 0.51] |
|
|
} |
|
|
|
|
|
if player_name in examples: |
|
|
return examples[player_name] |
|
|
return [25, 70, 50, 30.0, 6.0, 13.0, 46.0, "Small Forward", 15.0, 14.0, 5.0, 3.0, 0.50] |
|
|
|
|
|
|
|
|
status_message = "" |
|
|
if model is None: |
|
|
status_message = f""" |
|
|
โ ๏ธ **Status**: Running in fallback mode |
|
|
|
|
|
**Issue**: {model_error} |
|
|
|
|
|
**Current Mode**: Using simplified prediction based on age and last season performance. |
|
|
For full ML model predictions, ensure the trained model files are available. |
|
|
""" |
|
|
else: |
|
|
status_message = "โ
**Status**: Full ML model loaded and ready!" |
|
|
|
|
|
|
|
|
with gr.Blocks(title="NBA Performance Predictor", theme=gr.themes.Soft()) as demo: |
|
|
gr.Markdown(f""" |
|
|
# ๐ NBA Player Performance Predictor |
|
|
|
|
|
{status_message} |
|
|
|
|
|
Predict a player's points per game (PPG) using machine learning trained on historical NBA data. |
|
|
|
|
|
**How to use:** |
|
|
1. Enter the player's current season statistics |
|
|
2. Provide historical performance data (last 1-2 seasons) |
|
|
3. Click "Predict Performance" to get the PPG prediction |
|
|
|
|
|
*Note: The model works best with players who have at least 1-2 seasons of NBA experience.* |
|
|
""") |
|
|
|
|
|
with gr.Row(): |
|
|
with gr.Column(): |
|
|
gr.Markdown("### ๐ Current Season Stats") |
|
|
age = gr.Slider(18, 45, value=25, step=1, label="Age") |
|
|
games = gr.Slider(1, 82, value=70, step=1, label="Games Played") |
|
|
games_started = gr.Slider(0, 82, value=50, step=1, label="Games Started") |
|
|
minutes_played = gr.Slider(5.0, 45.0, value=30.0, step=0.1, label="Minutes Per Game") |
|
|
|
|
|
with gr.Row(): |
|
|
field_goals = gr.Number(value=6.0, label="Field Goals Made Per Game") |
|
|
field_goal_attempts = gr.Number(value=13.0, label="Field Goal Attempts Per Game") |
|
|
|
|
|
field_goal_percentage = gr.Slider(20.0, 70.0, value=46.0, step=0.1, label="Field Goal Percentage (%)") |
|
|
position = gr.Dropdown( |
|
|
choices=["Point Guard", "Shooting Guard", "Small Forward", "Power Forward", "Center"], |
|
|
value="Small Forward", |
|
|
label="Position" |
|
|
) |
|
|
|
|
|
with gr.Column(): |
|
|
gr.Markdown("### ๐ Historical Performance") |
|
|
pts_last_season = gr.Number(value=15.0, label="Points Per Game (Last Season)") |
|
|
pts_two_seasons_ago = gr.Number(value=14.0, label="Points Per Game (Two Seasons Ago)") |
|
|
rebounds_last_season = gr.Number(value=5.0, label="Rebounds Per Game (Last Season)") |
|
|
assists_last_season = gr.Number(value=3.0, label="Assists Per Game (Last Season)") |
|
|
points_per_minute_last_season = gr.Slider(0.1, 1.5, value=0.50, step=0.01, label="Points Per Minute (Last Season)") |
|
|
|
|
|
with gr.Row(): |
|
|
predict_btn = gr.Button("๐ฎ Predict Performance", variant="primary", size="lg") |
|
|
clear_btn = gr.Button("๐๏ธ Clear", variant="secondary") |
|
|
|
|
|
with gr.Row(): |
|
|
with gr.Column(): |
|
|
prediction_output = gr.Markdown(label="Prediction Result") |
|
|
with gr.Column(): |
|
|
category_output = gr.Markdown(label="Player Category") |
|
|
|
|
|
|
|
|
gr.Markdown("### ๐ฅ Try Example Players") |
|
|
example_buttons = [] |
|
|
example_names = ["LeBron James (Prime)", "Stephen Curry (Peak)", "Rookie Player", "Veteran Role Player"] |
|
|
|
|
|
with gr.Row(): |
|
|
for name in example_names: |
|
|
btn = gr.Button(name, variant="outline") |
|
|
example_buttons.append(btn) |
|
|
|
|
|
|
|
|
predict_btn.click( |
|
|
fn=predict_player_performance, |
|
|
inputs=[ |
|
|
age, games, games_started, minutes_played, field_goals, field_goal_attempts, |
|
|
field_goal_percentage, position, pts_last_season, pts_two_seasons_ago, |
|
|
rebounds_last_season, assists_last_season, points_per_minute_last_season |
|
|
], |
|
|
outputs=[prediction_output, category_output] |
|
|
) |
|
|
|
|
|
|
|
|
for i, btn in enumerate(example_buttons): |
|
|
btn.click( |
|
|
fn=lambda name=example_names[i]: load_example_player(name), |
|
|
outputs=[ |
|
|
age, games, games_started, minutes_played, field_goals, field_goal_attempts, |
|
|
field_goal_percentage, position, pts_last_season, pts_two_seasons_ago, |
|
|
rebounds_last_season, assists_last_season, points_per_minute_last_season |
|
|
] |
|
|
) |
|
|
|
|
|
|
|
|
clear_btn.click( |
|
|
fn=lambda: [25, 70, 50, 30.0, 6.0, 13.0, 46.0, "Small Forward", 15.0, 14.0, 5.0, 3.0, 0.50], |
|
|
outputs=[ |
|
|
age, games, games_started, minutes_played, field_goals, field_goal_attempts, |
|
|
field_goal_percentage, position, pts_last_season, pts_two_seasons_ago, |
|
|
rebounds_last_season, assists_last_season, points_per_minute_last_season |
|
|
] |
|
|
) |
|
|
|
|
|
gr.Markdown(""" |
|
|
--- |
|
|
### โน๏ธ About the Model |
|
|
|
|
|
- **Model Type**: XGBoost Regressor |
|
|
- **Training Data**: Historical NBA player statistics |
|
|
- **Performance**: RMSE ~3-5 points, Rยฒ ~0.6-0.8 |
|
|
- **Features**: Uses 50+ features including lag variables, rolling averages, and efficiency metrics |
|
|
|
|
|
**Limitations**: |
|
|
- Works best for players with NBA history |
|
|
- May be less accurate for rookies or players with significant role changes |
|
|
- Predictions are based on historical patterns and may not account for injuries or team changes |
|
|
""") |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
demo.launch() |