learn-ml-production-with-phoebe / Session 4 of 6
ML in Production: The Leader Cut · Session 4 of 6

The retrain-policy bench

"How often should we retrain?" gets asked in every production review and answered with a habit: nightly because the pipeline can, monthly because that is the reporting cycle, never because nobody owns it. Tonight the habit is replaced by a measurement. Two and a half years of a real electricity market, 15,104 half-hour rows, are replayed forward in your browser, one prediction at a time. The model never changes. The policy for refitting it does: never, on three schedules, on an alarm, on recent data only, and before every single prediction. Every run prints two numbers, the accuracy it bought and the retraining it cost, because a retrain policy is a spending decision before it is a technical one.

🔴 Bench night Leaders: read the two numbers Builders: read the replay 45 min
0-3 · Welcome 3-14 · How the replay works 14-40 · The eight policies, in order 40-45 · Q&A
Part 0

Where we start

Session 3 chose how the model goes out. This session decides what happens after it has gone out and the world keeps moving. The data is Elec2, the New South Wales electricity market from May 1996 to December 1998, the most used concept-drift benchmark there is. Each row is a half-hour; the label says whether the price went UP or DOWN against its own average over the last 24 hours. Prices, demand and the flow of power from Victoria all shift over the period, and a model trained on the first four weeks meets a market it has never seen. That is the production problem in miniature, on rows nobody invented.

🎫 Clear all three quiz questions to stamp your passport measured = computed from the real rows set by you = the dollar cost of one retrain

★ What you walk out with tonight. The measured price of retraining freshness on a real drifting stream, the two-number habit (accuracy and spend, never one without the other), the reason "retrain more often" has a floor below which it makes things worse, and a label-delay test that tells you when the right production decision is no model at all.

Part 1 · covers what the replay does

One model, one stream, eight policies

8 min live

A replay is the honest way to test a retrain policy: walk the rows in time order, predict each one with whatever model the policy has in service at that moment, and only let the policy use a label once that label would really have arrived. Nothing from the future leaks backwards. The figure is the whole machine.

THE REPLAY: PREDICT WITH WHAT IS IN SERVICE, LEARN ONLY FROM LABELS THAT HAVE ARRIVED first 4 weeks train model 1 labelled rows: prediction vs truth known delay D: no label yet row t: predict UP or DOWN the future: unseen Trigger 1: a schedule refit every K rows, whatever happened Trigger 2: an alarm start level falls theta below: fire refit window A: all labelled history window B: recent weeks only refit 9 weights on the chosen window Three dials decide every policy: what triggers a refit, which labelled rows it learns from, and how late the labels arrive. The model, the rows and the scoring never change between runs, so any difference in the two numbers is the policy.
🔍 Click to zoom - the ochre gap is the label delay, and it is the dial most retrain debates forget exists
LiveThe model is deliberately boring, and that is the point3 min▶

Nine inputs: a constant, the New South Wales price and demand, the Victoria price and demand, the scheduled transfer between the two states, the time of day as a point on a circle, and a weekend flag. One linear score, fitted by ridge least squares; a score above zero means UP. There is no feature engineering, no tuning and no clever architecture, and there should not be. A retrain policy is a decision about a model you already have in production. If the model changed between runs you could not tell whether a better number came from the policy or from the model.

The first model learns from the first four weeks, 448 rows. Every run is then scored on the same 14,656 rows that follow, from June 1996 to December 1998. The floor for reference, always answering DOWN because DOWN is the more common label, scores 57.72 percent.

LiveThe two numbers, and why neither is allowed alone3 min▶

Accuracy is the share of the 14,656 rows the policy's model called right. It is measured: the same rows, the same labels, counted.

Retrain spend is the number of refits times a dollar figure you set, $500 by default. That $500 is not a fact about anybody's cloud bill; it stands for the whole cost of one retrain in production, which is rarely the compute. It is the validation run, the review, the change ticket, the canary from session 3, and the on-call risk of shipping a new model on a Friday. Set it to what one retrain costs your team and every spend figure on the page moves with it. The accuracy column never does.

Read them as a pair. A policy that gains a point and a half for $65,000 and a policy that gains four points for $3,000 are not "both better than never". One of them is a bargain and one of them is a habit.

Self-studyHow the sample was made, and what that does to one baseline4 min▶

The full Elec2 file on OpenML has 45,312 rows, one per half-hour from 7 May 1996 to 5 December 1998. The bench keeps every third row, in time order, which gives 15,104 rows one and a half hours apart: 16 a day, 112 a week. Each input, already scaled between 0 and 1 by OpenML, is rounded to one of 256 levels. Nothing is shuffled, so the drift is exactly where the market put it.

