Thibaut Forest Claude Fable 5 commited on
Commit ·
2cabcac
1
Parent(s): 9438aac
Phase 49: four new ordering-signal families opened and closed - longitudinal cross-origin, interactions, tau re-rank, temporal ensembling; the marginal-rank defect is missing information, not noise
Browse files- EXPERIMENTS.md +80 -0
- exp_x29_new_signal_sweep.py +214 -0
EXPERIMENTS.md
CHANGED
|
@@ -2498,3 +2498,83 @@ p42_sum untouched so the count rule is byte-identical).
|
|
| 2498 |
Local champion is now **cert-first at 1623.7** (from 1661.7). Public look not
|
| 2499 |
yet spent; submission is the user's call. Expected public value if the wobble
|
| 2500 |
rate transfers: ~-35 +/- (fires 0.46 devices/scenario locally).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2498 |
Local champion is now **cert-first at 1623.7** (from 1661.7). Public look not
|
| 2499 |
yet spent; submission is the user's call. Expected public value if the wobble
|
| 2500 |
rate transfers: ~-35 +/- (fires 0.46 devices/scenario locally).
|
| 2501 |
+
|
| 2502 |
+
## Phase 49 - four new ordering-signal families opened and closed in one sweep
|
| 2503 |
+
|
| 2504 |
+
Directive (user, 2026-08-22): test new ideas against the champion, be
|
| 2505 |
+
innovative, try brand-new approaches. Everything below is a fixed-N ordering
|
| 2506 |
+
screen (`cv.ablate` discipline, both instruments where applicable, paired per
|
| 2507 |
+
origin, bootstrap 95% CI), so no depth confound; costs on the 1661.7 scale
|
| 2508 |
+
(cv.run_all48 does not route through submit.py's cert-first). Screen code:
|
| 2509 |
+
`exp_x29_new_signal_sweep.py` [long|tau|tavg]. Phase 48 is reserved for the
|
| 2510 |
+
cert-first public adjudication (parallel session).
|
| 2511 |
+
|
| 2512 |
+
### (A) Longitudinal cross-origin features - the first untouched signal family
|
| 2513 |
+
|
| 2514 |
+
The feature table is a 168-origin snapshot grid (~3-4d apart) per device; every
|
| 2515 |
+
existing feature reads one 30/90d window at ONE origin, and no phase had ever
|
| 2516 |
+
read ACROSS origins. Three features, all strictly backward-looking
|
| 2517 |
+
(merge_asof, snapshots < T): `mom28`/`mom56` = within-fleet rank change of
|
| 2518 |
+
v_last vs 28/56d ago; `wolf` = count of snapshots >= 42d ago in the bottom
|
| 2519 |
+
decile (device provably survived - it is alive at T).
|
| 2520 |
+
|
| 2521 |
+
The raw signal is REAL: bottom-decile chronics (wolf > 2) die at 20.7% vs
|
| 2522 |
+
15.5% for newcomers, and dying devices' fleet rank slides (median mom28 -0.025
|
| 2523 |
+
vs -0.007 for survivors). The model cannot use it:
|
| 2524 |
+
|
| 2525 |
+
| variant | native N=12 | gate N=12 | verdict |
|
| 2526 |
+
|---|---|---|---|
|
| 2527 |
+
| mom | -5 [-13,+3] | -7 [-14,+0] | reject (gate N=16/20 significantly negative) |
|
| 2528 |
+
| wolf | **-24 [-42,-7]** | **-14 [-27,-1]** | reject |
|
| 2529 |
+
| momwolf | -27 [-47,-7] | -15 [-30,-1] | reject |
|
| 2530 |
+
|
| 2531 |
+
Mechanism: the 30d-window slope/drop/accel features already price the
|
| 2532 |
+
trajectory in; the cross-origin rank version duplicates them with extra noise,
|
| 2533 |
+
and `wolf` duplicates the level (chronics ARE low). Effective n ~80 punishes
|
| 2534 |
+
every redundant column.
|
| 2535 |
+
|
| 2536 |
+
### (B) Interaction terms - the linear champion offered its first products
|
| 2537 |
+
|
| 2538 |
+
`z(v_last)*z(slope_30)`, `z(v_last)*z(vstd_30)`, `z(v_min_7)*z(accel)`
|
| 2539 |
+
(within-origin z-scores, leak-free). Flat everywhere: native +2/-2/+5/+2
|
| 2540 |
+
across N, gate +0/-1/-5/-1, every CI straddling zero. There is no exploitable
|
| 2541 |
+
interaction structure - the phase-45 ceiling holds against nonlinearity in
|
| 2542 |
+
feature space, not just against nonlinear learners.
|
| 2543 |
+
|
| 2544 |
+
### (C) tau descent-band re-rank - phase 43's open candidate, closed
|
| 2545 |
+
|
| 2546 |
+
The knn screen left one open item: logbag underweights `tau_projected` in the
|
| 2547 |
+
descent band where its misses live (24/36/44 of 132 panel misses in tau's
|
| 2548 |
+
top-3/5/10); EV-negative as extra swaps, never tested as a pure REORDER at
|
| 2549 |
+
fixed N. Tested three transforms (band rank-blend, global rank-blend,
|
| 2550 |
+
promotion-only): native **-45 of 454 at N=12 (7W/29L)**, -53 at N=8. The gate
|
| 2551 |
+
is mildly positive (+3..+11) - the same protocol-specificity signature as
|
| 2552 |
+
`v_last` in phase 41: a single static foreign fit underuses the timer, the
|
| 2553 |
+
weekly refit already extracts it. The gate's sign must never override a
|
| 2554 |
+
native loss. Candidate closed for the native path.
|
| 2555 |
+
|
| 2556 |
+
### (D) Temporal score ensembling - the variance question, settled directly
|
| 2557 |
+
|
| 2558 |
+
Rank-average the current origin's fit with the previous 1-2 origins' fits
|
| 2559 |
+
applied to the same rows (adjacent origins are near-identical draws of the
|
| 2560 |
+
~80-death training set). Dead flat: tavg2 -3 at N=12 (0W/3L), tavg3 -4
|
| 2561 |
+
(1W/5L) - refit-to-refit orderings barely differ. With phase 44's flat C
|
| 2562 |
+
sweep (regularisation not binding) and logbag never separating from plain
|
| 2563 |
+
logistic (bagging variance not binding), this is the third independent leg:
|
| 2564 |
+
|
| 2565 |
+
> **The marginal-rank defect is missing information, not estimation noise.
|
| 2566 |
+
> Any future ordering candidate must bring a NEW signal, not a better
|
| 2567 |
+
> estimate of the current ones.**
|
| 2568 |
+
|
| 2569 |
+
(It also moots the deployment-gate objection - there is no fit noise to
|
| 2570 |
+
smooth, in any branch.)
|
| 2571 |
+
|
| 2572 |
+
### Standing
|
| 2573 |
+
|
| 2574 |
+
Four families opened, four closed, all with mechanisms. The information
|
| 2575 |
+
ceiling of phase 45 now covers: re-weightings (45), replacement sets (47),
|
| 2576 |
+
cross-origin dynamics, interactions, timer blends, and temporal ensembles
|
| 2577 |
+
(49). What remains is what phase 44 said: a signal outside this feature
|
| 2578 |
+
space, or the declined forward-read. Local champion unchanged (cert-first
|
| 2579 |
+
1623.7 / base 1661.7); public champion **3c7b883 at 1661.45**. Deadline
|
| 2580 |
+
2026-08-23.
|
exp_x29_new_signal_sweep.py
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Phase-49 sweep: four new ordering-signal families, all REJECTED.
|
| 2 |
+
|
| 3 |
+
Usage: venv/bin/python exp_x29_new_signal_sweep.py [long|tau|tavg]
|
| 4 |
+
|
| 5 |
+
long A. LONGITUDINAL cross-origin features - the per-device history ACROSS
|
| 6 |
+
the 168-origin snapshot grid (~3-4d apart), untouched by any prior
|
| 7 |
+
phase. mom28/mom56 = fleet-rank change vs 28/56d ago; wolf = count
|
| 8 |
+
of snapshots >=42d ago in the bottom decile, survived to T.
|
| 9 |
+
B. INTERACTIONS - within-origin z-score products (the champion is
|
| 10 |
+
linear with zero interaction terms).
|
| 11 |
+
tau C. Descent-band tau_projected re-rank at fixed N (the phase-43 knn
|
| 12 |
+
screen's "open deployment-regime candidate", never tested as a
|
| 13 |
+
pure reorder).
|
| 14 |
+
tavg D. Temporal score ensembling - rank-average the current fit with the
|
| 15 |
+
previous 1-2 origins' fits applied to current rows (fit-noise
|
| 16 |
+
smoothing; effective n ~80 deaths).
|
| 17 |
+
|
| 18 |
+
Verdicts (fixed-N deaths caught, paired per origin, bootstrap 95% CI):
|
| 19 |
+
A: wolf -24 [-42,-7] native N=12, -14 [-27,-1] gate; momwolf/allnew worse;
|
| 20 |
+
mom -5 [-13,+3] native, significantly negative gate N=16/20. The raw
|
| 21 |
+
signal EXISTS (bottom-decile chronics die 20.7% vs 15.5%; dying devices'
|
| 22 |
+
rank slides -0.025 median in 28d) but the 30d-window slope/drop features
|
| 23 |
+
already price it in - the rank version adds noise, not information.
|
| 24 |
+
B: inter flat everywhere (+2/-2 native, +0/-1 gate) - no exploitable
|
| 25 |
+
interaction structure; the phase-45 linear ceiling again.
|
| 26 |
+
C: native -45 of 454 at N=12 (7W/29L) - decisive. Gate mildly positive
|
| 27 |
+
(+3..+11), the same protocol-specificity signature as v_last in phase
|
| 28 |
+
41: the weekly refit already extracts the timer. Do not trust the gate's
|
| 29 |
+
sign against a native loss.
|
| 30 |
+
D: dead flat (tavg2 -3 at N=12, 0W/3L; tavg3 -4, 1W/5L) - adjacent 7d-apart
|
| 31 |
+
refits produce near-identical orderings. Third leg of the
|
| 32 |
+
variance-vs-information triangulation (with phase 44's flat C sweep and
|
| 33 |
+
logbag==logistic): the marginal-rank defect is MISSING INFORMATION, not
|
| 34 |
+
estimation noise. Any future ordering candidate must bring a NEW signal,
|
| 35 |
+
not a better estimate of the current ones.
|
| 36 |
+
"""
|
| 37 |
+
import sys
|
| 38 |
+
|
| 39 |
+
import numpy as np
|
| 40 |
+
import pandas as pd
|
| 41 |
+
|
| 42 |
+
from batteryswap_example import cv
|
| 43 |
+
from batteryswap_example import models_cv as mc
|
| 44 |
+
|
| 45 |
+
NS = (8, 12, 16, 20, 30)
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
# ---------------------------------------------------------------- A + B ----
|
| 49 |
+
|
| 50 |
+
def _ensure_longitudinal(t):
|
| 51 |
+
if 'mom28' in t.columns:
|
| 52 |
+
return
|
| 53 |
+
snap = (t[['device_id', 'origin', 'r_vlast']]
|
| 54 |
+
.sort_values('origin').reset_index(drop=True))
|
| 55 |
+
snap['danger'] = (snap['r_vlast'] < 0.10).astype(float)
|
| 56 |
+
snap = snap.sort_values(['device_id', 'origin'])
|
| 57 |
+
snap['cum_danger'] = snap.groupby('device_id')['danger'].cumsum()
|
| 58 |
+
snap = snap.sort_values('origin')
|
| 59 |
+
base = t[['device_id', 'origin']].copy()
|
| 60 |
+
base['_row'] = np.arange(len(base))
|
| 61 |
+
|
| 62 |
+
def asof(offset_days, col, tol):
|
| 63 |
+
left = base.sort_values('origin').copy()
|
| 64 |
+
left['key'] = left['origin'] - pd.Timedelta(days=offset_days)
|
| 65 |
+
left = left.sort_values('key')
|
| 66 |
+
m = pd.merge_asof(left, snap[['device_id', 'origin', col]]
|
| 67 |
+
.rename(columns={'origin': 'snap_origin'})
|
| 68 |
+
.sort_values('snap_origin'),
|
| 69 |
+
left_on='key', right_on='snap_origin',
|
| 70 |
+
by='device_id', direction='backward',
|
| 71 |
+
tolerance=pd.Timedelta(days=tol))
|
| 72 |
+
return m.sort_values('_row')[col].values
|
| 73 |
+
|
| 74 |
+
r28 = asof(28, 'r_vlast', 10)
|
| 75 |
+
r56 = asof(56, 'r_vlast', 10)
|
| 76 |
+
cur = t['r_vlast'].values
|
| 77 |
+
t['mom28'] = np.where(np.isnan(r28), 0.0, cur - r28)
|
| 78 |
+
t['mom56'] = np.where(np.isnan(r56), 0.0, cur - r56)
|
| 79 |
+
cd = asof(42, 'cum_danger', 400)
|
| 80 |
+
t['wolf'] = np.where(np.isnan(cd), 0.0, cd)
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
def _ensure_inter(t):
|
| 84 |
+
if 'ix_v_slope' in t.columns:
|
| 85 |
+
return
|
| 86 |
+
|
| 87 |
+
def z(col):
|
| 88 |
+
g = t.groupby('origin_idx')[col]
|
| 89 |
+
return (t[col] - g.transform('mean')) / g.transform('std').replace(0, 1)
|
| 90 |
+
|
| 91 |
+
zv, zs = z('v_last'), z('slope_30')
|
| 92 |
+
zm7, za = z('v_min_7'), z('accel')
|
| 93 |
+
zvs = z('vstd_30')
|
| 94 |
+
t['ix_v_slope'] = (zv * zs).clip(-30, 30).fillna(0)
|
| 95 |
+
t['ix_v_vstd'] = (zv * zvs).clip(-30, 30).fillna(0)
|
| 96 |
+
t['ix_m7_accel'] = (zm7 * za).clip(-30, 30).fillna(0)
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
LONG_VARIANTS = {
|
| 100 |
+
'mom': lambda t: cv.BASE_FEATURES + ['mom28', 'mom56'],
|
| 101 |
+
'wolf': lambda t: cv.BASE_FEATURES + ['wolf'],
|
| 102 |
+
'momwolf': lambda t: cv.BASE_FEATURES + ['mom28', 'mom56', 'wolf'],
|
| 103 |
+
'inter': lambda t: cv.BASE_FEATURES + ['ix_v_slope', 'ix_v_vstd',
|
| 104 |
+
'ix_m7_accel'],
|
| 105 |
+
'allnew': lambda t: cv.BASE_FEATURES + ['mom28', 'mom56', 'wolf',
|
| 106 |
+
'ix_v_slope', 'ix_v_vstd',
|
| 107 |
+
'ix_m7_accel'],
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
def run_long():
|
| 112 |
+
cv.VARIANTS.update(LONG_VARIANTS)
|
| 113 |
+
# ablate() slices training_pairs BEFORE the variant loop, so the columns
|
| 114 |
+
# must exist at load time (same latent limitation bites the zone variant)
|
| 115 |
+
orig = cv.load_table
|
| 116 |
+
|
| 117 |
+
def load_plus(dataset_path=cv.Path('dataset')):
|
| 118 |
+
t = orig(dataset_path)
|
| 119 |
+
_ensure_longitudinal(t)
|
| 120 |
+
_ensure_inter(t)
|
| 121 |
+
return t
|
| 122 |
+
|
| 123 |
+
cv.load_table = load_plus
|
| 124 |
+
var = ('base',) + tuple(LONG_VARIANTS)
|
| 125 |
+
df, ns = cv.ablate(variants=var, protocol='all48')
|
| 126 |
+
df.to_csv('/tmp/x29_long_all48.csv', index=False)
|
| 127 |
+
cv.ablation_report(df, ns, 'native all48 / longitudinal + interactions')
|
| 128 |
+
df2, ns2 = cv.ablate(variants=var, protocol='static')
|
| 129 |
+
df2.to_csv('/tmp/x29_long_static.csv', index=False)
|
| 130 |
+
cv.ablation_report(df2, ns2, 'static gate / longitudinal + interactions')
|
| 131 |
+
|
| 132 |
+
|
| 133 |
+
# -------------------------------------------------------------------- C ----
|
| 134 |
+
|
| 135 |
+
def _tau_transforms(rows, p42):
|
| 136 |
+
s = pd.DataFrame({'p42': p42})
|
| 137 |
+
s['rp'] = s['p42'].rank(pct=True)
|
| 138 |
+
tau = rows['tau_projected'].reindex(s.index)
|
| 139 |
+
vc = rows['v_corr_last'].reindex(s.index)
|
| 140 |
+
rt = (-tau).rank(pct=True)
|
| 141 |
+
band = (vc < 2.55) & tau.notna()
|
| 142 |
+
out = {'base': s['p42']}
|
| 143 |
+
b = s['rp'].copy()
|
| 144 |
+
b[band] = 0.5 * s['rp'][band] + 0.5 * rt[band]
|
| 145 |
+
out['blend_b'] = b
|
| 146 |
+
a = s['rp'].copy()
|
| 147 |
+
m = tau.notna()
|
| 148 |
+
a[m] = 0.5 * s['rp'][m] + 0.5 * rt[m]
|
| 149 |
+
out['blend_all'] = a
|
| 150 |
+
p = s['rp'].copy()
|
| 151 |
+
p[band] = np.maximum(s['rp'][band], rt[band])
|
| 152 |
+
out['promote'] = p
|
| 153 |
+
return out
|
| 154 |
+
|
| 155 |
+
|
| 156 |
+
def _native_scores(score_fn):
|
| 157 |
+
"""Shared walk: fit champion per origin, emit _order_stats per variant."""
|
| 158 |
+
t = cv.load_table()
|
| 159 |
+
ctx = mc.load_context(cv.Path('dataset'))
|
| 160 |
+
mc.FEATURES = list(cv.BASE_FEATURES)
|
| 161 |
+
recs, models = [], {}
|
| 162 |
+
for idx in range(48):
|
| 163 |
+
c = ctx[idx]
|
| 164 |
+
T = c['start_time']
|
| 165 |
+
tr = mc.training_pairs(t, T)
|
| 166 |
+
if tr['dies42'].sum() < 3:
|
| 167 |
+
continue
|
| 168 |
+
models[idx] = mc.SklearnRUL(cv.CHAMPION['model']).fit(tr)
|
| 169 |
+
rows = (t[t['origin_idx'] == idx].set_index('device_id')
|
| 170 |
+
.reindex(c['locs']['battery']).dropna(subset=['v_last']))
|
| 171 |
+
eol = c['eol'].reindex(rows.index)
|
| 172 |
+
deaths = set(eol.index[(eol > T)
|
| 173 |
+
& (eol <= T + pd.Timedelta(days=42))])
|
| 174 |
+
if not deaths:
|
| 175 |
+
continue
|
| 176 |
+
for name, score in score_fn(models, idx, rows).items():
|
| 177 |
+
recs.append(dict(cv._order_stats(score, deaths, NS),
|
| 178 |
+
origin=idx, variant=name, seed=0))
|
| 179 |
+
print(f's_{idx} done', file=sys.stderr, flush=True)
|
| 180 |
+
return pd.DataFrame(recs)
|
| 181 |
+
|
| 182 |
+
|
| 183 |
+
def run_tau():
|
| 184 |
+
def fn(models, idx, rows):
|
| 185 |
+
p = models[idx].predict(rows)['p42']
|
| 186 |
+
return _tau_transforms(rows, p)
|
| 187 |
+
|
| 188 |
+
df = _native_scores(fn)
|
| 189 |
+
df.to_csv('/tmp/x29_tau_all48.csv', index=False)
|
| 190 |
+
cv.ablation_report(df, NS, 'native all48 / tau descent-band re-rank')
|
| 191 |
+
|
| 192 |
+
|
| 193 |
+
# -------------------------------------------------------------------- D ----
|
| 194 |
+
|
| 195 |
+
def run_tavg():
|
| 196 |
+
def fn(models, idx, rows):
|
| 197 |
+
p_now = models[idx].predict(rows)['p42']
|
| 198 |
+
r_now = p_now.rank(pct=True)
|
| 199 |
+
scores = {'base': p_now}
|
| 200 |
+
prev = [models[j].predict(rows)['p42'].rank(pct=True)
|
| 201 |
+
for j in (idx - 1, idx - 2) if j in models]
|
| 202 |
+
if len(prev) >= 1:
|
| 203 |
+
scores['tavg2'] = 0.6 * r_now + 0.4 * prev[0]
|
| 204 |
+
if len(prev) >= 2:
|
| 205 |
+
scores['tavg3'] = 0.5 * r_now + 0.3 * prev[0] + 0.2 * prev[1]
|
| 206 |
+
return scores
|
| 207 |
+
|
| 208 |
+
df = _native_scores(fn)
|
| 209 |
+
df.to_csv('/tmp/x29_tavg_all48.csv', index=False)
|
| 210 |
+
cv.ablation_report(df, NS, 'native all48 / temporal score ensembling')
|
| 211 |
+
|
| 212 |
+
|
| 213 |
+
if __name__ == '__main__':
|
| 214 |
+
{'long': run_long, 'tau': run_tau, 'tavg': run_tavg}[sys.argv[1]]()
|