File size: 5,007 Bytes
04d4928
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22f83cf
 
 
 
 
04d4928
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6a6196e
04d4928
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
# -*- coding: utf-8 -*-
"""tabular_gradio.ipynb

Automatically generated by Colab.

Original file is located at
    https://colab.research.google.com/drive/1-_lDVeqDrMkiSuBA380Q7IC2WYa0NHcF
"""

import os  # For filesystem operations
import shutil  # For directory cleanup
import zipfile  # For extracting model archives
import pathlib  # For path manipulations
import pandas as pd # For tabular data handling
import gradio as gr  # For interactive UI
import huggingface_hub  # For downloading model assets
import autogluon.tabular  # For loading and running AutoGluon predictors

# Settings
MODEL_REPO_ID = "mrob937/2024-24679-tabular-autogluon-predictor"
ZIP_FILENAME  = "autogluon_predictor_dir.zip"
CACHE_DIR = pathlib.Path("hf_assets")
EXTRACT_DIR = CACHE_DIR / "predictor_native"

FEATURE_COLS = [
    "Tgt",
    "Rec",
    "Yds",
    "YBC/R",
    "YAC/R",
    "ADOT",
    "Drop%",
    "Rat"
]
TARGET_COL = "Elite"

def _prepare_predictor_dir() -> str:
    CACHE_DIR.mkdir(parents=True, exist_ok=True)
    local_zip = huggingface_hub.hf_hub_download(
        repo_id=MODEL_REPO_ID,
        filename=ZIP_FILENAME,
        repo_type="model",
        local_dir=str(CACHE_DIR),
        local_dir_use_symlinks=False,
    )
    if EXTRACT_DIR.exists():
        shutil.rmtree(EXTRACT_DIR)
    EXTRACT_DIR.mkdir(parents=True, exist_ok=True)
    with zipfile.ZipFile(local_zip, "r") as zf:
        zf.extractall(str(EXTRACT_DIR))
    contents = list(EXTRACT_DIR.iterdir())
    predictor_root = contents[0] if (len(contents) == 1 and contents[0].is_dir()) else EXTRACT_DIR
    return str(predictor_root)

PREDICTOR_DIR = _prepare_predictor_dir()
PREDICTOR = autogluon.tabular.TabularPredictor.load(PREDICTOR_DIR, require_py_version_match=False)

OUTCOME_MAP = {
    0: "Not Elite",
    1: "Elite",
}

def _human_label(c):
    try:
        ci = int(c)
        if ci in OUTCOME_MAP:
            return OUTCOME_MAP[ci]
    except Exception:
        pass
    return str(c)

def do_predict(player, tgt, rec, yds, ybc_r, yac_r, adot, drop_pct, rat):
    row = {
        "Player": str(player),
        FEATURE_COLS[0]: float(tgt),
        FEATURE_COLS[1]: float(rec),
        FEATURE_COLS[2]: float(yds),
        FEATURE_COLS[3]: float(ybc_r),
        FEATURE_COLS[4]: float(yac_r),
        FEATURE_COLS[5]: float(adot),
        FEATURE_COLS[6]: float(drop_pct),
        FEATURE_COLS[7]: float(rat),
    }
    X = pd.DataFrame([row], columns=["Player"] + FEATURE_COLS)

    pred_series = PREDICTOR.predict(X)
    raw_pred = pred_series.iloc[0]

    try:
        proba = PREDICTOR.predict_proba(X)
        if isinstance(proba, pd.Series):
            proba = proba.to_frame().T
    except Exception:
        proba = None

    pred_label = _human_label(raw_pred)

    proba_dict = None
    if proba is not None:
        row0 = proba.iloc[0]
        tmp = {}
        for cls, val in row0.items():
            key = _human_label(cls)
            tmp[key] = float(val) + float(tmp.get(key, 0.0))
        proba_dict = dict(sorted(tmp.items(), key=lambda kv: kv[1], reverse=True))

    if proba_dict:
        return {f"{player}{k}": v for k, v in proba_dict.items()}
    else:
        return {f"{player}{pred_label}": 1.0}

EXAMPLES = [
    ["Justin Jefferson", 8.0, 5.0, 65.0, 6.0, 4.0, 8.5, 1.5, 137.2],
    ["Cooper Kupp", 15.0, 10.0, 140.0, 8.0, 6.0, 9.0, 0.5, 118.5],
    ["Rookie WR", 3.0, 2.0, 12.0, 4.0, 3.0, 5.0, 4.0, 50.5],
    ["Tyreek Hill", 20.0, 14.0, 220.0, 10.0, 8.0, 12.0, 0.2, 130.0],
    ["Bench Player", 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 10.0, 30.0],
]

with gr.Blocks() as demo:
    gr.Markdown("# Football: Will this player be Elite?")
    gr.Markdown("Enter the player's name and stats below. The model will predict whether they're Elite and show probabilities.")

    player_name = gr.Textbox(value="Example Player", label="Player Name")

    with gr.Row():
        tgt = gr.Slider(0, 30, value=8.0, step=0.5, label=FEATURE_COLS[0])
        rec = gr.Slider(0, 20, value=5.0, step=0.5, label=FEATURE_COLS[1])

    with gr.Row():
        yds = gr.Number(value=60.0, precision=1, label=FEATURE_COLS[2])
        ybc_r = gr.Number(value=6.0, precision=2, label=FEATURE_COLS[3])

    with gr.Row():
        yac_r = gr.Number(value=4.0, precision=2, label=FEATURE_COLS[4])
        adot = gr.Number(value=8.0, precision=2, label=FEATURE_COLS[5])

    with gr.Row():
        drop_pct = gr.Slider(0.0, 100.0, value=1.5, step=0.1, label=FEATURE_COLS[6])
        rat = gr.Slider(0.0, 158.0, value=7.2, step=0.1, label=FEATURE_COLS[7])

    proba_pretty = gr.Label(num_top_classes=5, label="Class probabilities")

    inputs = [player_name, tgt, rec, yds, ybc_r, yac_r, adot, drop_pct, rat]
    for comp in inputs:
        comp.change(fn=do_predict, inputs=inputs, outputs=[proba_pretty])

    gr.Examples(
        examples=EXAMPLES,
        inputs=inputs,
        label="Representative examples",
        examples_per_page=5,
        cache_examples=False,
    )

if __name__ == "__main__":
    demo.launch()