Bike Sharing Demand - Tabular Models (CatBoost + XGBoost, Poisson)

Pre-trained baseline models for the t22000t/bike-sharing-tabular dataset, produced by the tabular-data-modelling-pipeline.

These models train with a Poisson loss (matching the count-data target), which is the right thing for non-negative integer counts like hourly bike rentals. This is the v1 baseline drop - DL architectures will land in a follow-up.

Results

Model Test Gini Train Gini Test MAE Test RMSE A/E ratio n params Training time
XGBoost (Poisson) 0.4975 0.5047 22.9 38.65 1.007 999 trees 1.3 s
CatBoost (Poisson) 0.4935 0.4964 29.7 45.87 1.021 583 trees 3.1 s
Stacked ensemble (NNLS) 0.4975 0.5047 22.9 38.65 1.007 (weights) -
  • Test set: 3,470 hourly rows (20% of 17,379)
  • Target: cnt (hourly bike rental count, 1-977)
  • Loss: Poisson NLL (count:poisson for XGBoost, Poisson for CatBoost)
  • Link: log
  • Random seed: 42

MAE is in count units (bikes); a test MAE of ~23 on a target with median 142 and max 977 is genuinely useful. Gini ~0.50 indicates the model captures about half the rank-order signal in the data.

Files

File What it is Size
catboost.cbm Trained CatBoost model (native format, Poisson loss) ~2 MB
xgboost.json Trained XGBoost Booster (native JSON format, count:poisson) ~2 MB
evaluation_summary.csv Per-model train/test metrics
ensemble_weights.json NNLS-stacked weights over base predictions
dashboard_dl_models.html Interactive Plotly dashboard
figures/fig_dl_*.png Standalone publication-quality figures
model_summary.json Structured run record

Loading and inference

CatBoost

from huggingface_hub import hf_hub_download
from catboost import CatBoostRegressor
import pandas as pd

path = hf_hub_download("t22000t/bike-sharing-tabular-models", "catboost.cbm")
model = CatBoostRegressor()
model.load_model(path)

df = pd.read_csv("hf://datasets/t22000t/bike-sharing-tabular/hour.csv")
features = [
    "temp", "atemp", "hum", "windspeed", "hr", "yr", "mnth",
    "season", "holiday", "weekday", "workingday", "weathersit",
]
preds = model.predict(df[features])  # predicted hourly rental count

XGBoost

from huggingface_hub import hf_hub_download
import xgboost as xgb

path = hf_hub_download("t22000t/bike-sharing-tabular-models", "xgboost.json")
booster = xgb.Booster()
booster.load_model(path)

XGBoost predictions require the exact feature order used at training time; clone the pipeline repo for the preprocessing path.

Training configuration

Setting Value
Pipeline tabular-data-modelling-pipeline v0.1.0
Architecture mix CatBoost + XGBoost (DL excluded from this drop)
Hyperparameters Defaults - no Optuna tuning
Family / link Poisson / log
XGBoost objective count:poisson
CatBoost loss Poisson
XGBoost base_score log(mean(y_train)) (set explicitly to avoid an inf-base_score bug)
Train/test split Random 80/20, seed 42
Cap percentile 99.9 (light cap - count data)
CV folds 5
Hardware Apple M-series, CPU

To reproduce:

git clone https://github.com/timothy22000/tabular_data_modelling_pipeline
cd tabular_data_modelling_pipeline
pip install -e ".[gbm,viz]"
python scripts/download_data.py --dataset bike_sharing

OMP_NUM_THREADS=1 python train.py \
    --config configs/example_bike_sharing.py \
    --input data/bike_sharing.csv \
    --skip-tuning --skip-interpretability \
    --architectures catboost xgboost

OMP_NUM_THREADS=1 is only needed on macOS arm64; Linux is unaffected.

Limitations

  • Defaults only. No hyperparameter tuning. With Optuna, expect Gini lift of 0.02-0.04.
  • GBM only. DL architectures (CANN, FT-Transformer, TabM, DRN) would likely beat XGBoost on this dataset given the rich seasonality and the 17k row count - watch for the v2 drop.
  • Random split. Time-series data ideally needs a chronological split. This baseline uses random 80/20 for consistency with other dataset drops; for a more realistic evaluation, use a date-based split (e.g. train on 2011, test on 2012).
  • Casual/registered excluded. The dataset's casual and registered columns sum to cnt - they are excluded from features to prevent label leakage. This is the same setup most published Bike Sharing benchmarks use.

Intended use

  • Demonstrating the pipeline on count/Poisson data. Pairs naturally with the House Prices model collection (gamma) to show family flexibility.
  • Baseline for tabular DL research on count regression.
  • Teaching Poisson regression and pricing-style modelling.

Citation

@article{fanaee2014event,
  title   = {Event labeling combining ensemble detectors and background knowledge},
  author  = {Fanaee-T, Hadi and Gama, Jo{\~a}o},
  journal = {Progress in Artificial Intelligence},
  year    = {2014}
}

@software{tabular_data_modelling_pipeline,
  author = {Mun, Timothy},
  title  = {tabular-data-modelling-pipeline},
  url    = {https://github.com/timothy22000/tabular_data_modelling_pipeline},
  year   = {2026}
}

License

MIT for the model code and pipeline. Underlying dataset is CC BY 4.0.

Related

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support

Dataset used to train t22000t/bike-sharing-tabular-models

Evaluation results

  • Test Gini (XGBoost) on Bike Sharing Demand
    self-reported
    0.497
  • Test MAE (XGBoost, count units) on Bike Sharing Demand
    self-reported
    22.900
  • Test Gini (CatBoost) on Bike Sharing Demand
    self-reported
    0.493
  • Test MAE (CatBoost, count units) on Bike Sharing Demand
    self-reported
    29.700