corbanyax commited on
Commit
6c73c29
·
verified ·
1 Parent(s): 3c93791

Improve model controls and TabFM visibility

Browse files
Files changed (2) hide show
  1. README.md +3 -1
  2. app.py +26 -12
README.md CHANGED
@@ -42,7 +42,9 @@ The built-in catalog uses real open datasets where possible:
42
 
43
  TabFM is loaded through the public Google Research package when available. The app keeps graceful fallbacks so the Space still works on CPU-only or dependency-constrained runtimes. Live TabFM runs are opt-in because the model weights are large and CPU-only inference can be slow.
44
 
45
- Model choices include Logistic/Ridge, RandomForest, ExtraTrees, GradientBoosting, HistGradientBoosting, AdaBoost, KNN, SVM, XGBoost, LightGBM, Dummy, and optional live TabFM.
 
 
46
 
47
  Note: TabFM's weights use their own non-commercial license. Review the upstream model license before using this Space commercially.
48
 
 
42
 
43
  TabFM is loaded through the public Google Research package when available. The app keeps graceful fallbacks so the Space still works on CPU-only or dependency-constrained runtimes. Live TabFM runs are opt-in because the model weights are large and CPU-only inference can be slow.
44
 
45
+ Model choices include Logistic, Linear Regression, Ridge, Bayesian Ridge, RandomForest, ExtraTrees, GradientBoosting, HistGradientBoosting, AdaBoost, KNN, SVC/SVR, XGBoost, LightGBM, Dummy, and optional live TabFM.
46
+
47
+ TabFM is always represented in the leaderboard: it appears as skipped until **Run TabFM live** is enabled, then reports live metrics when the run completes.
48
 
49
  Note: TabFM's weights use their own non-commercial license. Review the upstream model license before using this Space commercially.
50
 
app.py CHANGED
@@ -31,7 +31,7 @@ from sklearn.ensemble import (
31
  RandomForestRegressor,
32
  )
33
  from sklearn.impute import SimpleImputer
34
- from sklearn.linear_model import LogisticRegression, Ridge
35
  from sklearn.metrics import (
36
  accuracy_score,
37
  f1_score,
@@ -734,19 +734,21 @@ def available_baselines(task: str) -> dict[str, object]:
734
  "HistGradientBoosting": Pipeline([("prep", make_preprocessor(pd.DataFrame())), ("model", HistGradientBoostingClassifier(max_iter=120, random_state=RANDOM_STATE))]),
735
  "AdaBoost": Pipeline([("prep", make_preprocessor(pd.DataFrame())), ("model", AdaBoostClassifier(n_estimators=80, learning_rate=0.08, random_state=RANDOM_STATE))]),
736
  "KNN": Pipeline([("prep", make_preprocessor(pd.DataFrame(), True)), ("model", KNeighborsClassifier(n_neighbors=7))]),
737
- "SVM": Pipeline([("prep", make_preprocessor(pd.DataFrame(), True)), ("model", SVC(C=1.0, probability=True, random_state=RANDOM_STATE))]),
738
  "Dummy": Pipeline([("prep", make_preprocessor(pd.DataFrame())), ("model", DummyClassifier(strategy="most_frequent"))]),
739
  }
740
  else:
741
  models = {
 
742
  "Ridge": Pipeline([("prep", make_preprocessor(pd.DataFrame(), True)), ("model", Ridge(alpha=1.0))]),
 
743
  "RandomForest": Pipeline([("prep", make_preprocessor(pd.DataFrame())), ("model", RandomForestRegressor(n_estimators=80, min_samples_leaf=2, n_jobs=-1, random_state=RANDOM_STATE))]),
744
  "ExtraTrees": Pipeline([("prep", make_preprocessor(pd.DataFrame())), ("model", ExtraTreesRegressor(n_estimators=120, min_samples_leaf=2, n_jobs=-1, random_state=RANDOM_STATE))]),
745
  "GradientBoosting": Pipeline([("prep", make_preprocessor(pd.DataFrame())), ("model", GradientBoostingRegressor(n_estimators=100, learning_rate=0.06, random_state=RANDOM_STATE))]),
746
  "HistGradientBoosting": Pipeline([("prep", make_preprocessor(pd.DataFrame())), ("model", HistGradientBoostingRegressor(max_iter=120, random_state=RANDOM_STATE))]),
747
  "AdaBoost": Pipeline([("prep", make_preprocessor(pd.DataFrame())), ("model", AdaBoostRegressor(n_estimators=80, learning_rate=0.08, random_state=RANDOM_STATE))]),
748
  "KNN": Pipeline([("prep", make_preprocessor(pd.DataFrame(), True)), ("model", KNeighborsRegressor(n_neighbors=7))]),
749
- "SVM": Pipeline([("prep", make_preprocessor(pd.DataFrame(), True)), ("model", SVR(C=1.0))]),
750
  "Dummy": Pipeline([("prep", make_preprocessor(pd.DataFrame())), ("model", DummyRegressor(strategy="median"))]),
751
  }
