Spaces:
Running
Running
updated tabbench space with up-to-date data
Browse files- .DS_Store +0 -0
- app.py +572 -309
- complete_results_acad.json +0 -0
- complete_results_indus.json +0 -0
- complete_results_indus_noxgboost.json +0 -0
- workflow.png → make_classif-parameter_space.parquet +2 -2
- model_info.json +23 -18
- private_dummy.json +0 -0
- public_datasets_info.json +0 -0
- public_dummy.json +0 -0
- public_dummy_first.json +0 -0
- qrt.json +7 -0
- requirements.txt +2 -0
- run.py +1 -1
.DS_Store
CHANGED
|
Binary files a/.DS_Store and b/.DS_Store differ
|
|
|
app.py
CHANGED
|
@@ -5,6 +5,11 @@ import pandas as pd
|
|
| 5 |
import json
|
| 6 |
import random
|
| 7 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
# TabBench currently supports the following models, with new additions that keep coming:
|
| 9 |
# - **NICL (Neuralk In-Context-Learning)**: Our in-house tabular foundation model based on an in-context learning architecture (proprietary).
|
| 10 |
# - **TabICL**: A transformer-based model that performs feature compression before doing in-context learning on tabular data by conditioning on labeled support examples to predict unseen queries without task-specific training.
|
|
@@ -12,15 +17,13 @@ import random
|
|
| 12 |
# - **XGBoost**: An optimized distributed gradient boosting library designed to be highly efficient, flexible, and portable.
|
| 13 |
# - **CatBoost**: A gradient boosting on decision trees library, particularly strong with categorical features.
|
| 14 |
# - **LightGBM**: A fast gradient boosting framework that builds decision trees using histogram-based learning for scalable, high-performance tabular modeling.
|
| 15 |
-
# - **MLP**: A feedforward neural network that models tabular data by learning non-linear interactions between numerical and embedded categorical features.
|
| 16 |
-
# - **Random Forest**: A robust ensemble method that builds multiple decision trees and averages their predictions to reduce overfitting and improve accuracy.
|
| 17 |
# - **ModernNCA**: An advanced extension of Neighborhood Component Analysis (NCA) that employs deep neural networks with stochastic neighborhood sampling to learn complex feature interactions for tabular data.
|
| 18 |
# - **RealMLP**: An enhanced MLP optimized with strong default parameters, achieving competitive performance on tabular data.
|
| 19 |
# - **TabM**: A deep learning model that efficiently imitates an ensemble of MLPs, enhancing performance on tabular data tasks without the overhead of training multiple models.
|
| 20 |
# It is capable of processing datasets up to 100× larger and running up to 10× faster than TabPFNv2.
|
| 21 |
|
| 22 |
PUBLIC_DATASETS_TEXT = """
|
| 23 |
-
We curate a list of **
|
| 24 |
|
| 25 |
🔎 You can easily filter datasets by industry below or explore the industry specific leaderboards via the sidebar.
|
| 26 |
"""
|
|
@@ -28,8 +31,10 @@ We curate a list of **214 datasets** from OpenML that span various industries su
|
|
| 28 |
MODELS_TEXT = """
|
| 29 |
TabBench currently supports the following models, with more additions planned:
|
| 30 |
- **Tabular foundation models**: NICL, TabICL, TabPFNv2
|
| 31 |
-
- **Tree-based**: XGBoost, CatBoost, LightGBM
|
| 32 |
-
- **Neural networks**:
|
|
|
|
|
|
|
| 33 |
"""
|
| 34 |
|
| 35 |
BENCHMARKING_TEXT = """
|
|
@@ -47,32 +52,34 @@ Evaluation is optimized for ROC-AUC and preprocessing steps vary following each
|
|
| 47 |
METRICS_TEXT = """
|
| 48 |
TabBench uses different types of metrics to evaluate model performance:
|
| 49 |
- **Classic metrics**: Accuracy, Precision, Recall, F1 score, AUC
|
| 50 |
-
- **Ranking metrics**:
|
| 51 |
-
- **Industry-relevant metrics**: [ADD WHICH]
|
| 52 |
"""
|
| 53 |
|
| 54 |
TITLE = """
|
| 55 |
-
<
|
| 56 |
-
|
| 57 |
-
</
|
| 58 |
-
<
|
| 59 |
-
An
|
| 60 |
-
</
|
|
|
|
|
|
|
|
|
|
| 61 |
"""
|
| 62 |
|
| 63 |
INTRODUCTION_TEXT = """
|
| 64 |
-
<p style="font-size: 16px; text-align:center">
|
| 65 |
Bridging the gap between academic benchmarks and industry needs
|
| 66 |
</p>
|
| 67 |
"""
|
| 68 |
|
| 69 |
DATA_MAP_TEXT = """
|
| 70 |
-
- 🔎 **Explore
|
| 71 |
-
- 📈 **Compare
|
| 72 |
"""
|
| 73 |
|
| 74 |
PUBLIC_BENCHMARK_TEXT = """
|
| 75 |
-
- 📊 **A curation of
|
| 76 |
- 🤖 **Evaluations on 10+ powerful models** from gradient boosting and decision trees to tabular foundation models
|
| 77 |
- 💥 **Integration of NICL**, the Neuralk AI tabular foundation model designed for industry-grade use cases
|
| 78 |
- 🏅 **Leaderboards by sector** to discover which models perform best for each industry
|
|
@@ -87,7 +94,7 @@ PRIVATE_BENCHMARK_TEXT = """
|
|
| 87 |
# rewrite new uses continuously being added
|
| 88 |
|
| 89 |
PRIVATE_DATA_TEXT = """
|
| 90 |
-
We curate a list of **
|
| 91 |
|
| 92 |
👚 Each dataset contains product titles, descriptions, and hierarchical product categories with four levels.
|
| 93 |
|
|
@@ -99,10 +106,10 @@ You can read more about product categorization and its challenges [here](https:/
|
|
| 99 |
"""
|
| 100 |
|
| 101 |
PRIVATE_MODEL_TEXT = """
|
| 102 |
-
|
| 103 |
- **Tabular foundation models**: NICL, TabICL, TabPFNv2
|
| 104 |
-
- **Tree-based**: XGBoost
|
| 105 |
-
- **Neural networks**:
|
| 106 |
"""
|
| 107 |
|
| 108 |
PRIVATE_BENCHMARKING_TEXT = """
|
|
@@ -116,11 +123,9 @@ For a deeper understanding, you can explore our [Notebooks](https://github.com/N
|
|
| 116 |
"""
|
| 117 |
|
| 118 |
PRIVATE_METRICS_TEXT = """
|
| 119 |
-
|
| 120 |
-
TabBench Pro uses different types of metrics to evaluate model performance:
|
| 121 |
- **Classic metrics**: Accuracy, Precision, Recall, F1 score, AUC
|
| 122 |
-
- **Ranking metrics**:
|
| 123 |
-
- **Industry-relevant metrics**: [ADD WHICH]
|
| 124 |
"""
|
| 125 |
|
| 126 |
|
|
@@ -132,7 +137,8 @@ CITATION_BUTTON_TEXT = """
|
|
| 132 |
year={2025},
|
| 133 |
publisher={GitHub},
|
| 134 |
url={https://github.com/Neuralk-AI/TabBench}
|
| 135 |
-
}
|
|
|
|
| 136 |
|
| 137 |
|
| 138 |
data = {
|
|
@@ -184,12 +190,47 @@ def highlight_max(df: pd.DataFrame):
|
|
| 184 |
return df.style.apply(style_column, axis=0)
|
| 185 |
|
| 186 |
|
| 187 |
-
with open("
|
| 188 |
public_per_dataset = pd.json_normalize(json.load(f))
|
| 189 |
|
| 190 |
-
with open("
|
| 191 |
private_per_dataset = pd.json_normalize(json.load(f))
|
| 192 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 193 |
# -------------------------
|
| 194 |
# Leaderboard builder
|
| 195 |
# -------------------------
|
|
@@ -226,6 +267,10 @@ df_comparison = pd.DataFrame(data)
|
|
| 226 |
# Gradio UI
|
| 227 |
# -------------------------
|
| 228 |
css = """
|
|
|
|
|
|
|
|
|
|
|
|
|
| 229 |
.lg {
|
| 230 |
font-size: 14px;
|
| 231 |
}
|
|
@@ -308,25 +353,63 @@ def df_to_wrapped_html(df: pd.DataFrame):
|
|
| 308 |
html += '</table>'
|
| 309 |
return html
|
| 310 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 311 |
|
| 312 |
-
|
| 313 |
-
# Sidemenu for benchmark selection
|
| 314 |
-
with gr.Sidebar():
|
| 315 |
-
gr.Markdown("### Select benchmark")
|
| 316 |
-
home_btn = gr.Button("🏡 Home", elem_classes=["white-btn", "selected-btn"])
|
| 317 |
-
# gr.Markdown("---")
|
| 318 |
|
| 319 |
-
|
| 320 |
-
|
| 321 |
-
|
| 322 |
-
|
| 323 |
-
|
| 324 |
-
domain_healthcare_btn = gr.Button("🏥 Healthcare", elem_classes=["white-btn"])
|
| 325 |
-
# gr.Markdown("---")
|
| 326 |
|
| 327 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 328 |
|
| 329 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 330 |
|
| 331 |
|
| 332 |
|
|
@@ -337,42 +420,80 @@ with gr.Blocks(css=css) as demo:
|
|
| 337 |
# gr.Markdown("---")
|
| 338 |
gr.Markdown(INTRODUCTION_TEXT)
|
| 339 |
gr.Markdown(" ")
|
| 340 |
-
with gr.
|
| 341 |
-
|
| 342 |
-
|
| 343 |
-
|
| 344 |
-
|
| 345 |
-
|
| 346 |
-
|
| 347 |
-
|
| 348 |
-
|
| 349 |
-
|
| 350 |
-
# """
|
| 351 |
-
# While academic benchmarks for ML on tabular data offer useful insights for researchers, they rarely capture the challenges industry teams face, like messy data, complex pipelines and the need for deployment readiness.
|
| 352 |
-
|
| 353 |
-
# This makes it hard to translate benchmark results into real-world impact and gives industry practitioners little clarity on which models to trust.
|
| 354 |
-
|
| 355 |
-
# TabBench bridges this gap with an evaluation suite designed with industry challenges in mind, making it easier for teams across sectors to evaluate which models perform best in practice.
|
| 356 |
-
# """
|
| 357 |
|
| 358 |
-
|
| 359 |
-
|
| 360 |
-
|
| 361 |
-
with gr.
|
| 362 |
-
gr.
|
| 363 |
-
|
| 364 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 365 |
|
| 366 |
-
|
| 367 |
-
|
| 368 |
-
|
| 369 |
-
|
|
|
|
|
|
|
| 370 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 371 |
|
| 372 |
public_content = gr.Column(visible=False)
|
| 373 |
with public_content:
|
| 374 |
-
|
| 375 |
-
|
| 376 |
gr.Markdown('### Features')
|
| 377 |
# -------------------------
|
| 378 |
# Top row: Models & Datasets
|
|
@@ -436,96 +557,123 @@ with gr.Blocks(css=css) as demo:
|
|
| 436 |
gr.Markdown(f"Estimated average model performance over {num_unique_datasets} datasets.")
|
| 437 |
# Use per-model averages for leaderboard, allow filtering by model_type
|
| 438 |
per_model_leaderboard = init_leaderboard(public_model_agg, include_model_type_filter=True, industry_filter=False)
|
| 439 |
-
|
|
|
|
| 440 |
with gr.Tab("📊 Performance by dataset"):
|
| 441 |
-
|
| 442 |
-
# Merge public_per_dataset with datasets_info for rich dataset metadata
|
| 443 |
with open("public_datasets_info.json", "r") as f:
|
| 444 |
public_datasets_info = pd.DataFrame(json.load(f))
|
|
|
|
| 445 |
public_per_dataset_merged = public_per_dataset.merge(
|
| 446 |
public_datasets_info,
|
| 447 |
left_on=["dataset_name", "dataset_id"],
|
| 448 |
right_on=["dataset_name", "dataset_id"],
|
| 449 |
how="left"
|
| 450 |
)
|
| 451 |
-
# Set industry directly from public_datasets_info.json
|
| 452 |
-
public_per_dataset_merged['industry'] = public_per_dataset_merged['dataset_industry']
|
| 453 |
|
| 454 |
-
public_per_dataset_merged = public_per_dataset_merged
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 455 |
|
| 456 |
-
dataset_perf_cols = [
|
| 457 |
-
"dataset_name", "dataset_id", "industry", "dataset_target", "model", "Accuracy", "Precision", "Recall", "F1_score", "AUC", "Elo_score",
|
| 458 |
-
"num_rows", "num_features", "num_classes", "imbalance_ratio", "missing_values", "categorical_features_ratio"
|
| 459 |
-
]
|
| 460 |
-
show_cols = [col for col in dataset_perf_cols] #if col in public_per_dataset_merged.columns]
|
| 461 |
-
# Slider for filtering by number of features
|
| 462 |
-
min_num_features = int(public_per_dataset_merged['num_features'].min())
|
| 463 |
-
max_num_features = int(public_per_dataset_merged['num_features'].max())
|
| 464 |
with gr.Row():
|
| 465 |
with gr.Column():
|
| 466 |
features_slider = gr.Slider(
|
| 467 |
-
minimum=
|
| 468 |
-
maximum=
|
| 469 |
-
value=
|
| 470 |
step=1,
|
| 471 |
label="Min Number of Features",
|
| 472 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 473 |
with gr.Column():
|
| 474 |
-
|
| 475 |
-
|
| 476 |
-
|
| 477 |
-
|
| 478 |
-
|
| 479 |
-
|
| 480 |
-
|
| 481 |
-
|
| 482 |
-
|
| 483 |
-
|
| 484 |
-
|
| 485 |
-
|
| 486 |
-
|
| 487 |
-
|
| 488 |
-
|
| 489 |
-
|
| 490 |
-
|
| 491 |
-
|
| 492 |
-
|
| 493 |
-
|
| 494 |
-
search_columns=["dataset_name"] if "dataset_name" in show_cols else [],
|
| 495 |
-
hide_columns=[],
|
| 496 |
-
filter_columns=[
|
| 497 |
-
ColumnFilter("model", type="checkboxgroup", label="🤖 Model"),
|
| 498 |
-
ColumnFilter("industry", type="checkboxgroup", label="🏭 Industry"),
|
| 499 |
-
],
|
| 500 |
-
interactive=False,
|
| 501 |
-
)
|
| 502 |
|
| 503 |
-
def public_filter_per_dataset_leaderboard(min_features, min_classes):
|
| 504 |
filtered = public_per_dataset_merged[
|
| 505 |
-
(public_per_dataset_merged[
|
| 506 |
-
(public_per_dataset_merged[
|
|
|
|
|
|
|
| 507 |
]
|
| 508 |
-
return filtered[show_cols]
|
| 509 |
|
| 510 |
-
|
| 511 |
-
|
| 512 |
-
|
| 513 |
-
|
| 514 |
-
|
| 515 |
-
|
| 516 |
-
|
| 517 |
-
|
| 518 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 519 |
)
|
| 520 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 521 |
|
| 522 |
def make_domain_content(industry, label, public_per_dataset, public_datasets_info, model_info):
|
| 523 |
domain_content = gr.Column(visible=False)
|
| 524 |
with domain_content:
|
|
|
|
| 525 |
gr.Markdown(f"## 🥇 {label} Benchmark Leaderboard")
|
| 526 |
-
|
| 527 |
-
#
|
| 528 |
-
# Filter datasets for this industry first
|
| 529 |
domain_per_dataset = public_per_dataset.merge(
|
| 530 |
public_datasets_info[['dataset_name', 'dataset_id', 'dataset_industry']],
|
| 531 |
on=['dataset_name', 'dataset_id'],
|
|
@@ -533,15 +681,12 @@ with gr.Blocks(css=css) as demo:
|
|
| 533 |
)
|
| 534 |
domain_per_dataset = domain_per_dataset[domain_per_dataset['dataset_industry'] == industry]
|
| 535 |
|
| 536 |
-
|
| 537 |
-
model_info = pd.DataFrame(json.load(f))
|
| 538 |
-
# Compute model overview for the industry
|
| 539 |
model_agg = domain_per_dataset.groupby('model')[['Accuracy', 'Precision', 'Recall', 'F1_score', 'AUC', 'Elo_score']].mean().reset_index()
|
| 540 |
model_agg = model_agg.round(3)
|
| 541 |
model_agg = model_agg.merge(model_info[["model_name", "model_type"]], left_on="model", right_on="model_name", how="left").drop(columns=["model_name"])
|
| 542 |
cols = ["model", "model_type"] + [c for c in model_agg.columns if c not in ["model", "model_type"]]
|
| 543 |
model_agg = model_agg[cols]
|
| 544 |
-
# Sort so NICL is always first
|
| 545 |
model_agg = model_agg.sort_values(by=["model"], key=lambda x: x != "NICL").reset_index(drop=True)
|
| 546 |
gr.DataFrame(
|
| 547 |
value=highlight_max(model_agg),
|
|
@@ -550,53 +695,62 @@ with gr.Blocks(css=css) as demo:
|
|
| 550 |
type="pandas",
|
| 551 |
)
|
| 552 |
|
| 553 |
-
gr.Markdown("## 🔍 Explore
|
| 554 |
-
# Merge per_dataset with datasets_info for rich dataset metadata
|
| 555 |
-
with open("public_datasets_info.json", "r") as f:
|
| 556 |
-
public_datasets_info = pd.DataFrame(json.load(f))
|
| 557 |
|
|
|
|
| 558 |
domain_per_dataset_merged = domain_per_dataset.merge(
|
| 559 |
public_datasets_info,
|
| 560 |
left_on=["dataset_name", "dataset_id"],
|
| 561 |
right_on=["dataset_name", "dataset_id"],
|
| 562 |
how="left"
|
| 563 |
)
|
| 564 |
-
print(domain_per_dataset_merged.columns)
|
| 565 |
-
# Set industry directly from public_datasets_info.json
|
| 566 |
domain_per_dataset_merged['industry'] = domain_per_dataset_merged['dataset_industry_y']
|
| 567 |
-
# Filter for the correct industry only
|
| 568 |
domain_per_dataset_merged = domain_per_dataset_merged[domain_per_dataset_merged['industry'] == industry]
|
| 569 |
-
num_unique_datasets = domain_per_dataset_merged['dataset_name'].nunique() if 'dataset_name' in domain_per_dataset_merged.columns else 0
|
| 570 |
-
|
| 571 |
-
with gr.Tabs() as tabs:
|
| 572 |
-
with gr.Tab("🤖 Average model performance"):
|
| 573 |
-
gr.Markdown(f"Estimated average model performance over {num_unique_datasets} datasets.")
|
| 574 |
-
model_leaderboard = init_leaderboard(model_agg, include_model_type_filter=True, industry_filter=False)
|
| 575 |
-
|
| 576 |
-
with gr.Tab("📊 Performance by dataset"):
|
| 577 |
-
dataset_perf_cols = [
|
| 578 |
-
"dataset_name", "dataset_id", "industry", "dataset_target", "model", "Accuracy", "Precision", "Recall", "F1_score", "AUC", "Elo_score",
|
| 579 |
-
"num_rows", "num_features", "num_classes", "imbalance_ratio", "missing_values", "categorical_features_ratio"
|
| 580 |
-
]
|
| 581 |
-
show_cols = [col for col in dataset_perf_cols if col in domain_per_dataset_merged.columns]
|
| 582 |
-
# Add model filter just like in TabBench Public
|
| 583 |
-
per_dataset_leaderboard = Leaderboard(
|
| 584 |
-
value=domain_per_dataset_merged[show_cols],
|
| 585 |
-
datatype=["str"] + ["number"] * (len(show_cols) - 1),
|
| 586 |
-
select_columns=SelectColumns(
|
| 587 |
-
default_selection=show_cols,
|
| 588 |
-
cant_deselect=["model"] if "model" in show_cols else [],
|
| 589 |
-
label="Select Columns to Display:",
|
| 590 |
-
),
|
| 591 |
-
search_columns=["dataset_name"] if "dataset_name" in show_cols else [],
|
| 592 |
-
hide_columns=[],
|
| 593 |
-
filter_columns=[
|
| 594 |
-
ColumnFilter("model", type="checkboxgroup", label="🤖 Model"),
|
| 595 |
-
],
|
| 596 |
-
interactive=False,
|
| 597 |
-
)
|
| 598 |
|
| 599 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 600 |
|
| 601 |
with open("public_datasets_info.json", "r") as f:
|
| 602 |
public_datasets_info = pd.DataFrame(json.load(f))
|
|
@@ -604,14 +758,25 @@ with gr.Blocks(css=css) as demo:
|
|
| 604 |
with open("model_info.json", "r") as f:
|
| 605 |
model_info = pd.DataFrame(json.load(f))
|
| 606 |
|
| 607 |
-
retail_domain_content = make_domain_content('Retail', 'Retail', public_per_dataset, public_datasets_info, model_info)
|
| 608 |
-
finance_domain_content = make_domain_content('Finance/insurance', 'Finance/insurance', public_per_dataset, public_datasets_info, model_info)
|
| 609 |
-
healthcare_domain_content = make_domain_content('Healthcare', 'Healthcare', public_per_dataset, public_datasets_info, model_info)
|
| 610 |
|
| 611 |
private_content = gr.Column(visible=False)
|
| 612 |
with private_content:
|
| 613 |
-
|
| 614 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 615 |
gr.Markdown('### Features')
|
| 616 |
# -------------------------
|
| 617 |
# Top row: Models & Datasets
|
|
@@ -666,134 +831,216 @@ with gr.Blocks(css=css) as demo:
|
|
| 666 |
wrap=True,
|
| 667 |
type="pandas",
|
| 668 |
)
|
| 669 |
-
gr.Markdown("## 🔍 Explore
|
| 670 |
-
|
| 671 |
-
|
| 672 |
-
|
| 673 |
-
|
| 674 |
-
|
| 675 |
-
|
| 676 |
-
|
| 677 |
-
|
| 678 |
-
|
| 679 |
-
|
| 680 |
-
|
| 681 |
-
|
| 682 |
-
|
| 683 |
-
|
| 684 |
-
|
| 685 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 686 |
)
|
| 687 |
-
# Set industry directly from private_datasets_info.json
|
| 688 |
-
private_per_dataset_merged['industry'] = private_per_dataset_merged['dataset_industry']
|
| 689 |
-
dataset_perf_cols = [
|
| 690 |
-
"dataset_name", "dataset_id", "industry", "dataset_target", "model", "Accuracy", "Precision", "Recall", "F1_score", "AUC", "Elo_score",
|
| 691 |
-
"num_rows", "num_features", "num_classes", "imbalance_ratio", "missing_values", "categorical_features_ratio"
|
| 692 |
-
]
|
| 693 |
-
show_cols = [col for col in dataset_perf_cols] #if col in private_per_dataset_merged.columns]
|
| 694 |
|
| 695 |
-
|
| 696 |
-
|
| 697 |
-
|
| 698 |
-
|
| 699 |
-
|
| 700 |
-
|
| 701 |
-
|
| 702 |
-
|
| 703 |
-
|
| 704 |
-
|
| 705 |
-
|
| 706 |
-
|
| 707 |
-
|
| 708 |
-
min_num_classes = int(private_per_dataset_merged['num_classes'].min())
|
| 709 |
-
max_num_classes = int(private_per_dataset_merged['num_classes'].max())
|
| 710 |
-
with gr.Row():
|
| 711 |
-
classes_slider = gr.Slider(
|
| 712 |
-
minimum=min_num_classes,
|
| 713 |
-
maximum=max_num_classes,
|
| 714 |
-
value=min_num_classes,
|
| 715 |
-
step=1,
|
| 716 |
-
label="Min Number of Classes",
|
| 717 |
-
)
|
| 718 |
-
|
| 719 |
-
# Add model filter to leaderboard
|
| 720 |
-
private_per_dataset_leaderboard = Leaderboard(
|
| 721 |
-
value=private_per_dataset_merged[show_cols],
|
| 722 |
-
datatype=["str"] + ["number"] * (len(show_cols) - 1),
|
| 723 |
-
select_columns=SelectColumns(
|
| 724 |
-
default_selection=show_cols,
|
| 725 |
-
cant_deselect=["model"] if "model" in show_cols else [],
|
| 726 |
-
label="Select Columns to Display:",
|
| 727 |
-
),
|
| 728 |
-
search_columns=["dataset_name"] if "dataset_name" in show_cols else [],
|
| 729 |
-
hide_columns=[],
|
| 730 |
-
filter_columns=[
|
| 731 |
-
ColumnFilter("model", type="checkboxgroup", label="🤖 Model"),
|
| 732 |
-
ColumnFilter("industry", type="checkboxgroup", label="🏭 Industry"),
|
| 733 |
-
],
|
| 734 |
-
interactive=False,
|
| 735 |
)
|
| 736 |
|
| 737 |
-
|
| 738 |
-
|
| 739 |
-
|
| 740 |
-
|
| 741 |
-
]
|
| 742 |
-
|
|
|
|
|
|
|
|
|
|
| 743 |
|
| 744 |
-
|
| 745 |
-
|
| 746 |
-
|
| 747 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 748 |
)
|
| 749 |
-
|
| 750 |
-
|
| 751 |
-
|
| 752 |
-
|
|
|
|
|
|
|
| 753 |
)
|
| 754 |
|
| 755 |
-
|
| 756 |
-
|
| 757 |
-
|
| 758 |
-
|
| 759 |
-
|
| 760 |
-
|
| 761 |
-
|
| 762 |
-
compare_columns = [
|
| 763 |
-
# "num_rows",
|
| 764 |
-
# "num_features",
|
| 765 |
-
"num_classes",
|
| 766 |
-
"imbalance_ratio",
|
| 767 |
-
"skewness",
|
| 768 |
-
"frobenius_norm",
|
| 769 |
-
"min_eigenvalue"
|
| 770 |
-
]
|
| 771 |
|
| 772 |
-
|
| 773 |
-
|
| 774 |
-
|
|
|
|
|
|
|
|
|
|
| 775 |
|
| 776 |
-
|
| 777 |
-
|
| 778 |
-
|
| 779 |
-
|
| 780 |
-
|
| 781 |
-
|
| 782 |
-
|
| 783 |
-
})
|
| 784 |
|
| 785 |
-
|
| 786 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 787 |
|
| 788 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 789 |
|
| 790 |
-
|
| 791 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 792 |
interactive=False,
|
| 793 |
-
wrap=True,
|
| 794 |
type="pandas",
|
|
|
|
| 795 |
)
|
| 796 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 797 |
# # Optional: visual comparison chart
|
| 798 |
# with gr.Accordion("📈 Visualize Differences", open=False):
|
| 799 |
|
|
@@ -829,7 +1076,8 @@ with gr.Blocks(css=css) as demo:
|
|
| 829 |
def show_content(visible_content, selected_btn):
|
| 830 |
# All content blocks and buttons
|
| 831 |
content_blocks = [home_intro, public_content, retail_domain_content, finance_domain_content, healthcare_domain_content, private_content, datamap_content]
|
| 832 |
-
btns = [home_btn, public_btn, domain_retail_btn, domain_finance_btn, domain_healthcare_btn, private_btn, datamap_btn]
|
|
|
|
| 833 |
# Set visibility
|
| 834 |
updates = {block: gr.update(visible=(block == visible_content)) for block in content_blocks}
|
| 835 |
# Set button classes
|
|
@@ -841,35 +1089,50 @@ with gr.Blocks(css=css) as demo:
|
|
| 841 |
return updates
|
| 842 |
|
| 843 |
def show_home():
|
| 844 |
-
return show_content(home_intro,
|
| 845 |
|
| 846 |
def show_public():
|
| 847 |
-
return show_content(public_content,
|
| 848 |
def show_demain_retail():
|
| 849 |
-
return show_content(retail_domain_content,
|
| 850 |
def show_domain_finance():
|
| 851 |
-
return show_content(finance_domain_content,
|
| 852 |
def show_domain_healthcare():
|
| 853 |
-
return show_content(healthcare_domain_content,
|
| 854 |
|
| 855 |
def show_private():
|
| 856 |
-
return show_content(private_content,
|
| 857 |
|
| 858 |
def show_datamap():
|
| 859 |
-
return show_content(datamap_content,
|
| 860 |
|
| 861 |
|
| 862 |
-
outputs = [home_intro, public_content, retail_domain_content, finance_domain_content, healthcare_domain_content, private_content, datamap_content, home_btn, public_btn, domain_retail_btn, domain_finance_btn, domain_healthcare_btn, private_btn, datamap_btn]
|
| 863 |
-
|
| 864 |
-
|
| 865 |
-
|
| 866 |
-
|
| 867 |
-
|
| 868 |
-
|
|
|
|
|
|
|
|
|
|
| 869 |
|
| 870 |
-
|
|
|
|
|
|
|
|
|
|
| 871 |
|
| 872 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 873 |
|
|
|
|
|
|
|
|
|
|
| 874 |
|
| 875 |
-
demo.launch(ssr_mode=False)
|
|
|
|
| 5 |
import json
|
| 6 |
import random
|
| 7 |
|
| 8 |
+
import plotly.express as px
|
| 9 |
+
import seaborn as sns
|
| 10 |
+
from io import BytesIO
|
| 11 |
+
import base64
|
| 12 |
+
|
| 13 |
# TabBench currently supports the following models, with new additions that keep coming:
|
| 14 |
# - **NICL (Neuralk In-Context-Learning)**: Our in-house tabular foundation model based on an in-context learning architecture (proprietary).
|
| 15 |
# - **TabICL**: A transformer-based model that performs feature compression before doing in-context learning on tabular data by conditioning on labeled support examples to predict unseen queries without task-specific training.
|
|
|
|
| 17 |
# - **XGBoost**: An optimized distributed gradient boosting library designed to be highly efficient, flexible, and portable.
|
| 18 |
# - **CatBoost**: A gradient boosting on decision trees library, particularly strong with categorical features.
|
| 19 |
# - **LightGBM**: A fast gradient boosting framework that builds decision trees using histogram-based learning for scalable, high-performance tabular modeling.
|
|
|
|
|
|
|
| 20 |
# - **ModernNCA**: An advanced extension of Neighborhood Component Analysis (NCA) that employs deep neural networks with stochastic neighborhood sampling to learn complex feature interactions for tabular data.
|
| 21 |
# - **RealMLP**: An enhanced MLP optimized with strong default parameters, achieving competitive performance on tabular data.
|
| 22 |
# - **TabM**: A deep learning model that efficiently imitates an ensemble of MLPs, enhancing performance on tabular data tasks without the overhead of training multiple models.
|
| 23 |
# It is capable of processing datasets up to 100× larger and running up to 10× faster than TabPFNv2.
|
| 24 |
|
| 25 |
PUBLIC_DATASETS_TEXT = """
|
| 26 |
+
We curate a list of **195 datasets** from OpenML that span various industries such as **retail, healthcare, finance, and more**.
|
| 27 |
|
| 28 |
🔎 You can easily filter datasets by industry below or explore the industry specific leaderboards via the sidebar.
|
| 29 |
"""
|
|
|
|
| 31 |
MODELS_TEXT = """
|
| 32 |
TabBench currently supports the following models, with more additions planned:
|
| 33 |
- **Tabular foundation models**: NICL, TabICL, TabPFNv2
|
| 34 |
+
- **Tree-based**: XGBoost, CatBoost, LightGBM
|
| 35 |
+
- **Neural networks**: RealMLP, TabM, ModernNCA
|
| 36 |
+
|
| 37 |
+
__Note__ : Tree-based models are also ensembled according to best practices.
|
| 38 |
"""
|
| 39 |
|
| 40 |
BENCHMARKING_TEXT = """
|
|
|
|
| 52 |
METRICS_TEXT = """
|
| 53 |
TabBench uses different types of metrics to evaluate model performance:
|
| 54 |
- **Classic metrics**: Accuracy, Precision, Recall, F1 score, AUC
|
| 55 |
+
- **Ranking metrics**: Rank, Elo score
|
|
|
|
| 56 |
"""
|
| 57 |
|
| 58 |
TITLE = """
|
| 59 |
+
<div style="display:flex; text-align:center">
|
| 60 |
+
<h1 style="margin:0; font-size:34px; font-weight:600;">
|
| 61 |
+
<span style="color:#25ccb9; font-style: bold;">TabBench</span>
|
| 62 |
+
<span>
|
| 63 |
+
: An Industry Benchmark for Tabular Machine Learning
|
| 64 |
+
</span>
|
| 65 |
+
</h1>
|
| 66 |
+
</div>
|
| 67 |
+
|
| 68 |
"""
|
| 69 |
|
| 70 |
INTRODUCTION_TEXT = """
|
| 71 |
+
<p style="font-size: 16px; text-align:center; font-style: italic;">
|
| 72 |
Bridging the gap between academic benchmarks and industry needs
|
| 73 |
</p>
|
| 74 |
"""
|
| 75 |
|
| 76 |
DATA_MAP_TEXT = """
|
| 77 |
+
- 🔎 **Explore different settings of dataset generation**
|
| 78 |
+
- 📈 **Compare Tabular Foundation Models on specific situations and identify strengths & weaknesses**
|
| 79 |
"""
|
| 80 |
|
| 81 |
PUBLIC_BENCHMARK_TEXT = """
|
| 82 |
+
- 📊 **A curation of 195 public datasets** across industries such as retail, healthcare, finance, energy, etc
|
| 83 |
- 🤖 **Evaluations on 10+ powerful models** from gradient boosting and decision trees to tabular foundation models
|
| 84 |
- 💥 **Integration of NICL**, the Neuralk AI tabular foundation model designed for industry-grade use cases
|
| 85 |
- 🏅 **Leaderboards by sector** to discover which models perform best for each industry
|
|
|
|
| 94 |
# rewrite new uses continuously being added
|
| 95 |
|
| 96 |
PRIVATE_DATA_TEXT = """
|
| 97 |
+
We curate a list of **63 proprietary datasets** from different retailers focused on the **use case of product categorization**.
|
| 98 |
|
| 99 |
👚 Each dataset contains product titles, descriptions, and hierarchical product categories with four levels.
|
| 100 |
|
|
|
|
| 106 |
"""
|
| 107 |
|
| 108 |
PRIVATE_MODEL_TEXT = """
|
| 109 |
+
TabBench Enterprise currently supports the following models, with more additions planned:
|
| 110 |
- **Tabular foundation models**: NICL, TabICL, TabPFNv2
|
| 111 |
+
- **Tree-based**: XGBoost
|
| 112 |
+
- **Neural networks**: RealMLP, TabM, ModernNCA
|
| 113 |
"""
|
| 114 |
|
| 115 |
PRIVATE_BENCHMARKING_TEXT = """
|
|
|
|
| 123 |
"""
|
| 124 |
|
| 125 |
PRIVATE_METRICS_TEXT = """
|
| 126 |
+
TabBench Enterprise uses different types of metrics to evaluate model performance:
|
|
|
|
| 127 |
- **Classic metrics**: Accuracy, Precision, Recall, F1 score, AUC
|
| 128 |
+
- **Ranking metrics**: Rank, Elo score
|
|
|
|
| 129 |
"""
|
| 130 |
|
| 131 |
|
|
|
|
| 137 |
year={2025},
|
| 138 |
publisher={GitHub},
|
| 139 |
url={https://github.com/Neuralk-AI/TabBench}
|
| 140 |
+
}
|
| 141 |
+
"""
|
| 142 |
|
| 143 |
|
| 144 |
data = {
|
|
|
|
| 190 |
return df.style.apply(style_column, axis=0)
|
| 191 |
|
| 192 |
|
| 193 |
+
with open("complete_results_acad.json", "r") as f:
|
| 194 |
public_per_dataset = pd.json_normalize(json.load(f))
|
| 195 |
|
| 196 |
+
with open("complete_results_indus.json", "r") as f:
|
| 197 |
private_per_dataset = pd.json_normalize(json.load(f))
|
| 198 |
|
| 199 |
+
with open("qrt.json", "r") as f:
|
| 200 |
+
qrt_scores = json.load(f)
|
| 201 |
+
|
| 202 |
+
# Suppose qrt_scores is a dict like {"NICL": 0.8, "TabPFNv2": 0.6, "XGBoost": 0.5}
|
| 203 |
+
models = ["Models"]+ list(qrt_scores.keys())
|
| 204 |
+
accuracies = ["Test Accuracy"] + list(qrt_scores.values())
|
| 205 |
+
|
| 206 |
+
# Create a DataFrame with two rows: "Model" and "Test Accuracy"
|
| 207 |
+
df_qrt = pd.DataFrame([accuracies], index=["Test Accuracy"], columns=models)
|
| 208 |
+
|
| 209 |
+
# Optional: highlight best accuracy
|
| 210 |
+
def highlight_best_qrt(df):
|
| 211 |
+
styles = pd.DataFrame("", index=df.index, columns=df.columns)
|
| 212 |
+
styles.loc["Test Accuracy", df.loc["Test Accuracy"] == 51.7] = "background-color: gold; color: black;"
|
| 213 |
+
styles.loc["Test Accuracy", df.loc["Test Accuracy"] == 51.58] = "background-color: #a6a6a6; color: black;"
|
| 214 |
+
styles.loc["Test Accuracy", df.loc["Test Accuracy"] == 51.18] = "background-color: #ad5803; color: black;"
|
| 215 |
+
return styles
|
| 216 |
+
|
| 217 |
+
styled_df_qrt = df_qrt.style.apply(highlight_best_qrt, axis=None)
|
| 218 |
+
|
| 219 |
+
def add_top3_ranks(df, metric_cols):
|
| 220 |
+
df = df.copy()
|
| 221 |
+
|
| 222 |
+
for col in metric_cols:
|
| 223 |
+
if col not in df.columns:
|
| 224 |
+
continue
|
| 225 |
+
|
| 226 |
+
ranks = df[col].rank(ascending=False, method="min")
|
| 227 |
+
|
| 228 |
+
df[f"{col}_rank"] = ranks.map(
|
| 229 |
+
lambda r: "🥇" if r == 1 else "🥈" if r == 2 else "🥉" if r == 3 else ""
|
| 230 |
+
)
|
| 231 |
+
|
| 232 |
+
return df
|
| 233 |
+
|
| 234 |
# -------------------------
|
| 235 |
# Leaderboard builder
|
| 236 |
# -------------------------
|
|
|
|
| 267 |
# Gradio UI
|
| 268 |
# -------------------------
|
| 269 |
css = """
|
| 270 |
+
:root {
|
| 271 |
+
color-scheme: light;
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
.lg {
|
| 275 |
font-size: 14px;
|
| 276 |
}
|
|
|
|
| 353 |
html += '</table>'
|
| 354 |
return html
|
| 355 |
|
| 356 |
+
def plot_global_model_ranking_plotly(df, metric="Accuracy"):
|
| 357 |
+
import plotly.graph_objects as go
|
| 358 |
+
|
| 359 |
+
df_sorted = df.sort_values(metric, ascending=True).reset_index(drop=True)
|
| 360 |
+
x_max = df_sorted[metric].max() * 1.1 # 10% buffer
|
| 361 |
+
|
| 362 |
+
fig = go.Figure(go.Bar(
|
| 363 |
+
x=df_sorted[metric],
|
| 364 |
+
y=df_sorted['model'],
|
| 365 |
+
orientation='h',
|
| 366 |
+
text=df_sorted[metric],
|
| 367 |
+
textposition='inside',
|
| 368 |
+
marker=dict(
|
| 369 |
+
color=df_sorted[metric],
|
| 370 |
+
colorscale='Viridis',
|
| 371 |
+
showscale=False
|
| 372 |
+
)
|
| 373 |
+
))
|
| 374 |
+
|
| 375 |
+
fig.update_layout(
|
| 376 |
+
template="plotly_white",
|
| 377 |
+
plot_bgcolor="white",
|
| 378 |
+
paper_bgcolor="white",
|
| 379 |
+
xaxis=dict(title=metric, automargin=True, range=[0, x_max]),
|
| 380 |
+
yaxis=dict(title="Model", automargin=True),
|
| 381 |
+
height=100 + 40 * len(df_sorted),
|
| 382 |
+
margin=dict(l=180, r=40, t=60, b=40),
|
| 383 |
+
)
|
| 384 |
|
| 385 |
+
return fig
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 386 |
|
| 387 |
+
def update_ranking_plot(metric):
|
| 388 |
+
return plot_global_model_ranking_plotly(
|
| 389 |
+
public_model_agg,
|
| 390 |
+
metric=metric
|
| 391 |
+
)
|
|
|
|
|
|
|
| 392 |
|
| 393 |
+
with gr.Blocks(css=css, theme=gr.themes.Default()) as demo:
|
| 394 |
+
# # Sidemenu for benchmark selection
|
| 395 |
+
# with gr.Sidebar(visible=True) as sidebar:
|
| 396 |
+
# gr.Markdown("### Select benchmark")
|
| 397 |
+
# home_btn = gr.Button("🏡 Home", elem_classes=["white-btn", "selected-btn"])
|
| 398 |
+
# # gr.Markdown("---")
|
| 399 |
|
| 400 |
+
# public_btn = gr.Button("🌐 TabBench public", elem_classes=["white-btn"])
|
| 401 |
+
# private_btn = gr.Button("💼 TabBench Enterprise ", elem_classes=["white-btn"])
|
| 402 |
+
|
| 403 |
+
# with gr.Column():
|
| 404 |
+
# with gr.Accordion("🔍 Search by Industry", open=False):
|
| 405 |
+
# domain_retail_btn = gr.Button("🛍️ Retail", elem_classes=["white-btn"])
|
| 406 |
+
# domain_finance_btn = gr.Button("💰 Finance", elem_classes=["white-btn"])
|
| 407 |
+
# domain_healthcare_btn = gr.Button("🏥 Healthcare", elem_classes=["white-btn"])
|
| 408 |
+
# # gr.Markdown("---")
|
| 409 |
+
|
| 410 |
+
|
| 411 |
+
|
| 412 |
+
# datamap_btn = gr.Button("🗺️ Data mapping", elem_classes=["white-btn"])
|
| 413 |
|
| 414 |
|
| 415 |
|
|
|
|
| 420 |
# gr.Markdown("---")
|
| 421 |
gr.Markdown(INTRODUCTION_TEXT)
|
| 422 |
gr.Markdown(" ")
|
| 423 |
+
with gr.Column():
|
| 424 |
+
gr.Markdown("## ⚡ Why TabBench ?")
|
| 425 |
+
gr.Markdown(
|
| 426 |
+
"""
|
| 427 |
+
While useful for research, academic benchmarks rarely capture the challenges faced in industry, offering teams little guidance on which models to trust in production.
|
| 428 |
+
|
| 429 |
+
TabBench is the first Open Source benchmark designed to test both Predictive Foundation Models and Traditional ML Models on real Enterprise data and use cases, Unlike most benchmarks, TabBench evaluates models on real-world scenarios across industries, helping Data scientists confidently choose the models that work best in production, not just in theory.
|
| 430 |
+
Real-workd data is complex, messy and high-dimensional; TabBench is particularly useful in showcasing the performance of SOTA Predictive Foundation models as well as traditional ML tools in this context.
|
| 431 |
+
"""
|
| 432 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 433 |
|
| 434 |
+
gr.Markdown(' ')
|
| 435 |
+
gr.Markdown("## 🚀 Search by Benchmark Type")
|
| 436 |
+
with gr.Row():
|
| 437 |
+
with gr.Column():
|
| 438 |
+
with gr.Accordion("🌐 TabBench Public", open=False):
|
| 439 |
+
gr.Markdown(PUBLIC_BENCHMARK_TEXT)
|
| 440 |
+
public_btn_home = gr.Button("Go to TabBench Public", elem_classes=["white-btn"])
|
| 441 |
+
with gr.Column():
|
| 442 |
+
with gr.Accordion("💼 TabBench Enterprise", open=False):
|
| 443 |
+
gr.Markdown(PRIVATE_BENCHMARK_TEXT)
|
| 444 |
+
private_btn_home = gr.Button("Go to TabBench Enterprise", elem_classes=["white-btn"])
|
| 445 |
+
with gr.Column():
|
| 446 |
+
with gr.Accordion("🤖 Understanding Tabular Foundation Models", open=False):
|
| 447 |
+
gr.Markdown(DATA_MAP_TEXT)
|
| 448 |
+
datamap_btn_home = gr.Button("Go to TabFMs space", elem_classes=["white-btn"])
|
| 449 |
+
# ,gr.DataFrame(df_comparison, interactive=False, wrap=True, type="pandas")
|
| 450 |
+
|
| 451 |
+
public_model_agg = public_per_dataset.groupby('model')[['Accuracy', 'Precision', 'Recall', 'F1_score', 'AUC', 'Elo_score']].mean().reset_index()
|
| 452 |
+
public_model_agg = public_model_agg.round(3)
|
| 453 |
+
# ranking_fig = plot_global_model_ranking_plotly(public_model_agg, metric="Accuracy")
|
| 454 |
+
# Search by industry section
|
| 455 |
+
gr.Markdown(' ')
|
| 456 |
+
gr.Markdown("## 🔍 Search by Industry")
|
| 457 |
+
with gr.Row():
|
| 458 |
+
finance_btn_home = gr.Button("💰 Finance", elem_classes=["white-btn"])
|
| 459 |
+
healthcare_btn_home = gr.Button("🏥 Healthcare", elem_classes=["white-btn"])
|
| 460 |
+
retail_btn_home = gr.Button("🛍️ Retail", elem_classes=["white-btn"])
|
| 461 |
+
|
| 462 |
+
gr.Markdown(' ')
|
| 463 |
+
gr.Markdown("## 🏆 Overview of the Leaderboard *(Evaluation on Public Datasets)*")
|
| 464 |
+
gr.Markdown(' ')
|
| 465 |
+
# ranking_fig = plot_global_model_ranking_plotly(
|
| 466 |
+
# public_model_agg,
|
| 467 |
+
# metric="Accuracy",
|
| 468 |
+
# )
|
| 469 |
+
|
| 470 |
+
# gr.Plot(ranking_fig)
|
| 471 |
+
|
| 472 |
+
with gr.Row():
|
| 473 |
+
metric_selector = gr.Dropdown(
|
| 474 |
+
choices=["Accuracy", "Precision", "Recall", "F1_score", "AUC", "Elo_score"],
|
| 475 |
+
value="Accuracy",
|
| 476 |
+
label="📊 Metric to display"
|
| 477 |
+
)
|
| 478 |
|
| 479 |
+
ranking_plot = gr.Plot(
|
| 480 |
+
value=plot_global_model_ranking_plotly(
|
| 481 |
+
public_model_agg,
|
| 482 |
+
metric="Accuracy"
|
| 483 |
+
)
|
| 484 |
+
)
|
| 485 |
|
| 486 |
+
metric_selector.change(
|
| 487 |
+
fn=update_ranking_plot,
|
| 488 |
+
inputs=metric_selector,
|
| 489 |
+
outputs=ranking_plot
|
| 490 |
+
)
|
| 491 |
+
|
| 492 |
|
| 493 |
public_content = gr.Column(visible=False)
|
| 494 |
with public_content:
|
| 495 |
+
home_btn_public = gr.Button("🏡 Home", elem_classes=["white-btn", "selected-btn"])
|
| 496 |
+
label_md = gr.Markdown("# 🥇 TabBench Public Leaderboard - All Industries")
|
| 497 |
gr.Markdown('### Features')
|
| 498 |
# -------------------------
|
| 499 |
# Top row: Models & Datasets
|
|
|
|
| 557 |
gr.Markdown(f"Estimated average model performance over {num_unique_datasets} datasets.")
|
| 558 |
# Use per-model averages for leaderboard, allow filtering by model_type
|
| 559 |
per_model_leaderboard = init_leaderboard(public_model_agg, include_model_type_filter=True, industry_filter=False)
|
| 560 |
+
|
| 561 |
+
|
| 562 |
with gr.Tab("📊 Performance by dataset"):
|
| 563 |
+
# Load dataset metadata
|
|
|
|
| 564 |
with open("public_datasets_info.json", "r") as f:
|
| 565 |
public_datasets_info = pd.DataFrame(json.load(f))
|
| 566 |
+
|
| 567 |
public_per_dataset_merged = public_per_dataset.merge(
|
| 568 |
public_datasets_info,
|
| 569 |
left_on=["dataset_name", "dataset_id"],
|
| 570 |
right_on=["dataset_name", "dataset_id"],
|
| 571 |
how="left"
|
| 572 |
)
|
|
|
|
|
|
|
| 573 |
|
| 574 |
+
public_per_dataset_merged["industry"] = public_per_dataset_merged["dataset_industry"]
|
| 575 |
+
public_per_dataset_merged = public_per_dataset_merged.dropna(subset=["industry"])
|
| 576 |
+
|
| 577 |
+
# --- Sliders and controls ---
|
| 578 |
+
min_features, max_features = int(public_per_dataset_merged["features"].min()), int(public_per_dataset_merged["features"].max())
|
| 579 |
+
min_rows, max_rows = int(public_per_dataset_merged["rows"].min()), int(public_per_dataset_merged["rows"].max())
|
| 580 |
+
min_pct_cat, max_pct_cat = float(public_per_dataset_merged["pct_cat"].min()), float(public_per_dataset_merged["pct_cat"].max())
|
| 581 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 582 |
with gr.Row():
|
| 583 |
with gr.Column():
|
| 584 |
features_slider = gr.Slider(
|
| 585 |
+
minimum=min_features,
|
| 586 |
+
maximum=max_features,
|
| 587 |
+
value=min_features,
|
| 588 |
step=1,
|
| 589 |
label="Min Number of Features",
|
| 590 |
)
|
| 591 |
+
rows_slider = gr.Slider(
|
| 592 |
+
minimum=min_rows,
|
| 593 |
+
maximum=max_rows,
|
| 594 |
+
value=min_rows,
|
| 595 |
+
step=100,
|
| 596 |
+
label="Min Number of Rows",
|
| 597 |
+
)
|
| 598 |
+
pct_cat_slider = gr.Slider(
|
| 599 |
+
minimum=min_pct_cat,
|
| 600 |
+
maximum=max_pct_cat,
|
| 601 |
+
value=min_pct_cat,
|
| 602 |
+
step=0.01,
|
| 603 |
+
label="Min % Categorical Features",
|
| 604 |
+
)
|
| 605 |
+
|
| 606 |
with gr.Column():
|
| 607 |
+
task_button = gr.Radio(
|
| 608 |
+
choices=["Binary", "Multi-class"],
|
| 609 |
+
value="Binary",
|
| 610 |
+
label="Task Type",
|
| 611 |
+
)
|
| 612 |
+
|
| 613 |
+
# --- Columns ---
|
| 614 |
+
dataset_perf_cols = [
|
| 615 |
+
"model",
|
| 616 |
+
"Accuracy",
|
| 617 |
+
"Precision",
|
| 618 |
+
"Recall",
|
| 619 |
+
"F1_score",
|
| 620 |
+
"AUC",
|
| 621 |
+
"Elo_score",
|
| 622 |
+
]
|
| 623 |
+
|
| 624 |
+
# --- Filtering & aggregation ---
|
| 625 |
+
def filter_and_aggregate_models(min_features, min_rows, min_pct_cat, task_type):
|
| 626 |
+
task_val = 0 if task_type == "Binary" else 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 627 |
|
|
|
|
| 628 |
filtered = public_per_dataset_merged[
|
| 629 |
+
(public_per_dataset_merged["features"] >= min_features)
|
| 630 |
+
& (public_per_dataset_merged["rows"] >= min_rows)
|
| 631 |
+
& (public_per_dataset_merged["pct_cat"] >= min_pct_cat)
|
| 632 |
+
& (public_per_dataset_merged["task"] == task_val)
|
| 633 |
]
|
|
|
|
| 634 |
|
| 635 |
+
if filtered.empty:
|
| 636 |
+
return pd.DataFrame(columns=dataset_perf_cols)
|
| 637 |
+
|
| 638 |
+
per_model_avg = (
|
| 639 |
+
filtered
|
| 640 |
+
.groupby("model")[dataset_perf_cols[1:]]
|
| 641 |
+
.mean()
|
| 642 |
+
.reset_index()
|
| 643 |
+
)
|
| 644 |
+
|
| 645 |
+
return highlight_max(per_model_avg)
|
| 646 |
+
|
| 647 |
+
# --- Styled table ---
|
| 648 |
+
performance_table = gr.DataFrame(
|
| 649 |
+
value=filter_and_aggregate_models(
|
| 650 |
+
min_features,
|
| 651 |
+
min_rows,
|
| 652 |
+
min_pct_cat,
|
| 653 |
+
"Binary",
|
| 654 |
+
),
|
| 655 |
+
interactive=False,
|
| 656 |
+
wrap=True,
|
| 657 |
+
type="pandas",
|
| 658 |
)
|
| 659 |
|
| 660 |
+
# --- Bind controls ---
|
| 661 |
+
inputs = [features_slider, rows_slider, pct_cat_slider, task_button]
|
| 662 |
+
for control in inputs:
|
| 663 |
+
control.change(
|
| 664 |
+
fn=filter_and_aggregate_models,
|
| 665 |
+
inputs=inputs,
|
| 666 |
+
outputs=performance_table,
|
| 667 |
+
)
|
| 668 |
+
|
| 669 |
|
| 670 |
def make_domain_content(industry, label, public_per_dataset, public_datasets_info, model_info):
|
| 671 |
domain_content = gr.Column(visible=False)
|
| 672 |
with domain_content:
|
| 673 |
+
home_btn_domain = gr.Button("🏡 Home", elem_classes=["white-btn", "selected-btn"])
|
| 674 |
gr.Markdown(f"## 🥇 {label} Benchmark Leaderboard")
|
| 675 |
+
|
| 676 |
+
# Filter datasets for this industry
|
|
|
|
| 677 |
domain_per_dataset = public_per_dataset.merge(
|
| 678 |
public_datasets_info[['dataset_name', 'dataset_id', 'dataset_industry']],
|
| 679 |
on=['dataset_name', 'dataset_id'],
|
|
|
|
| 681 |
)
|
| 682 |
domain_per_dataset = domain_per_dataset[domain_per_dataset['dataset_industry'] == industry]
|
| 683 |
|
| 684 |
+
# Compute model overview
|
|
|
|
|
|
|
| 685 |
model_agg = domain_per_dataset.groupby('model')[['Accuracy', 'Precision', 'Recall', 'F1_score', 'AUC', 'Elo_score']].mean().reset_index()
|
| 686 |
model_agg = model_agg.round(3)
|
| 687 |
model_agg = model_agg.merge(model_info[["model_name", "model_type"]], left_on="model", right_on="model_name", how="left").drop(columns=["model_name"])
|
| 688 |
cols = ["model", "model_type"] + [c for c in model_agg.columns if c not in ["model", "model_type"]]
|
| 689 |
model_agg = model_agg[cols]
|
|
|
|
| 690 |
model_agg = model_agg.sort_values(by=["model"], key=lambda x: x != "NICL").reset_index(drop=True)
|
| 691 |
gr.DataFrame(
|
| 692 |
value=highlight_max(model_agg),
|
|
|
|
| 695 |
type="pandas",
|
| 696 |
)
|
| 697 |
|
| 698 |
+
gr.Markdown("## 🔍 Explore performance by dataset")
|
|
|
|
|
|
|
|
|
|
| 699 |
|
| 700 |
+
# Merge for full dataset info
|
| 701 |
domain_per_dataset_merged = domain_per_dataset.merge(
|
| 702 |
public_datasets_info,
|
| 703 |
left_on=["dataset_name", "dataset_id"],
|
| 704 |
right_on=["dataset_name", "dataset_id"],
|
| 705 |
how="left"
|
| 706 |
)
|
|
|
|
|
|
|
| 707 |
domain_per_dataset_merged['industry'] = domain_per_dataset_merged['dataset_industry_y']
|
|
|
|
| 708 |
domain_per_dataset_merged = domain_per_dataset_merged[domain_per_dataset_merged['industry'] == industry]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 709 |
|
| 710 |
+
# Columns for dataset-wise leaderboard
|
| 711 |
+
dataset_perf_cols = [
|
| 712 |
+
"model",
|
| 713 |
+
"Accuracy",
|
| 714 |
+
"Precision",
|
| 715 |
+
"Recall",
|
| 716 |
+
"F1_score",
|
| 717 |
+
"AUC",
|
| 718 |
+
"Elo_score",
|
| 719 |
+
]
|
| 720 |
+
num_unique_datasets = domain_per_dataset_merged['dataset_id'].nunique() if 'dataset_id' in domain_per_dataset_merged.columns else 0
|
| 721 |
+
gr.Markdown(f"Estimated average model performance over {num_unique_datasets} datasets.")
|
| 722 |
+
# Available datasets
|
| 723 |
+
dataset_ids = sorted(domain_per_dataset_merged["dataset_name"].dropna().unique().tolist())
|
| 724 |
+
|
| 725 |
+
dataset_dropdown = gr.Dropdown(
|
| 726 |
+
choices=dataset_ids,
|
| 727 |
+
label="📂 Select a dataset",
|
| 728 |
+
value=dataset_ids[0] if dataset_ids else None,
|
| 729 |
+
)
|
| 730 |
+
|
| 731 |
+
dataset_leaderboard = gr.DataFrame(
|
| 732 |
+
value=highlight_max(domain_per_dataset_merged[
|
| 733 |
+
domain_per_dataset_merged["dataset_name"] == dataset_ids[0]
|
| 734 |
+
][dataset_perf_cols]) if dataset_ids else pd.DataFrame(),
|
| 735 |
+
interactive=False,
|
| 736 |
+
wrap=True,
|
| 737 |
+
type="pandas",
|
| 738 |
+
)
|
| 739 |
+
|
| 740 |
+
# Callback to update leaderboard
|
| 741 |
+
def update_dataset_leaderboard(selected_dataset_id):
|
| 742 |
+
return highlight_max(domain_per_dataset_merged[
|
| 743 |
+
domain_per_dataset_merged["dataset_name"] == selected_dataset_id
|
| 744 |
+
][dataset_perf_cols])
|
| 745 |
+
|
| 746 |
+
dataset_dropdown.change(
|
| 747 |
+
fn=update_dataset_leaderboard,
|
| 748 |
+
inputs=dataset_dropdown,
|
| 749 |
+
outputs=dataset_leaderboard,
|
| 750 |
+
)
|
| 751 |
+
|
| 752 |
+
return domain_content, home_btn_domain
|
| 753 |
+
|
| 754 |
|
| 755 |
with open("public_datasets_info.json", "r") as f:
|
| 756 |
public_datasets_info = pd.DataFrame(json.load(f))
|
|
|
|
| 758 |
with open("model_info.json", "r") as f:
|
| 759 |
model_info = pd.DataFrame(json.load(f))
|
| 760 |
|
| 761 |
+
retail_domain_content, home_btn_retail = make_domain_content('Retail', 'Retail', public_per_dataset, public_datasets_info, model_info)
|
| 762 |
+
finance_domain_content, home_btn_finance = make_domain_content('Finance/insurance', 'Finance/insurance', public_per_dataset, public_datasets_info, model_info)
|
| 763 |
+
healthcare_domain_content, home_btn_health = make_domain_content('Healthcare', 'Healthcare', public_per_dataset, public_datasets_info, model_info)
|
| 764 |
|
| 765 |
private_content = gr.Column(visible=False)
|
| 766 |
with private_content:
|
| 767 |
+
home_btn_private = gr.Button("🏡 Home", elem_classes=["white-btn", "selected-btn"])
|
| 768 |
+
label_md2 = gr.Markdown("# 🥇 TabBench Enterprise Leaderboard")
|
| 769 |
+
gr.Markdown("## Example: comparative results on QRT Data Challenge")
|
| 770 |
+
gr.Markdown("" \
|
| 771 |
+
"Qube Research & Technologies (QRT) is a leading global quantitative and systematic investment manager. Their use of real-world business data to sponsor a data challenge with ENS Paris provided a real-world opportunity to highlight the value of Neuralk's Predictive Foundation Models on Enterprise financial data. " \
|
| 772 |
+
"The proposed challenge aimed predicting the return of a stock in the US market using historical data over a recent period of 20 days. More info on the challenge [here](https://challengedata.ens.fr/challenges/23)."
|
| 773 |
+
)
|
| 774 |
+
gr.DataFrame(
|
| 775 |
+
value=styled_df_qrt,
|
| 776 |
+
interactive=False,
|
| 777 |
+
wrap=True,
|
| 778 |
+
type="pandas",
|
| 779 |
+
)
|
| 780 |
gr.Markdown('### Features')
|
| 781 |
# -------------------------
|
| 782 |
# Top row: Models & Datasets
|
|
|
|
| 831 |
wrap=True,
|
| 832 |
type="pandas",
|
| 833 |
)
|
| 834 |
+
gr.Markdown("## 🔍 Explore performance by dataset")
|
| 835 |
+
|
| 836 |
+
# Columns to display
|
| 837 |
+
dataset_perf_cols = [
|
| 838 |
+
"model",
|
| 839 |
+
"Accuracy",
|
| 840 |
+
"Precision",
|
| 841 |
+
"Recall",
|
| 842 |
+
"F1_score",
|
| 843 |
+
"AUC",
|
| 844 |
+
"Elo_score",
|
| 845 |
+
]
|
| 846 |
+
|
| 847 |
+
# Available datasets
|
| 848 |
+
dataset_ids = (
|
| 849 |
+
private_per_dataset["dataset_id"]
|
| 850 |
+
.dropna()
|
| 851 |
+
.unique()
|
| 852 |
+
.tolist()
|
| 853 |
+
)
|
| 854 |
+
|
| 855 |
+
dataset_ids = sorted(dataset_ids)
|
| 856 |
+
|
| 857 |
+
dataset_dropdown = gr.Dropdown(
|
| 858 |
+
choices=dataset_ids,
|
| 859 |
+
label="📂 Select a dataset",
|
| 860 |
+
value=dataset_ids[0],
|
| 861 |
+
)
|
| 862 |
+
|
| 863 |
+
dataset_leaderboard = gr.DataFrame(
|
| 864 |
+
value=highlight_max(private_per_dataset[
|
| 865 |
+
private_per_dataset["dataset_id"] == dataset_ids[0]
|
| 866 |
+
][dataset_perf_cols]),
|
| 867 |
+
interactive=False,
|
| 868 |
+
wrap=True,
|
| 869 |
+
type="pandas",
|
| 870 |
+
)
|
| 871 |
+
|
| 872 |
+
def update_dataset_leaderboard(selected_dataset_id):
|
| 873 |
+
return highlight_max(private_per_dataset[
|
| 874 |
+
private_per_dataset["dataset_id"] == selected_dataset_id
|
| 875 |
+
][dataset_perf_cols])
|
| 876 |
+
|
| 877 |
+
dataset_dropdown.change(
|
| 878 |
+
fn=update_dataset_leaderboard,
|
| 879 |
+
inputs=dataset_dropdown,
|
| 880 |
+
outputs=dataset_leaderboard,
|
| 881 |
+
)
|
| 882 |
+
|
| 883 |
+
|
| 884 |
+
datamap_content = gr.Column(visible=False)
|
| 885 |
+
with datamap_content:
|
| 886 |
+
home_btn_datamap = gr.Button("🏡 Home", elem_classes=["white-btn", "selected-btn"])
|
| 887 |
+
gr.Markdown("# 🤖 Understanding tabular Foundation Models")
|
| 888 |
+
gr.Markdown(" ")
|
| 889 |
+
gr.Markdown(
|
| 890 |
+
"Side study using scikit-learn's make_classification data generation function to have an in-depth understanding of Tabular Foundation Models strengths and weaknesses under specific data characteristics.")
|
| 891 |
+
|
| 892 |
+
gr.Markdown('')
|
| 893 |
+
PARQUET_PATH = "make_classif-parameter_space.parquet"
|
| 894 |
+
df_sklearn = pd.read_parquet(PARQUET_PATH)
|
| 895 |
+
|
| 896 |
+
# =====================
|
| 897 |
+
# Basic preprocessing
|
| 898 |
+
# =====================
|
| 899 |
+
|
| 900 |
+
MODEL_COLS = {
|
| 901 |
+
"NICL": "acc_NICL",
|
| 902 |
+
"TABPFN": "acc_TABPFN",
|
| 903 |
+
"TABICL": "acc_TABICL",
|
| 904 |
+
"RF": "acc_RF",
|
| 905 |
+
}
|
| 906 |
+
|
| 907 |
+
# =====================
|
| 908 |
+
# Slider ranges
|
| 909 |
+
# =====================
|
| 910 |
+
min_features, max_features = int(df_sklearn["n_features"].min()), int(df_sklearn["n_features"].max())
|
| 911 |
+
min_samples, max_samples = int(df_sklearn["n_samples"].min()), int(df_sklearn["n_samples"].max())
|
| 912 |
+
min_classes, max_classes = int(df_sklearn["n_classes"].min()), int(df_sklearn["n_classes"].max())
|
| 913 |
+
min_sep, max_sep = float(df_sklearn["class_sep"].min()), float(df_sklearn["class_sep"].max())
|
| 914 |
+
|
| 915 |
+
# =====================
|
| 916 |
+
# Filtering + aggregation
|
| 917 |
+
# =====================
|
| 918 |
+
def filter_and_aggregate(
|
| 919 |
+
f_min, f_max,
|
| 920 |
+
s_min, s_max,
|
| 921 |
+
c_min, c_max,
|
| 922 |
+
sep_min, sep_max,
|
| 923 |
+
):
|
| 924 |
+
# sécurité si sliders se croisent
|
| 925 |
+
if f_min > f_max or s_min > s_max or c_min > c_max or sep_min > sep_max:
|
| 926 |
+
return (
|
| 927 |
+
pd.DataFrame(columns=["Model", "Accuracy"]),
|
| 928 |
+
"⚠️ Invalid interval selection",
|
| 929 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 930 |
|
| 931 |
+
filtered = df_sklearn[
|
| 932 |
+
df_sklearn["n_features"].between(f_min, f_max)
|
| 933 |
+
& df_sklearn["n_samples"].between(s_min, s_max)
|
| 934 |
+
& df_sklearn["n_classes"].between(c_min, c_max)
|
| 935 |
+
& df_sklearn["class_sep"].between(sep_min, sep_max)
|
| 936 |
+
]
|
| 937 |
+
|
| 938 |
+
n_datasets = len(filtered)
|
| 939 |
+
|
| 940 |
+
if filtered.empty:
|
| 941 |
+
return (
|
| 942 |
+
pd.DataFrame(columns=["Model", "Accuracy"]),
|
| 943 |
+
"⚠️ No datasets match the current filters.",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 944 |
)
|
| 945 |
|
| 946 |
+
rows = []
|
| 947 |
+
for model, col in MODEL_COLS.items():
|
| 948 |
+
rows.append({
|
| 949 |
+
"Model": model,
|
| 950 |
+
"Accuracy": filtered[col].mean(),
|
| 951 |
+
})
|
| 952 |
+
|
| 953 |
+
out = highlight_max(pd.DataFrame(rows))
|
| 954 |
+
return out, f"📦 **{n_datasets} datasets** considered"
|
| 955 |
|
| 956 |
+
|
| 957 |
+
gr.Markdown("## 📊 Average Model Accuracy by Dataset Properties")
|
| 958 |
+
|
| 959 |
+
with gr.Row():
|
| 960 |
+
with gr.Column():
|
| 961 |
+
features_min = gr.Slider(
|
| 962 |
+
min_features, max_features,
|
| 963 |
+
value=min_features,
|
| 964 |
+
step=1,
|
| 965 |
+
label="Min number of features"
|
| 966 |
)
|
| 967 |
+
|
| 968 |
+
features_max = gr.Slider(
|
| 969 |
+
min_features, max_features,
|
| 970 |
+
value=max_features,
|
| 971 |
+
step=1,
|
| 972 |
+
label="Max number of features"
|
| 973 |
)
|
| 974 |
|
| 975 |
+
with gr.Column():
|
| 976 |
+
samples_min = gr.Slider(
|
| 977 |
+
min_samples, max_samples,
|
| 978 |
+
value=min_samples,
|
| 979 |
+
step=10,
|
| 980 |
+
label="Min number of samples"
|
| 981 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 982 |
|
| 983 |
+
samples_max = gr.Slider(
|
| 984 |
+
min_samples, max_samples,
|
| 985 |
+
value=max_samples,
|
| 986 |
+
step=10,
|
| 987 |
+
label="Max number of samples"
|
| 988 |
+
)
|
| 989 |
|
| 990 |
+
with gr.Column():
|
| 991 |
+
classes_min = gr.Slider(
|
| 992 |
+
min_classes, max_classes,
|
| 993 |
+
value=min_classes,
|
| 994 |
+
step=1,
|
| 995 |
+
label="Min number of classes"
|
| 996 |
+
)
|
|
|
|
| 997 |
|
| 998 |
+
classes_max = gr.Slider(
|
| 999 |
+
min_classes, max_classes,
|
| 1000 |
+
value=max_classes,
|
| 1001 |
+
step=1,
|
| 1002 |
+
label="Max number of classes"
|
| 1003 |
+
)
|
| 1004 |
|
| 1005 |
+
with gr.Column():
|
| 1006 |
+
sep_min = gr.Slider(
|
| 1007 |
+
min_sep, max_sep,
|
| 1008 |
+
value=min_sep,
|
| 1009 |
+
step=0.01,
|
| 1010 |
+
label="Min class separation"
|
| 1011 |
+
)
|
| 1012 |
|
| 1013 |
+
sep_max = gr.Slider(
|
| 1014 |
+
min_sep, max_sep,
|
| 1015 |
+
value=max_sep,
|
| 1016 |
+
step=0.01,
|
| 1017 |
+
label="Max class separation"
|
| 1018 |
+
)
|
| 1019 |
+
|
| 1020 |
+
perf_table = gr.DataFrame(
|
| 1021 |
interactive=False,
|
|
|
|
| 1022 |
type="pandas",
|
| 1023 |
+
wrap=True,
|
| 1024 |
)
|
| 1025 |
|
| 1026 |
+
count_md = gr.Markdown("")
|
| 1027 |
+
|
| 1028 |
+
|
| 1029 |
+
controls = [
|
| 1030 |
+
features_min, features_max,
|
| 1031 |
+
samples_min, samples_max,
|
| 1032 |
+
classes_min, classes_max,
|
| 1033 |
+
sep_min, sep_max,
|
| 1034 |
+
]
|
| 1035 |
+
|
| 1036 |
+
for c in controls:
|
| 1037 |
+
c.change(
|
| 1038 |
+
fn=filter_and_aggregate,
|
| 1039 |
+
inputs=controls,
|
| 1040 |
+
outputs=[perf_table, count_md],
|
| 1041 |
+
)
|
| 1042 |
+
|
| 1043 |
+
|
| 1044 |
# # Optional: visual comparison chart
|
| 1045 |
# with gr.Accordion("📈 Visualize Differences", open=False):
|
| 1046 |
|
|
|
|
| 1076 |
def show_content(visible_content, selected_btn):
|
| 1077 |
# All content blocks and buttons
|
| 1078 |
content_blocks = [home_intro, public_content, retail_domain_content, finance_domain_content, healthcare_domain_content, private_content, datamap_content]
|
| 1079 |
+
## btns = [home_btn, public_btn, domain_retail_btn, domain_finance_btn, domain_healthcare_btn, private_btn, datamap_btn]
|
| 1080 |
+
btns = [public_btn_home, home_btn_public, home_btn_retail, home_btn_finance, home_btn_health, home_btn_private, home_btn_datamap]
|
| 1081 |
# Set visibility
|
| 1082 |
updates = {block: gr.update(visible=(block == visible_content)) for block in content_blocks}
|
| 1083 |
# Set button classes
|
|
|
|
| 1089 |
return updates
|
| 1090 |
|
| 1091 |
def show_home():
|
| 1092 |
+
return show_content(home_intro, public_btn_home)
|
| 1093 |
|
| 1094 |
def show_public():
|
| 1095 |
+
return show_content(public_content, home_btn_public)
|
| 1096 |
def show_demain_retail():
|
| 1097 |
+
return show_content(retail_domain_content, home_btn_retail)
|
| 1098 |
def show_domain_finance():
|
| 1099 |
+
return show_content(finance_domain_content, home_btn_finance)
|
| 1100 |
def show_domain_healthcare():
|
| 1101 |
+
return show_content(healthcare_domain_content, home_btn_health)
|
| 1102 |
|
| 1103 |
def show_private():
|
| 1104 |
+
return show_content(private_content, home_btn_private)
|
| 1105 |
|
| 1106 |
def show_datamap():
|
| 1107 |
+
return show_content(datamap_content, home_btn_datamap)
|
| 1108 |
|
| 1109 |
|
| 1110 |
+
# outputs = [home_intro, public_content, retail_domain_content, finance_domain_content, healthcare_domain_content, private_content, datamap_content, home_btn, public_btn, domain_retail_btn, domain_finance_btn, domain_healthcare_btn, private_btn, datamap_btn]
|
| 1111 |
+
outputs = [home_intro, public_content, retail_domain_content, finance_domain_content, healthcare_domain_content, private_content, datamap_content, public_btn_home, home_btn_public, home_btn_retail, home_btn_finance, home_btn_health, home_btn_private, home_btn_datamap]
|
| 1112 |
+
# home_btn.click(fn=show_home, inputs=None, outputs=outputs)
|
| 1113 |
+
home_btn_retail.click(fn=show_home, inputs=None, outputs=outputs)
|
| 1114 |
+
home_btn_finance.click(fn=show_home, inputs=None, outputs=outputs)
|
| 1115 |
+
home_btn_health.click(fn=show_home, inputs=None, outputs=outputs)
|
| 1116 |
+
home_btn_public.click(fn=show_home, inputs=None, outputs=outputs)
|
| 1117 |
+
home_btn_private.click(fn=show_home, inputs=None, outputs=outputs)
|
| 1118 |
+
home_btn_datamap.click(fn=show_home, inputs=None, outputs=outputs)
|
| 1119 |
+
|
| 1120 |
|
| 1121 |
+
# public_btn.click(fn=show_public, inputs=None, outputs=outputs)
|
| 1122 |
+
# domain_retail_btn.click(fn=show_demain_retail, inputs=None, outputs=outputs)
|
| 1123 |
+
# domain_finance_btn.click(fn=show_domain_finance, inputs=None, outputs=outputs)
|
| 1124 |
+
# domain_healthcare_btn.click(fn=show_domain_healthcare, inputs=None, outputs=outputs)
|
| 1125 |
|
| 1126 |
+
# private_btn.click(fn=show_private, inputs=None, outputs=outputs)
|
| 1127 |
+
|
| 1128 |
+
# datamap_btn.click(fn=show_datamap, inputs=None, outputs=outputs)
|
| 1129 |
+
|
| 1130 |
+
public_btn_home.click(fn=show_public, inputs=None, outputs=outputs)
|
| 1131 |
+
private_btn_home.click(fn=show_private, inputs=None, outputs=outputs)
|
| 1132 |
+
datamap_btn_home.click(fn=show_datamap, inputs=None, outputs=outputs)
|
| 1133 |
|
| 1134 |
+
finance_btn_home.click(fn=show_domain_finance, inputs=None, outputs=outputs)
|
| 1135 |
+
healthcare_btn_home.click(fn=show_domain_healthcare, inputs=None, outputs=outputs)
|
| 1136 |
+
retail_btn_home.click(fn=show_demain_retail, inputs=None, outputs=outputs)
|
| 1137 |
|
| 1138 |
+
demo.launch(ssr_mode=False, share=False)
|
complete_results_acad.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
complete_results_indus.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
complete_results_indus_noxgboost.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
workflow.png → make_classif-parameter_space.parquet
RENAMED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:0959a1f1204634a61bbc732fdeac0f1397755f1daadcd9e72b869f3c58cf4d99
|
| 3 |
+
size 5623086
|
model_info.json
CHANGED
|
@@ -1,56 +1,61 @@
|
|
| 1 |
[
|
| 2 |
{
|
| 3 |
-
"model_name": "
|
| 4 |
"model_type": "Tabular Foundation Model",
|
| 5 |
"model_description": "Our in-house tabular foundation model based on an in-context learning architecture."
|
| 6 |
},
|
| 7 |
{
|
| 8 |
-
"model_name": "
|
| 9 |
"model_type": "Decision Trees",
|
| 10 |
-
"model_description": "A
|
| 11 |
},
|
| 12 |
{
|
| 13 |
-
"model_name": "
|
| 14 |
-
"model_type": "
|
| 15 |
-
"model_description": "A
|
| 16 |
},
|
| 17 |
{
|
| 18 |
-
"model_name": "
|
| 19 |
"model_type": "Decision Trees",
|
| 20 |
-
"model_description": "A
|
| 21 |
},
|
| 22 |
{
|
| 23 |
-
"model_name": "
|
| 24 |
"model_type": "Decision Trees",
|
| 25 |
-
"model_description": "A high-performance gradient boosting algorithm that handles categorical features natively and requires minimal preprocessing."
|
| 26 |
},
|
| 27 |
{
|
| 28 |
-
"model_name": "
|
| 29 |
"model_type": "Neural Networks",
|
| 30 |
"model_description": "An advanced extension of Neighborhood Component Analysis (NCA) that employs deep neural networks with stochastic neighborhood sampling to learn complex feature interactions for tabular data."
|
| 31 |
},
|
| 32 |
{
|
| 33 |
-
"model_name": "
|
| 34 |
"model_type": "Tabular Foundation Model",
|
| 35 |
"model_description": "A transformer-based model that performs in-context learning by approximating Bayesian inference for tabular classification on small datasets."
|
| 36 |
},
|
| 37 |
{
|
| 38 |
-
"model_name": "
|
| 39 |
-
"model_type": "
|
| 40 |
-
"model_description": "An enhanced MLP optimized with strong default parameters, achieving competitive performance on tabular data."
|
| 41 |
},
|
| 42 |
{
|
| 43 |
-
"model_name": "
|
| 44 |
"model_type": "Tabular Foundation Model",
|
| 45 |
"model_description": "A transformer-based model that performs feature compression before doing in-context learning on tabular data by conditioning on labeled support examples to predict unseen queries without task-specific training."
|
| 46 |
},
|
| 47 |
{
|
| 48 |
-
"model_name": "
|
| 49 |
"model_type": "Decision Trees",
|
| 50 |
"model_description": "A fast gradient boosting framework that builds decision trees using histogram-based learning for scalable, high-performance tabular modeling."
|
| 51 |
},
|
| 52 |
{
|
| 53 |
-
"model_name": "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
"model_type": "Neural Networks",
|
| 55 |
"model_description": "A deep learning model that efficiently imitates an Neural Networks, enhancing performance on tabular data tasks without the overhead of training multiple models."
|
| 56 |
}
|
|
|
|
| 1 |
[
|
| 2 |
{
|
| 3 |
+
"model_name": "nicl",
|
| 4 |
"model_type": "Tabular Foundation Model",
|
| 5 |
"model_description": "Our in-house tabular foundation model based on an in-context learning architecture."
|
| 6 |
},
|
| 7 |
{
|
| 8 |
+
"model_name": "xgboost",
|
| 9 |
"model_type": "Decision Trees",
|
| 10 |
+
"model_description": "A highly efficient and scalable gradient boosting framework that improves performance with regularization and handles large tabular datasets effectively."
|
| 11 |
},
|
| 12 |
{
|
| 13 |
+
"model_name": "xgboost_ensemble",
|
| 14 |
+
"model_type": "Decision Trees",
|
| 15 |
+
"model_description": "(Ensembled Version) A highly efficient and scalable gradient boosting framework that improves performance with regularization and handles large tabular datasets effectively."
|
| 16 |
},
|
| 17 |
{
|
| 18 |
+
"model_name": "catboost",
|
| 19 |
"model_type": "Decision Trees",
|
| 20 |
+
"model_description": "A high-performance gradient boosting algorithm that handles categorical features natively and requires minimal preprocessing."
|
| 21 |
},
|
| 22 |
{
|
| 23 |
+
"model_name": "catboost_ensemble",
|
| 24 |
"model_type": "Decision Trees",
|
| 25 |
+
"model_description": "(Ensembled Version) A high-performance gradient boosting algorithm that handles categorical features natively and requires minimal preprocessing."
|
| 26 |
},
|
| 27 |
{
|
| 28 |
+
"model_name": "modern-nca",
|
| 29 |
"model_type": "Neural Networks",
|
| 30 |
"model_description": "An advanced extension of Neighborhood Component Analysis (NCA) that employs deep neural networks with stochastic neighborhood sampling to learn complex feature interactions for tabular data."
|
| 31 |
},
|
| 32 |
{
|
| 33 |
+
"model_name": "tabpfn2.5",
|
| 34 |
"model_type": "Tabular Foundation Model",
|
| 35 |
"model_description": "A transformer-based model that performs in-context learning by approximating Bayesian inference for tabular classification on small datasets."
|
| 36 |
},
|
| 37 |
{
|
| 38 |
+
"model_name": "realmlp",
|
| 39 |
+
"model_type": "Neural Networks",
|
| 40 |
+
"model_description": "An enhanced MLP optimized with strong default parameters, achieving competitive performance on tabular data. Note that due to computate limitation, we used the simple version of realmlp."
|
| 41 |
},
|
| 42 |
{
|
| 43 |
+
"model_name": "tabicl",
|
| 44 |
"model_type": "Tabular Foundation Model",
|
| 45 |
"model_description": "A transformer-based model that performs feature compression before doing in-context learning on tabular data by conditioning on labeled support examples to predict unseen queries without task-specific training."
|
| 46 |
},
|
| 47 |
{
|
| 48 |
+
"model_name": "lightgbm",
|
| 49 |
"model_type": "Decision Trees",
|
| 50 |
"model_description": "A fast gradient boosting framework that builds decision trees using histogram-based learning for scalable, high-performance tabular modeling."
|
| 51 |
},
|
| 52 |
{
|
| 53 |
+
"model_name": "lightgbm_ensemble",
|
| 54 |
+
"model_type": "Decision Trees",
|
| 55 |
+
"model_description": "(Ensembled Version) A fast gradient boosting framework that builds decision trees using histogram-based learning for scalable, high-performance tabular modeling."
|
| 56 |
+
},
|
| 57 |
+
{
|
| 58 |
+
"model_name": "tabm",
|
| 59 |
"model_type": "Neural Networks",
|
| 60 |
"model_description": "A deep learning model that efficiently imitates an Neural Networks, enhancing performance on tabular data tasks without the overhead of training multiple models."
|
| 61 |
}
|
private_dummy.json
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
public_datasets_info.json
CHANGED
|
The diff for this file is too large to render.
See raw diff
|
|
|
public_dummy.json
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
public_dummy_first.json
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
qrt.json
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"tabpfn2.5" : 50.72,
|
| 3 |
+
"lightgbm" : 50.98,
|
| 4 |
+
"xgboost" : 51.18,
|
| 5 |
+
"tabicl" : 51.58,
|
| 6 |
+
"nicl" : 51.70
|
| 7 |
+
}
|
requirements.txt
CHANGED
|
@@ -12,3 +12,5 @@ seaborn
|
|
| 12 |
scikit-learn
|
| 13 |
|
| 14 |
requests
|
|
|
|
|
|
|
|
|
| 12 |
scikit-learn
|
| 13 |
|
| 14 |
requests
|
| 15 |
+
|
| 16 |
+
pyarrow
|
run.py
CHANGED
|
@@ -2,7 +2,7 @@ import pandas as pd
|
|
| 2 |
import json
|
| 3 |
|
| 4 |
# Load model performance per dataset
|
| 5 |
-
with open("
|
| 6 |
public_per_dataset = pd.json_normalize(json.load(f))
|
| 7 |
|
| 8 |
# Load dataset metadata (including industries)
|
|
|
|
| 2 |
import json
|
| 3 |
|
| 4 |
# Load model performance per dataset
|
| 5 |
+
with open("complete_results_acad.json", "r") as f:
|
| 6 |
public_per_dataset = pd.json_normalize(json.load(f))
|
| 7 |
|
| 8 |
# Load dataset metadata (including industries)
|