Downloads · 30 days
0
Limmen/Limmen-batteryswapai2026
Limmen-batteryswapai2026 is a machine learning model from Limmen. Use it for the machine learning task on the model card, and read the license before you ship it in a product. The card lists the license as mit.
Censoring-aware remaining-useful-life prognosis for CR2477T IoT sensor batteries, coupled to a decision-theoretic replacement scheduler under worker-hour and travel constraints.
Downloads · 30 days
0
Access
Public
Updated Aug 24, 2026
Repo size
163 MB
Likes
0
Public
Click a slice to open those files.
.pickle22.5 MB · 99%
From the Hugging Face model README
Censoring-aware remaining-useful-life prognosis for CR2477T IoT sensor batteries, coupled to a decision-theoretic replacement scheduler under worker-hour and travel constraints.
Everything needed to reproduce the stored model and the submitted plans is in
this repository. All code here is authored by the participant and MIT
licensed (see LICENSE).
Four stages, each addressing a specific structure in the problem:
lifelines) is fitted on
all of them, censored rows included, rather than on the 82 observed failures
alone. Supplies the beyond-window survivor tail.batteryswap_public.utils.smooth_series.python -m venv venv && source venv/Scripts/activate
pip install -r requirements.txt
Developed on Python 3.11.9. requirements.txt is the organizers' fixed
competition set, copied verbatim; the submission adds no dependency
beyond it.
python download_data.py # from the project repo; or use huggingface_hub directly
Fetches batteryswapaichallenge/BatterySwapAI-2026-Public into data/:
devices.csv, eol_times.csv, battery_metrics.parquet, scenarios.json.
No other dataset is used.
python scripts/build_dense.py --step=2 --start=2025-06-01 --jobs=18 \
--out=artifacts/training_table_era_v6.parquet
One row per (snapshot, battery), features computed strictly from data at or before the snapshot and labels measured after it. Two deliberate choices:
--step=2 — snapshots every two days rather than only the 48 shipped
scenario starts, which the competition documentation explicitly invites.--start=2025-06-01 — restricted to the evaluation era. Training on the
full 2022–2026 history scored 2124 against 2065: the older period has a
0.9% in-window failure base rate against 2.3% in the scored era, and
isotonic calibration inherits the training base rate.Runtime ≈12 min on 18 cores. Deterministic.
AQUILA_MEMBERS=5 python scripts/train.py --table=artifacts/training_table_era_v6.parquet
| artifact | contents |
|---|---|
model.pkl | Weibull AFT, censoring-aware, survivor tail |
clf.pkl | monotonic GBM, P(EOL ≤ 42 d), isotonic-calibrated OOF by building |
hazard.pkl | six such classifiers at 7…42 d → calibrated discrete CDF |
Runtime ≈15 min. Deterministic given the table (SEED = 20260818; no RNG in
featurisation, AFT fitting is deterministic).
python scripts/make_submission_repo.py --safety=1.0 --quantile=0.05
Bundles the fitted planner into aquila/planners/best.pickle — the artifact
shipped in this repository — together with the aquila package, script.py
and the Dockerfile.
Exactly as the competition harness runs it:
BATTERYSWAP_DATASET_PATH=../data BATTERYSWAP_SPLITS=train python script.py
script.py unpickles aquila/planners/best.pickle and calls
Planner.plan(timeseries, locations, travel_costs, settings) per scenario,
writing submission.csv. CPU only, single process. Measured 3m37s for 48
scenarios against the 30-minute limit; peak memory well under 32 GB.
The serve path degrades in tiers rather than raising, because one uncaught
exception or a wall-clock overrun would void an entire run: full plan →
voltage-threshold plan built from the raw series alone → defer-all, which is
valid by construction. A time guard (AQUILA_TIME_BUDGET, default 1500 s)
switches remaining scenarios to the fallback rather than overrunning. All
tiers are verified by fault injection.
No pretrained models and no external datasets are used. Every package is from the organizers' fixed environment; versions are those used in development.
| package | version | license |
|---|---|---|
| pandas | 2.2.2 | BSD-3-Clause |
| numpy | 2.2.6 | BSD-3-Clause |
| scikit-learn | 1.7.2 | BSD-3-Clause |
| scipy | 1.13.1 | BSD-3-Clause |
| lifelines | 0.30.3 | MIT |
| statsmodels | 0.14.6 | BSD-3-Clause |
| pyarrow | 16.1.0 | Apache-2.0 |
| fastparquet | 2026.5.0 | Apache-2.0 |
| joblib | 1.5.2 | BSD-3-Clause |
| polars | 1.43.2 | MIT |
| ortools | 9.15.6755 | Apache-2.0 |
| batteryswap_public | 0.3.4 | organizers' package |
All permissive (MIT / BSD / Apache-2.0), consistent with the competition's licensing requirement.
Each tagged version below is a scored submission, kept intact for
verification. Public-leaderboard total_cost:
| commit | version | score |
|---|---|---|
d6b1dfd | v1 — AFT + calibrated window classifier | 2132.24 |
f65e62c | v2 — multi-horizon hazard, temp-compensated features | 2070.04 |
1f7a6d7 | v3 — tuned ensemble, true trip pricing | 1928.65 |
b057c82 | v5 — multi-building day chaining | 1816.82 |
416e64b | v6 — chaining caps from harsh geometry | 1777.22 |
7f5bc19 | v9 — rider margin 0.45 | 1953.35 |
3be9ee9 | v10 — safety 1.25 | 1794.94 |
00f5af9 | v11 — v6 decisions + serve-time safety net | — |
v9 and v10 bracket the swap-count axis from both sides and confirm v6 as a local optimum: removing swaps costs +90.4 late per swap, adding them saves only −35.7. Negative results are documented rather than discarded.