File size: 11,714 Bytes
060d2a9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
#!/usr/bin/env python3
"""
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

# Initialize the model
MODEL_DIR = "nba_model"
model = None
model_error = None

try:
    # Try to import the huggingface model
    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}")

# Fallback prediction function if model fails to load
def simple_prediction_fallback(pts_last_season, age, minutes_played):
    """Simple fallback prediction when model is not available"""
    # Basic heuristic based on age and last season performance
    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)  # Normalize to 35 minutes
    
    prediction = pts_last_season * age_factor * minutes_factor
    return max(prediction, 0.0)  # Ensure non-negative

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:
        # Use fallback prediction
        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
        """
        
        # Performance category for fallback
        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 (simplified)
        position_encoding = {
            "Point Guard": 0,
            "Shooting Guard": 1,
            "Small Forward": 2,
            "Power Forward": 3,
            "Center": 4
        }
        
        # Age category encoding
        age_category = 0 if age <= 23 else (1 if age <= 27 else (2 if age <= 32 else 3))
        
        # Create input dictionary
        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,  # Convert percentage to decimal
            'Pos_encoded': position_encoding.get(position, 2),
            'Team_encoded': 15,  # Default team encoding
            '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
        }
        
        # Make prediction
        prediction = model.predict(player_stats)
        
        # Create detailed output
        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"}
        """
        
        # Performance category
        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]

# Create status message
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!"

# Create Gradio interface
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")
    
    # Example players section
    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)
    
    # Event handlers
    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]
    )
    
    # Example player loading
    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 button
    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
    """)

# Launch the app
if __name__ == "__main__":
    demo.launch()