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:poissonfor XGBoost,Poissonfor 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
casualandregisteredcolumns sum tocnt- 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
- ๐ Dataset: t22000t/bike-sharing-tabular
- ๐ค Models: t22000t/house-prices-tabular-models - companion gamma-family collection
- ๐ฆ tabular-data-modelling-pipeline - the underlying pipeline
Dataset used to train t22000t/bike-sharing-tabular-models
Evaluation results
- Test Gini (XGBoost) on Bike Sharing Demandself-reported0.497
- Test MAE (XGBoost, count units) on Bike Sharing Demandself-reported22.900
- Test Gini (CatBoost) on Bike Sharing Demandself-reported0.493
- Test MAE (CatBoost, count units) on Bike Sharing Demandself-reported29.700