Thibaut Forest Claude Opus 5 (1M context) commited on
Commit ·
79a4af2
1
Parent(s): 11cbd93
all48oof: static fit protocol is the default (user-shaped) - one fit per fold on the other buildings' FULL closed history, deployment's exact shape; 40s runtime; new reference panel 1893.4 / ALL-48 1913.3; 'cv all48oof wf' keeps the walk-forward variant
Browse files- batteryswap_example/cv.py +46 -6
batteryswap_example/cv.py
CHANGED
|
@@ -610,7 +610,7 @@ def ablation_report(df, ns, label, ref='base'):
|
|
| 610 |
|
| 611 |
def run_all48_oof(n_folds=5, seed=0, origins=range(48),
|
| 612 |
dataset_path=Path('dataset'), kind=None, variant='base',
|
| 613 |
-
arms=('self', 'oof'), blend=None):
|
| 614 |
"""The walk-forward cost harness with BUILDING-CLEAN predictions.
|
| 615 |
|
| 616 |
all48 itself is temporal, not fold-based, and its PLANNING must stay
|
|
@@ -637,6 +637,16 @@ def run_all48_oof(n_folds=5, seed=0, origins=range(48),
|
|
| 637 |
a post-hoc blend whose beliefs disagree with the count machinery fails
|
| 638 |
for that reason alone).
|
| 639 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 640 |
kind = kind or CHAMPION['model']
|
| 641 |
t = load_table(dataset_path)
|
| 642 |
mc.FEATURES = list(VARIANTS[variant](t))
|
|
@@ -653,12 +663,31 @@ def run_all48_oof(n_folds=5, seed=0, origins=range(48),
|
|
| 653 |
p.split_days = CHAMPION['split_days']
|
| 654 |
p.floor_scale, p.recent_deaths = 0.0, 0.0
|
| 655 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 656 |
recs = []
|
| 657 |
for idx in origins:
|
| 658 |
c = ctx[idx]
|
| 659 |
T = c['start_time']
|
| 660 |
tr = mc.training_pairs(t, T)
|
| 661 |
-
if tr['dies42'].sum() < 3:
|
| 662 |
continue
|
| 663 |
rows = (t[t['origin_idx'] == idx].set_index('device_id')
|
| 664 |
.reindex(c['locs']['battery']).dropna(subset=['v_last']))
|
|
@@ -670,6 +699,14 @@ def run_all48_oof(n_folds=5, seed=0, origins=range(48),
|
|
| 670 |
row_fold = rows.index.to_series().map(dev_bldg).map(bldg_fold)
|
| 671 |
|
| 672 |
def _pred(k, arm):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 673 |
if k == 'tau':
|
| 674 |
# fit-free pseudo-model: the physics timer as a rank source
|
| 675 |
# (only meaningful inside a value-preserving blend)
|
|
@@ -835,11 +872,14 @@ def main():
|
|
| 835 |
elif proto == 'screen':
|
| 836 |
screen()
|
| 837 |
elif proto == 'all48oof':
|
| 838 |
-
# THE SCORE (user
|
| 839 |
-
#
|
| 840 |
-
#
|
|
|
|
|
|
|
| 841 |
arms = ('self', 'oof') if variant == 'self' else ('oof',)
|
| 842 |
-
|
|
|
|
| 843 |
df.to_csv('/tmp/cv_all48oof.csv', index=False)
|
| 844 |
oof_report(df)
|
| 845 |
elif proto == 'oofcand':
|
|
|
|
| 610 |
|
| 611 |
def run_all48_oof(n_folds=5, seed=0, origins=range(48),
|
| 612 |
dataset_path=Path('dataset'), kind=None, variant='base',
|
| 613 |
+
arms=('self', 'oof'), blend=None, fit='static'):
|
| 614 |
"""The walk-forward cost harness with BUILDING-CLEAN predictions.
|
| 615 |
|
| 616 |
all48 itself is temporal, not fold-based, and its PLANNING must stay
|
|
|
|
| 637 |
a post-hoc blend whose beliefs disagree with the count machinery fails
|
| 638 |
for that reason alone).
|
| 639 |
"""
|
| 640 |
+
# fit='static' (default; user-shaped 2026-08-22): each fold's model is
|
| 641 |
+
# fitted ONCE on the OTHER buildings' FULL closed history and scores all
|
| 642 |
+
# 48 origins - exactly deployment's shape (the shipped static model is
|
| 643 |
+
# one fit on the train fleet's full history through data end, applied at
|
| 644 |
+
# public origins that are mostly in its past; the competition itself
|
| 645 |
+
# hands the model future-of-origin FOREIGN-building knowledge, so
|
| 646 |
+
# respecting a temporal cutoff for other buildings is stricter than the
|
| 647 |
+
# thing being estimated and it starves warm-up in a way deployment never
|
| 648 |
+
# does). Calendar co-movement across buildings is therefore IN scope by
|
| 649 |
+
# design. fit='walkforward' keeps the old per-origin refits.
|
| 650 |
kind = kind or CHAMPION['model']
|
| 651 |
t = load_table(dataset_path)
|
| 652 |
mc.FEATURES = list(VARIANTS[variant](t))
|
|
|
|
| 663 |
p.split_days = CHAMPION['split_days']
|
| 664 |
p.floor_scale, p.recent_deaths = 0.0, 0.0
|
| 665 |
|
| 666 |
+
static_models = {}
|
| 667 |
+
if fit == 'static':
|
| 668 |
+
# one fit per fold on the full closed foreign history (+ one all-
|
| 669 |
+
# buildings fit for the self arm) - the deployment-shaped protocol
|
| 670 |
+
hazard = kind in ('aft', 'dthaz', 'dthaz_aux', 'logbag_open',
|
| 671 |
+
'blend_dh', 'blend_dhaux')
|
| 672 |
+
pool = (mc.censored_pairs(t, t['origin'].max()) if hazard
|
| 673 |
+
else t[t['origin'] <= t['origin'].max()
|
| 674 |
+
- pd.Timedelta(days=WINDOW_DAYS)])
|
| 675 |
+
pool_fold = pool['device_id'].map(dev_bldg).map(bldg_fold)
|
| 676 |
+
make = ((lambda: mc.MODELS[kind]()) if kind in mc.MODELS
|
| 677 |
+
else (lambda: mc.SklearnRUL(kind)))
|
| 678 |
+
for f in sorted(bldg_fold.dropna().unique()):
|
| 679 |
+
static_models[f] = make().fit(pool[(pool_fold != f).values])
|
| 680 |
+
if 'self' in arms:
|
| 681 |
+
static_models['SELF'] = make().fit(pool)
|
| 682 |
+
print(f'static foreign fits: {len(static_models)} on '
|
| 683 |
+
f'{len(pool)} closed pairs', flush=True, file=sys.stderr)
|
| 684 |
+
|
| 685 |
recs = []
|
| 686 |
for idx in origins:
|
| 687 |
c = ctx[idx]
|
| 688 |
T = c['start_time']
|
| 689 |
tr = mc.training_pairs(t, T)
|
| 690 |
+
if fit != 'static' and tr['dies42'].sum() < 3:
|
| 691 |
continue
|
| 692 |
rows = (t[t['origin_idx'] == idx].set_index('device_id')
|
| 693 |
.reindex(c['locs']['battery']).dropna(subset=['v_last']))
|
|
|
|
| 699 |
row_fold = rows.index.to_series().map(dev_bldg).map(bldg_fold)
|
| 700 |
|
| 701 |
def _pred(k, arm):
|
| 702 |
+
if fit == 'static' and k == kind:
|
| 703 |
+
if arm == 'self':
|
| 704 |
+
return static_models['SELF'].predict(rows)
|
| 705 |
+
parts = []
|
| 706 |
+
for f in sorted(row_fold.dropna().unique()):
|
| 707 |
+
parts.append(static_models[f].predict(
|
| 708 |
+
rows[(row_fold == f).values]))
|
| 709 |
+
return pd.concat(parts).reindex(rows.index)
|
| 710 |
if k == 'tau':
|
| 711 |
# fit-free pseudo-model: the physics timer as a rank source
|
| 712 |
# (only meaningful inside a value-preserving blend)
|
|
|
|
| 872 |
elif proto == 'screen':
|
| 873 |
screen()
|
| 874 |
elif proto == 'all48oof':
|
| 875 |
+
# THE SCORE (user directives 2026-08-22): oof arm, STATIC fit
|
| 876 |
+
# protocol (one fit per fold on the other buildings' full closed
|
| 877 |
+
# history - deployment's shape). `cv all48oof self` adds the self
|
| 878 |
+
# arm (flattery readout); `cv all48oof wf` uses the old per-origin
|
| 879 |
+
# walk-forward refits (whose self arm reproduces panel 1679.2).
|
| 880 |
arms = ('self', 'oof') if variant == 'self' else ('oof',)
|
| 881 |
+
fitp = 'walkforward' if variant == 'wf' else 'static'
|
| 882 |
+
df = run_all48_oof(arms=arms, fit=fitp)
|
| 883 |
df.to_csv('/tmp/cv_all48oof.csv', index=False)
|
| 884 |
oof_report(df)
|
| 885 |
elif proto == 'oofcand':
|