752
  if importlib.util.find_spec("xgboost"):
@@ -889,6 +891,7 @@ def benchmark_frame(
889
 
890
  rows: list[dict[str, object]] = []
891
  notes: list[str] = []
 
892
  models = available_baselines(task)
893
  for name, model in models.items():
894
  if name not in selected_models:
@@ -905,7 +908,7 @@ def benchmark_frame(
905
  rows.append({"model": name, "status": f"failed: {exc}", "seconds": time.perf_counter() - start})
906
  for name in selected_models:
907
  if name not in models:
908
- rows.append({"model": name, "status": "unavailable in this runtime", "seconds": 0.0, "rank_score": np.nan})
909
 
910
  if include_tabfm:
911
  start = time.perf_counter()
@@ -931,6 +934,7 @@ def benchmark_frame(
931
  notes.append(f"TabFM did not run in this environment. On Spaces, keep Python 3.11 and allow the GitHub dependency plus model download for `{TABFM_MODEL_ID}`.")
932
  else:
933
  rows.append({"model": "TabFM", "status": "skipped - enable Run TabFM live", "seconds": 0.0, "rank_score": np.nan})
 
934
 
935
  results = pd.DataFrame(rows)
936
  metric_cols = [c for c in ["accuracy", "f1_weighted", "roc_auc", "rmse", "mae", "r2", "rank_score", "seconds"] if c in results.columns]
@@ -1173,14 +1177,17 @@ def catalog_table() -> pd.DataFrame:
1173
 
1174
  DEFAULT_MODELS = [
1175
  "Logistic",
 
1176
  "Ridge",
 
1177
  "RandomForest",
1178
  "ExtraTrees",
1179
  "GradientBoosting",
1180
  "HistGradientBoosting",
1181
  "AdaBoost",
1182
  "KNN",
1183
- "SVM",
 
1184
  "XGBoost",
1185
  "LightGBM",
1186
  "Dummy",
@@ -1200,7 +1207,14 @@ def build_app() -> gr.Blocks:
1200
  .stat-card .value { font-size: 28px; font-weight: 760; margin-top: 12px; }
1201
  .stat-card .trend { display: inline-block; margin-left: 8px; font-size: 12px; color: #027a48; background: #ecfdf3; border-radius: 999px; padding: 2px 8px; }
1202
  .panel { background: #fff; border: 1px solid #edf0f5; border-radius: 14px; padding: 14px; box-shadow: 0 12px 35px rgba(15, 23, 42, 0.04); }
1203
- .gr-button-primary { background: #f97316 !important; border-color: #f97316 !important; }
 
 
 
 
 
 
 
1204
  footer { display: none !important; }
1205
  """
1206
  with gr.Blocks(title=APP_TITLE, css=css, theme=gr.themes.Soft(primary_hue="orange", secondary_hue="violet")) as demo:
@@ -1220,14 +1234,14 @@ def build_app() -> gr.Blocks:
1220
  with gr.Tabs():
1221
  with gr.Tab("Arena"):
1222
  with gr.Row():
1223
- with gr.Column(scale=1, elem_classes=["panel"]):
1224
  dataset = gr.Dropdown(dataset_names(), value="Titanic Survival", label="Dataset")
1225
  sample = gr.Slider(100, 50000, value=1000, step=100, label="Sample size")
1226
  test_pct = gr.Slider(10, 40, value=25, step=5, label="Test split (%)")
1227
  seed = gr.Number(value=42, precision=0, label="Random seed")
1228
- models = gr.CheckboxGroup(DEFAULT_MODELS, value=DEFAULT_SELECTED_MODELS, label="Baselines")
1229
  include_tabfm = gr.Checkbox(value=False, label="Run TabFM live (adds TabFM row)")
1230
- metric_toggles = gr.CheckboxGroup(METRIC_CHOICES, value=["rmse", "mae", "r2", "accuracy", "f1_weighted", "roc_auc"], label="Chart metrics")
1231
  chart_style = gr.Radio(["Line", "Radar"], value="Line", label="Chart style")
1232
  with gr.Accordion("TabFM tuning", open=False):
1233
  tabfm_preset = gr.Dropdown(list(TABFM_PRESETS.keys()) + ["Custom"], value="Fast", label="Preset")
@@ -1275,16 +1289,16 @@ def build_app() -> gr.Blocks:
1275
  demo.load(run_catalog, run_inputs, run_outputs)
1276
  with gr.Tab("Upload Dataset"):
1277
  with gr.Row():
1278
- with gr.Column(scale=1, elem_classes=["panel"]):
1279
  file = gr.File(label="CSV file", file_types=[".csv"])
1280
  target = gr.Textbox(label="Target column")
1281
  task = gr.Radio(["Auto", "Classification", "Regression"], value="Auto", label="Task")
1282
  upload_sample = gr.Slider(100, 50000, value=1000, step=100, label="Sample size")
1283
  upload_test_pct = gr.Slider(10, 40, value=25, step=5, label="Test split (%)")
1284
  upload_seed = gr.Number(value=42, precision=0, label="Random seed")
1285
- upload_models = gr.CheckboxGroup(DEFAULT_MODELS, value=DEFAULT_SELECTED_MODELS, label="Baselines")
1286
  upload_tabfm = gr.Checkbox(value=False, label="Run TabFM live (adds TabFM row)")
1287
- upload_metric_toggles = gr.CheckboxGroup(METRIC_CHOICES, value=["rmse", "mae", "r2", "accuracy", "f1_weighted", "roc_auc"], label="Chart metrics")
1288
  upload_chart_style = gr.Radio(["Line", "Radar"], value="Line", label="Chart style")
1289
  with gr.Accordion("TabFM tuning", open=False):
1290
  upload_tabfm_preset = gr.Dropdown(list(TABFM_PRESETS.keys()) + ["Custom"], value="Fast", label="Preset")
 
31
  RandomForestRegressor,
32
  )
33
  from sklearn.impute import SimpleImputer
34
+ from sklearn.linear_model import BayesianRidge, LinearRegression, LogisticRegression, Ridge
35
  from sklearn.metrics import (
36
  accuracy_score,
37
  f1_score,
 
734
  "HistGradientBoosting": Pipeline([("prep", make_preprocessor(pd.DataFrame())), ("model", HistGradientBoostingClassifier(max_iter=120, random_state=RANDOM_STATE))]),
735
  "AdaBoost": Pipeline([("prep", make_preprocessor(pd.DataFrame())), ("model", AdaBoostClassifier(n_estimators=80, learning_rate=0.08, random_state=RANDOM_STATE))]),
736
  "KNN": Pipeline([("prep", make_preprocessor(pd.DataFrame(), True)), ("model", KNeighborsClassifier(n_neighbors=7))]),
737
+ "SVC": Pipeline([("prep", make_preprocessor(pd.DataFrame(), True)), ("model", SVC(C=1.0, probability=True, random_state=RANDOM_STATE))]),
738
  "Dummy": Pipeline([("prep", make_preprocessor(pd.DataFrame())), ("model", DummyClassifier(strategy="most_frequent"))]),
739
  }
740
  else:
741
  models = {
742
+ "LinearRegression": Pipeline([("prep", make_preprocessor(pd.DataFrame(), True)), ("model", LinearRegression())]),
743
  "Ridge": Pipeline([("prep", make_preprocessor(pd.DataFrame(), True)), ("model", Ridge(alpha=1.0))]),
744
+ "BayesianRidge": Pipeline([("prep", make_preprocessor(pd.DataFrame(), True)), ("model", BayesianRidge())]),
745
  "RandomForest": Pipeline([("prep", make_preprocessor(pd.DataFrame())), ("model", RandomForestRegressor(n_estimators=80, min_samples_leaf=2, n_jobs=-1, random_state=RANDOM_STATE))]),
746
  "ExtraTrees": Pipeline([("prep", make_preprocessor(pd.DataFrame())), ("model", ExtraTreesRegressor(n_estimators=120, min_samples_leaf=2, n_jobs=-1, random_state=RANDOM_STATE))]),
747
  "GradientBoosting": Pipeline([("prep", make_preprocessor(pd.DataFrame())), ("model", GradientBoostingRegressor(n_estimators=100, learning_rate=0.06, random_state=RANDOM_STATE))]),
748
  "HistGradientBoosting": Pipeline([("prep", make_preprocessor(pd.DataFrame())), ("model", HistGradientBoostingRegressor(max_iter=120, random_state=RANDOM_STATE))]),
749
  "AdaBoost": Pipeline([("prep", make_preprocessor(pd.DataFrame())), ("model", AdaBoostRegressor(n_estimators=80, learning_rate=0.08, random_state=RANDOM_STATE))]),
750
  "KNN": Pipeline([("prep", make_preprocessor(pd.DataFrame(), True)), ("model", KNeighborsRegressor(n_neighbors=7))]),
751
+ "SVR": Pipeline([("prep", make_preprocessor(pd.DataFrame(), True)), ("model", SVR(C=1.0))]),
752
  "Dummy": Pipeline([("prep", make_preprocessor(pd.DataFrame())), ("model", DummyRegressor(strategy="median"))]),
753
  }
754
  if importlib.util.find_spec("xgboost"):
 
891
 
892
  rows: list[dict[str, object]] = []
893
  notes: list[str] = []
894
+ selected_models = selected_models or []
895
  models = available_baselines(task)
896
  for name, model in models.items():
897
  if name not in selected_models:
 
908
  rows.append({"model": name, "status": f"failed: {exc}", "seconds": time.perf_counter() - start})
909
  for name in selected_models:
910
  if name not in models:
911
+ rows.append({"model": name, "status": f"not compatible with {task} or unavailable", "seconds": 0.0, "rank_score": np.nan})
912
 
913
  if include_tabfm:
914
  start = time.perf_counter()
 
934
  notes.append(f"TabFM did not run in this environment. On Spaces, keep Python 3.11 and allow the GitHub dependency plus model download for `{TABFM_MODEL_ID}`.")
935
  else:
936
  rows.append({"model": "TabFM", "status": "skipped - enable Run TabFM live", "seconds": 0.0, "rank_score": np.nan})
937
+ notes.append("TabFM is listed as skipped because **Run TabFM live** is off. Enable it to benchmark TabFM; the first run may download large model weights.")
938
 
939
  results = pd.DataFrame(rows)
940
  metric_cols = [c for c in ["accuracy", "f1_weighted", "roc_auc", "rmse", "mae", "r2", "rank_score", "seconds"] if c in results.columns]
 
1177
 
1178
  DEFAULT_MODELS = [
1179
  "Logistic",
1180
+ "LinearRegression",
1181
  "Ridge",
1182
+ "BayesianRidge",
1183
  "RandomForest",
1184
  "ExtraTrees",
1185
  "GradientBoosting",
1186
  "HistGradientBoosting",
1187
  "AdaBoost",
1188
  "KNN",
1189
+ "SVC",
1190
+ "SVR",
1191
  "XGBoost",
1192
  "LightGBM",
1193
  "Dummy",
 
1207
  .stat-card .value { font-size: 28px; font-weight: 760; margin-top: 12px; }
1208
  .stat-card .trend { display: inline-block; margin-left: 8px; font-size: 12px; color: #027a48; background: #ecfdf3; border-radius: 999px; padding: 2px 8px; }
1209
  .panel { background: #fff; border: 1px solid #edf0f5; border-radius: 14px; padding: 14px; box-shadow: 0 12px 35px rgba(15, 23, 42, 0.04); }
1210
+ .control-panel { background: linear-gradient(180deg, #ffffff 0%, #fbfcff 100%); border-top: 4px solid #f97316; }
1211
+ .control-panel label span { color: #344054; font-weight: 720; }
1212
+ .control-panel input, .control-panel textarea, .control-panel select { border-radius: 10px !important; }
1213
+ .control-panel .wrap { gap: 9px !important; }
1214
+ .control-panel .token, .control-panel [data-testid="token"] { background: #fff7ed !important; color: #c2410c !important; border: 1px solid #fed7aa !important; border-radius: 999px !important; }
1215
+ .control-panel .checkbox label { border-radius: 999px !important; }
1216
+ .gr-button-primary { background: linear-gradient(135deg, #f97316, #ea4335) !important; border-color: #f97316 !important; box-shadow: 0 12px 24px rgba(249, 115, 22, 0.25) !important; border-radius: 12px !important; min-height: 46px !important; font-weight: 760 !important; }
1217
+ .plot-container, .table-wrap { border-radius: 14px !important; overflow: hidden; }
1218
  footer { display: none !important; }
1219
  """
1220
  with gr.Blocks(title=APP_TITLE, css=css, theme=gr.themes.Soft(primary_hue="orange", secondary_hue="violet")) as demo:
 
1234
  with gr.Tabs():
1235
  with gr.Tab("Arena"):
1236
  with gr.Row():
1237
+ with gr.Column(scale=1, elem_classes=["panel", "control-panel"]):
1238
  dataset = gr.Dropdown(dataset_names(), value="Titanic Survival", label="Dataset")
1239
  sample = gr.Slider(100, 50000, value=1000, step=100, label="Sample size")
1240
  test_pct = gr.Slider(10, 40, value=25, step=5, label="Test split (%)")
1241
  seed = gr.Number(value=42, precision=0, label="Random seed")
1242
+ models = gr.Dropdown(DEFAULT_MODELS, value=DEFAULT_SELECTED_MODELS, multiselect=True, label="Models")
1243
  include_tabfm = gr.Checkbox(value=False, label="Run TabFM live (adds TabFM row)")
1244
+ metric_toggles = gr.Dropdown(METRIC_CHOICES, value=["rmse", "mae", "r2", "accuracy", "f1_weighted", "roc_auc"], multiselect=True, label="Chart metrics")
1245
  chart_style = gr.Radio(["Line", "Radar"], value="Line", label="Chart style")
1246
  with gr.Accordion("TabFM tuning", open=False):
1247
  tabfm_preset = gr.Dropdown(list(TABFM_PRESETS.keys()) + ["Custom"], value="Fast", label="Preset")
 
1289
  demo.load(run_catalog, run_inputs, run_outputs)
1290
  with gr.Tab("Upload Dataset"):
1291
  with gr.Row():
1292
+ with gr.Column(scale=1, elem_classes=["panel", "control-panel"]):
1293
  file = gr.File(label="CSV file", file_types=[".csv"])
1294
  target = gr.Textbox(label="Target column")
1295
  task = gr.Radio(["Auto", "Classification", "Regression"], value="Auto", label="Task")
1296
  upload_sample = gr.Slider(100, 50000, value=1000, step=100, label="Sample size")
1297
  upload_test_pct = gr.Slider(10, 40, value=25, step=5, label="Test split (%)")
1298
  upload_seed = gr.Number(value=42, precision=0, label="Random seed")
1299
+ upload_models = gr.Dropdown(DEFAULT_MODELS, value=DEFAULT_SELECTED_MODELS, multiselect=True, label="Models")
1300
  upload_tabfm = gr.Checkbox(value=False, label="Run TabFM live (adds TabFM row)")
1301
+ upload_metric_toggles = gr.Dropdown(METRIC_CHOICES, value=["rmse", "mae", "r2", "accuracy", "f1_weighted", "roc_auc"], multiselect=True, label="Chart metrics")
1302
  upload_chart_style = gr.Radio(["Line", "Radar"], value="Line", label="Chart style")
1303
  with gr.Accordion("TabFM tuning", open=False):
1304
  upload_tabfm_preset = gr.Dropdown(list(TABFM_PRESETS.keys()) + ["Custom"], value="Fast", label="Preset")