The idea: the continuous-learner records every resolved prediction's per-feature contribution to the logit. Over enough samples, real predictors will have positive average contribution on wins and negative on losses. Noise features will show roughly zero contribution either way.

The mechanism: for each feature i, compute alpha_score = avgContribWin - avgContribLoss then build a per-feature learning-rate multiplier: mult = clamp(1.0 + 4.0 × alpha_score, 0.2, 2.0)

The result: high-signal features train ~2× faster, noise features train ~5× slower. Over time, the model learns to ignore noise without any change to the feature pipeline. The brain effectively discovers its own feature selection.
Features tracked
22
Boosted (mult ≥ 1.3)
0
Pruned (mult ≤ 0.7)
0
Total resolutions seen
0
📊 Learning-rate multiplier per feature
Center line = neutral (1.0x). Right of center = boosted (predictive feature). Left = pruned (noise).
F#
NAME
WINS
LOSSES
ALPHA
MULT
MULT VIS
STATUS
🔬 How this integrates
The Model.train() function in js/model.js now reads window.FeatureImportance.lrMultiplier(i) on every SGD step:

// SGD update + L2 weight decay + feature importance
const lrMult = FeatureImportance.lrMultiplier(i);
const decay = (i === last) ? 0 : this.l2 * this.weights[i];
this.weights[i] -= this.lr * lrMult * (err * x[i] + decay);

Cache refreshes every 60 seconds in the background. The multiplier is bounded to [0.2, 2.0] to prevent runaway updates or permanent disabling.

Until each feature has 20+ resolutions, multiplier defaults to 1.0 (no effect). The model isn't penalized for thin data.