One thing the thinning changes, and it matters for Part 3. On the full file, a rule that simply repeats the previous half-hour's label scores 85.3 percent, a figure Žliobaitė published in 2013 and that this build reproduces at 85.33 percent. On the bench, the "previous row" is an hour and a half earlier, so the same rule scores 74.63 percent. The model runs are not flattered or penalised by the thinning in the same way, which is why the page quotes the bench's own no-model number and never the 85.3.

One more real quirk: the Victoria price, Victoria demand and transfer columns hold a single constant value for roughly the first year, because they were missing and were filled in before the file was published. They start moving in May 1997. The chart on the bench marks the date. A model trained before then has learned nothing about three of its nine inputs, which is a very ordinary way for production data to change under a model.

Build-along · the bench

Eight policies, replayed in front of you

★ 26 min · the main event

Work down the eight in order, with the label delay on one day and the cost on $500. For each, read the verdict line, then the two numbers, then the chart: the raspberry line is the selected policy, the dashed grey line is never retraining, the dotted ochre line is no model at all. The ticks under the chart are the retrains. The last card is the anti-lever: the freshest possible model, and the bench shows what freshness costs when it is bought on too few rows.

Then change one dial at a time. Move the label delay to 1.5 hours and read the ladder table again: the no-model rule jumps to the top. Move it to one week and watch which policies barely notice. Then set the cost to what one retrain really costs your team, and read the spend column as a budget line.

What you would build

The bench is a replay harness, and every team that owns a model in production should have one for its own stream. The shape is small: a time-ordered table of rows with the timestamp at which each label actually arrived, a function that trains your real model on a window, and a loop that walks forward, predicts with whatever is in service, and lets a policy object decide when to refit. Score the policy on the rows it had not seen, count the refits, and store both numbers next to the policy's name.

★ The policy, written as datapolicy = { "trigger": "schedule", # or "alarm", "never" "every": "4 weeks", # schedule only "window": "all history", # which labelled rows a refit uses "alarm": None, # e.g. {"metric": "accuracy", "window": "4 weeks", "drop_pts": 10} "label_delay": "1 day", # measured from your own label pipeline, not assumed } # replay(policy, rows) -> {"accuracy": ..., "retrains": ...} # Review it like a budget line: accuracy bought, retrains spent.

The tooling that runs the chosen policy, the scheduler, the registry and the deploy script, is a DataOps job; DataOps session b6 ↗ builds it. This page is about choosing the policy it runs.

Part 2 · covers what the ladder finds

Freshness has a price and a floor

8 min live

These are the numbers the bench prints at a one-day label delay and $500 a retrain, written down so they can be argued with after class. Put the retrain count on one axis and accuracy on the other and the eight policies stop being a list and become a frontier.

WHAT EACH POLICY BOUGHT, AND WHAT IT SPENT label delay 1 day · 14,656 scored rows · retrains on a log scale 60% 64% 68% 72% 76% 0 1 10 100 1,000 10,000 retrains over the replay (log scale; 0 plotted at the far left) No model · 65.35% Never retrain · 68.70% Alarm · 6 retrains · 72.78% 13 weeks · 10 · 72.44% 4 weeks · 32 · 73.11% Weekly · 130 · 73.55% Daily · 915 · 73.55% Weekly, recent only · 130 · 69.88% Every step, 12 hours · 14,655 · 61.91% The dashed line is the frontier. Daily: 915 retrains, weekly: 130, the same 10,779 rows right. Red points spend like weekly or worse.
🔍 Click to zoom - most of the gain arrives with the first handful of retrains; after that you are paying for the habit
LiveFinding 1: never retraining is the most expensive free policy2 min▶

Never retrain costs nothing and scores 68.70 percent. Refitting on all history once a quarter, ten retrains, scores 72.44 percent: 3.75 points for $5,000, about $1,335 a point. The line under the chart shows where the gap opens. Select "Every week" and it reports a best four-week lead of +14.5 points over never retraining, in the four weeks from 19 Nov 1996, six months after launch. That slow slide is what drift looks like from the inside: no alert fired, no pipeline broke, and an uptime dashboard would have shown a healthy model. The same line keeps it honest in the other direction too. The weekly run's worst block, 58.5 percent from 10 Feb 1998, is as bad as never retraining's worst, and in the four weeks from 30 Jun 1998 never retraining beats it by 2.9 points. Retraining raises the average; it does not buy immunity from bad months.

LiveFinding 2: the first few retrains buy almost everything2 min▶

Ten retrains a quarter apart: 72.44. Thirty-two, every four weeks: 73.11. One hundred and thirty, weekly: 73.55. Nine hundred and fifteen, daily: 73.55 again, to the row, 10,779 correct in both. Going from weekly to daily multiplies the retrain bill by seven and buys nothing. On the bench's printed rate, the quarterly policy pays about $1,335 per accuracy point over never, monthly about $3,624, weekly about $13,399.

The alarm policy sits on the knee of the curve: 6 retrains, 72.78 percent, about $735 a point. It refits only when four-week accuracy on labelled rows has fallen 10 points below where that model started. It is not the most accurate policy on the page. It is the cheapest accuracy on the page, which is usually the more useful sentence in a budget meeting.

LiveFinding 3: fresh data is not the same as enough data2 min▶

"Weekly, recent only" retrains exactly as often as "weekly" and spends exactly the same $65,000. The one difference is the refit window: the last four weeks of labels instead of everything labelled so far. It scores 69.88 percent: +1.18 points over never retraining, against +4.85 for the all-history weekly run on the same schedule. On this stream, most of what retraining buys is more data, not newer data. That is a finding about this model on this market, not a law: a stream whose old regime is actively wrong, a fraud pattern that has been shut down, a product that no longer exists, would reward the recent window instead. Which is why the window is a dial on the bench and not a default in the policy.

LiveThe anti-lever: retrain before every prediction2 min▶

The freshest model money can buy: refit before every one of the 14,656 predictions, on the last eight labelled rows, the last twelve hours. It retrains 14,655 times, $7,327,500 at the default rate, and scores 61.91 percent. That is 6.78 points below never retraining and 3.43 points below having no model at all.

The mechanism is arithmetic, not bad luck. Eight rows cannot pin down nine weights; the ridge penalty keeps the solve from blowing up, but what it learns is whatever the last twelve hours happened to look like. Every refit is a fresh overreaction. "Retrain as often as the pipeline allows" sounds like diligence and is, on a small window, a way of paying to replace a model with noise.

Keep the nuance honest. Move the label delay to 1.5 hours and the same policy scores 69.45 percent, slightly above never retraining, because a model refitted on the last twelve hours with labels one row old is partly just copying the last label. Žliobaitė showed in 2013 that on this dataset even a detector firing at random lifts accuracy for exactly that reason. A frantic policy can look good on a stream whose labels are sticky. That is a reason to compare every policy against the no-model rule, which is Part 3.

Part 3 · covers the no-model rung and label delay

When the right policy is no model

6 min live

The first rung on the bench has no model in it. It predicts that the next half-hour will do whatever the last known half-hour did. It needs no training, no serving stack, no monitoring and no retrains. Whether it wins depends entirely on one number most teams never measure: how late the labels arrive.

THE SAME TWO RUNGS AT THREE LABEL DELAYS bars start at 50 percent · ochre = no model, hatched = weekly refit on all history Labels 1.5 hours late Labels 1 day late Labels 1 week late 74.63% 73.51% 65.35% 73.55% 65.80% 73.30% copies the label from 1 row back copies the label from 16 rows back copies the label from 112 rows back no model wins the model earns its place the model earns its place With fresh labels the market's own stickiness beats a nine-input model. A day of delay makes the last label stale, and the model is worth 8.20 points. The week-late rule does a little better than the day-late one because it copies the same half-hour last week.
🔍 Click to zoom - label delay decides whether you need a model before anyone argues about which model
LiveLabel delay is a production fact, not a modelling detail3 min▶

At a 1.5-hour delay the no-model rule scores 74.63 percent and beats every one of the seven model policies, the best of which, weekly on all history, reaches 73.51. Every dollar spent on training, serving and retraining that model buys a worse answer than a one-line rule. At a one-day delay the same rule falls to 65.35 percent and the weekly model beats it by 8.20 points.

The market did not change between those two runs. What changed is when the truth arrives, and that is decided by the business process around the model: how long until a loan defaults, a parcel is returned, a claim is settled, a price is published. Before a team argues about retrain schedules it should be able to answer, with a measured number, "how long after a prediction do we find out whether it was right?" Session 5 builds monitoring on that same number, because an alarm on accuracy can only look at rows whose labels have arrived.

Self-studyWhat the alarm cannot see, and why it still won on cost3 min▶

The alarm watches accuracy on the last four weeks of labelled rows. With labels a week late it is always looking at a window that ended a week ago, and it still scores 72.61 percent on 6 retrains against 72.78 at a one-day delay. That robustness is a property of this stream, which drifts over months rather than hours, and it would not survive a stream that breaks overnight.

Alarm tuning is also less smooth than the headline suggests. On the bench, a 5-point drop threshold fires 8 times and scores 71.38 percent, below the 10-point alarm's 72.78 on 6. Fewer alarms did better because of when they fired, not how many. An alarm is a timing decision, and one good run of one threshold is not a tuning result. Try the thresholds yourself before quoting any of them.

Real world

Elec2 is where the concept-drift field learned this the hard way. Harries published the dataset in 1999 and it became the standard test for adaptive classifiers. In 2013 Indrė Žliobaitė pointed out that the labels are so autocorrelated that the "same as last time" rule scores 85.3 percent on the full file, above most of the adaptive methods then being published on it, and that a change detector firing at random improves accuracy on it. Her recommendation was to compare every result against that rule. The production translation is the no-model rung: before any model ships, the team writes down the simplest rule a clerk could run, and the model has to beat it at the label delay the business really has.

Homework

Before session 5

30 min
  1. Price one retrain on your own team. List every step between "a new model is trained" and "it is serving": validation, review, sign-off, canary, rollback plan, on-call. Put a number of hours on each and turn it into dollars. Put that figure in the bench's cost box and read the ladder again.
  2. Measure your label delay. For one model you own, how long after a prediction does the true outcome land in a table you can query? Median and 90th percentile. If nobody can answer, that is the first finding.
  3. Write your no-model rule. One sentence a clerk could run with no training. Estimate or measure its accuracy at your real label delay, and write down the gap your model has to clear.
  4. Find the knee. On the bench, try three alarm thresholds and two refit windows of your choice. Bring the one policy you would defend, with its two numbers, to session 5.
Check yourself

Three questions

Clear all three and session 4 gets stamped in your passport.

1 · At a one-day label delay, weekly and daily refits on all history both score 73.55 percent. What should a leader take from that?

Both runs call 10,779 of the 14,656 rows right. Freshness has diminishing returns, and past the knee a faster schedule multiplies cost without moving accuracy. D generalises one stream to all of them; the knee has to be found on your own replay.

2 · Retraining before every prediction on the last twelve hours scores 61.91 percent at a one-day delay, below never retraining. Why?

The window is too small for the model, and refitting constantly replaces a reasonable model with a string of overfitted ones. D is contradicted by the bench itself: several policies clear 72 percent.

3 · With labels arriving 1.5 hours late, the no-model rule beats every model policy on the bench. What does that change in a production decision?

Label delay is part of the problem definition. The no-model rung is the baseline every model has to clear, and on a sticky stream with fast labels it is hard to clear. Session 6 turns this into the kill decision.

Sources covered

What this session teaches, and where it came from

✓Elec2, Harries 1999, via OpenML dataset 151 "electricity"45,312 rows, 7 May 1996 to 5 December 1998, UP or DOWN against a 24-hour moving average; downloaded without login and replayed here. Every accuracy and retrain count on the page is computed from it, and a Python reference matches the browser engine row for row
✓Žliobaitė 2013, "How good is the Electricity benchmark for evaluating concept drift adaptation"Read at source on arXiv: the 85.3 percent "moving average of one" and the random-alarm finding. The 85.33 percent is reproduced on the full file in this build
✓Retraining cadence and data freshness as a decisionZinkevich, Rules of Machine Learning, on knowing your system's freshness requirements; the cadence and window trade-offs are measured on the bench rather than asserted
◐Stateless retraining versus continual trainingHuyen, Designing Machine Learning Systems, 2022; reported. The bench only refits from scratch on a window, and says so
◐Drift detection metrics and continuous evaluationNot taught here. The alarm uses plain rolling accuracy; the statistics of drift detection live in Model Evaluation session b9

Every fact on this page, and its verification tier, is recorded in the course's source map.

Session 4 cheat sheet · pin this

Two numbers, alwaysAccuracy bought and retrains spent. One without the other is a habit, not a policy.
Price a retrain in fullValidation, review, canary, rollback, on-call. The compute is the small part.
Find the kneeOn Elec2: 6 alarm retrains buy 72.78; weekly buys 73.55; daily buys the same 73.55.
Window before cadenceSame 130 retrains: all history 73.55, last four weeks 69.88.
Tiny window, every step = worse14,655 refits on 8 rows: 61.91, below never (68.70) and below no model (65.35).
Measure the label delayAt 1.5 hours no model wins (74.63). At 1 day the model wins by 8.20 points.