learn-sales-pipeline-analytics-with-phoebe / Analyst session 5 of 6
Learn B2B Sales Pipeline Analytics with Phoebe · Analyst session 5 of 6

Bias, error and the track record

Last session three methods each forecast one quarter, and one of them landed closest. That tells you almost nothing. A method that wins one quarter can lose the next five, and a rep who is right on average can be wrong by two thirds every single quarter. Tonight you score forecasts the way a finance team scores them: over many quarters, with three separate numbers. Bias says which way a forecast leans. Error says how far it misses. Coverage says whether its range can be trusted. The outcomes are real Olist rows; Kettle & Co's stages, amounts and reps are constructed and labelled.

🟠 Analyst Data analysts who build pipeline reporting and forecasts Hands-on in the browser 45 min
0-3 · Welcome 3-18 · Replays, bias vs error, honest ranges 18-40 · Build-along: score twenty quarters 40-45 · Q&A
Part 0

Where we start

You can rebuild the pipeline on any date (Analyst session 1), measure conversion by cohort (session 2), read cycle time with open deals left in (session 3), and produce three forecasts for a quarter (session 4). Tonight is about the track record: the scores that tell a BD lead which forecast to believe next quarter, and by how much. The scores here are for sales forecasts built deal by deal. The metric families used to compare statistical forecasting models, and the backtesting that goes with them, belong to Learn Timeseries Forecasting with Phoebe; the ideas rhyme, the inputs differ.

🎫 Clear all three quiz questions to stamp your passport Live = presented in the 45 minutes Self-study = the full depth, after class ★ Build-along = everyone builds it

★ What you walk out with tonight. Three definitions you can write on a whiteboard without notes, a 2x2 that separates a leaning forecast from a noisy one, a coverage check for any range a forecast publishes, and a short pandas script that scores your own past quarters from frozen snapshots. Analyst session 6 runs the whole ladder on one bench; tonight builds the scoreboard it uses.

Part 1 · covers forecast vs actual over many quarters

One quarter is an anecdote

5 min live

A single quarter gives each forecast one miss. One miss has a size and a sign, but it cannot tell you whether the forecast leans, because a lean only shows up when the misses keep falling on the same side. So the bench replays the quarter twenty times. Each replay draws a different 300 deals from the same 3,465 real open leads, keeps who really closed between 1 June and 30 August 2018, and lays Kettle & Co's constructed stages, amounts and reps over the top with a fixed seed. Across those twenty quarters, the average quarter really closed 4.57m yen.

ONE METHOD, TWENTY QUARTERS history-based · dot positions illustrative · summary numbers printed by the widget History-based each dot is one replayed quarter: (forecast - actual) / actual bias +18.6% error 38.8% coverage 17 of 20 average actual 4.57m yen under-forecast over-forecast bias +18.6% this quarter: -14.5% -100% -50% 0 +50% +100% +150% Bias is where the dots sit on average. Error is how far they sit from zero, with the sign ignored.
🔍 Click to zoom - the filled dot alone says "leans low"; the twenty together say "leans high", and only the twenty can say it
LiveThree definitions, exactly3 min▶

Every number on the widget comes from one of these three. Write them down in this form, because small changes in wording produce different numbers.

★ The scoreboardbias = total (forecast - actual) / total actual over all quarters error = mean |forecast - actual| / mean actual over all quarters coverage = quarters whose actual fell inside the range e.g. 17 of 20

Bias keeps the sign, so overs and unders cancel. It answers "which way does this forecast lean?" Error drops the sign, so nothing cancels. It answers "how far off is a typical quarter?" Coverage ignores the point forecast and checks only the range, so it answers "when this forecast says 'somewhere between', can I plan on that?"

Both bias and error are scaled by actuals in total, not quarter by quarter. A tiny quarter with a huge percentage miss would otherwise dominate the average, which is the main reason per-quarter percentage averages behave badly on lumpy sales numbers.

Self-studyHow the twenty replays are built, and how yours would differ3 min▶

On the bench. The open pool is 3,465 real Olist leads first contacted March to May 2018 and not won by 1 June 2018. Each replay draws 300 of them; draw 0 is "this quarter", the one Analyst session 4 forecast. Which leads really closed in the 91 days to 30 August 2018 is real. Stages, amounts and which rep owns a deal are constructed with seed 20181011, so every reload prints the same numbers.

On your own data. You do not need replays: you have past quarters. For each one you need two frozen things, the forecast as it was submitted and the pipeline snapshot it was made from (the as-of join from Analyst session 1), plus what really closed by quarter end. Eight quarters is a thin track record; twelve is better. Replays stand in for that history here because the public rows cover only one usable quarter.

What replays cannot do. Every replay shares the same market, the same season and the same buyers' behaviour. Real quarters differ in all three, so a real track record will usually look worse than a replayed one.

Real world

The sign flipped. On this quarter alone, the history-based forecast missed by -14.5%: it under-called what really closed in the Olist rows. Judged on that one quarter, you would conclude it is cautious and nudge it up. Over the twenty replays it leans the other way, +18.6%. The quarter Analyst session 4 used happened to close 5.86m yen against an average of 4.57m, a strong quarter, and a strong quarter makes every forecast look cautious. One quarter told you the opposite of the truth, and nothing on the page warned you.

Part 2 · covers bias vs error

Unbiased is not the same as useful

5 min live

Bias and error measure different failures, and a forecast can pass one and fail the other. A rep who over-calls by a million one quarter and under-calls by a million the next has zero bias and a large error. A forecast that is always 10% high has bias and error both at 10%, and it is easy to fix. The one shape that cannot exist is high bias with low error: the average miss, sign ignored, is never smaller than the size of the average lean.

BIAS AND ERROR ARE TWO DIFFERENT QUESTIONS twenty replays · methods filled, reps hollow · Kettle's reps constructed error: average miss / average actual (up) 0% 50% 100% 0% 50% 100% size of bias: |total forecast - total actual| / total actual low bias, high error high bias, high error the goal empty by arithmetic: error is never below |bias| 1 2 3 4 5 6 7 BIAS / ERROR, 20 REPLAYS 1 History-based +18.6% / 38.8% 2 Rep commit +33.9% / 48.2% 3 Stage-weighted +62.7% / 68.2% 4 Aiko: ratio 0.98 (-2%) / 68.0% 5 Chiara: ratio 1.45 (+45%) / 69.7% 6 Dev: ratio 0.00 (-100%) / 100.0% 7 Ben: ratio 4.60 / 360.1%, off chart rep bias = call ratio - 1 (arithmetic) Aiko: unbiased and useless Points below the diagonal cannot exist: the average miss is never smaller than the size of the average lean.
🔍 Click to zoom - the copper dot sits at almost zero bias and still misses by two thirds; low bias alone earns nothing
LiveThe method table, read row by row3 min▶

Rep commit: +33.9% bias, 48.2% error. It leans high, and most of its error is that lean. A steady lean is the most fixable fault a forecast can have, as long as it stays steady.

Stage-weighted: +62.7% bias, 68.2% error. It leans hardest of the three. Almost all of its error is lean, which says the stage table (Kettle's own, from the prior quarter) is set too generously for the deals now in the pipe.

History-based: +18.6% bias, 38.8% error. The smallest of both, and still not small. Over half its error is noise rather than lean, which is what you expect from about seven wins a quarter: a couple of deals arriving a week early or late moves the actual a long way.

LivePer rep: the call ratio2 min▶

The call ratio is a rep's total commit over twenty quarters divided by what that rep really closed. It is the rep's bias plus one. Above 1 over-calls, below 1 under-calls.

Aiko, 0.98. Unbiased in total, 68.0% error per quarter. As a single-quarter call her number is close to useless, yet she is the rep most managers would hold up as "accurate". Ben, 4.60. He commits from stage 4, a stage below the others, and over-calls more than four-fold; error 360.1%. Chiara, 1.45. Mildly high, 69.7% error. Dev, 0.00. He commits only once a contract is signed, so his commit is always zero and his error always 100.0%. That is an under-caller, often called a sandbagger, and his zero tells the BD lead nothing about what he will close.

Self-studyWhy the best method still leans high2 min▶

History-based learns conversion from earlier cohorts. In the real Olist rows the May 2018 cohort converted 10.0%, against 13 to 14% for January to April. A history-based forecast assumes the next quarter's leads behave like the last ones, so when a weaker cohort arrives it over-calls. That is the honest limit of the method: it cannot see a change it has not yet lived through. The remedy is not a cleverer formula; it is watching the lean quarter by quarter and asking why when it moves.

Self-studyWhat to do with an over-caller or an under-caller2 min▶

A systematic lean is a pattern in how a person reads deals, so it is a coaching conversation for the BD lead, not something data should quietly correct. If an analyst divides Ben's commit by 4.60 every quarter, three things go wrong: Ben never learns, nobody notices when he changes, and the forecast now depends on a private adjustment no one signed off. Show the call ratio to the BD lead and to Ben, agree what "commit" means, and keep scoring. Who owns that conversation, and who owns the method, is the subject of Business session 3, Who owns the forecast.

Dev's case is different. A zero is not a lean you can scale, because zero times anything is zero. The fix is a definition: commit means a deal the rep expects to sign this quarter, not one already signed.

Real world

Constructed Kettle & Co example. In a forecast call, the BD lead praises Aiko for being "spot on over the year": her twenty-quarter call ratio is 0.98. The analyst puts the error column beside it: 68.0% per quarter. Both are true. Over a year her overs and unders cancel, so her total is right, but in any single quarter her number misses by about two thirds, and the BD lead plans quarters, not years. The right sentence for the call is "Aiko is honest and noisy; Ben is consistent and high; Dev is silent". Each one needs a different conversation.

Part 3 · covers honest error bands

An 80% range should miss about four quarters in twenty

5 min live

A forecast that publishes a range is making a second promise: "the actual will land in here about this often". That promise can be scored on its own. An 80% range should cover the actual in about 16 of 20 quarters. History-based covers 17, which is what an honest range looks like. Stage-weighted covers 10: its range is too narrow, aimed too high, or both. Rep commit covers 4, because its floor, the commit itself, usually sits above what really closed.

THREE RANGES, TWENTY ACTUALS bar: one replay's range · dot: what really closed · layout illustrative, counts real Rep commit 4 of 20 floor sits above the actual Stage-weighted 10 of 20 too narrow, aimed high History-based 17 of 20 close to the 16 expected filled bar: the range covered the actual · copper outline: the range missed it An honest 80% range misses about 4 quarters in 20. Covering 17 is consistent with that; 10 and 4 are not.
🔍 Click to zoom - count the copper outlines, not the bar heights: coverage is a promise about how often, and it is scored by counting
LiveHow the ranges are built, and why they are lumpy3 min▶

Rep commit's range runs from the commit to commit plus best case, so it is two rep judgements stacked. Stage-weighted and history-based ranges are modelled: the point forecast plus and minus 1.2816 standard deviations, a normal approximation of a sum of yes-or-no deals, each with its own win probability. That is the standard 80% band under a normal curve, and it is labelled as modelled on the widget.

The approximation is rough here. This quarter, 7 deals won out of 300. A sum of seven or so wins is lumpy: one large deal closing or slipping moves the actual by more than the smooth bell curve expects. So even an honest modelled range should be read as "about 80%", and coverage is the check on whether "about" is close enough.

LiveReading a coverage count2 min▶

Twenty quarters is a small sample, so 16 of 20 is the centre of a spread, not a pass mark. Constructed arithmetic for an honest 80% range: the count of covered quarters has a standard deviation of the square root of 20 x 0.8 x 0.2 = 3.2, which is 1.79. So 14 to 18 covered is ordinary; 17 is comfortably inside.

10 of 20 is more than three standard deviations below 16. An 80% range that covers half the time is either too narrow, centred in the wrong place, or both. With stage-weighted's +62.7% bias, the centre is the larger problem. 4 of 20 for rep commit is not a calibration slip at all: the range starts at the commit, and the commit sits above the actual in most quarters.

Coverage that is too high is a fault too. A range covering 20 of 20 every time is usually so wide it does not help anyone plan.

Self-studyHappy ears: what moves and what does not3 min▶

"Happy ears" is the sales habit of hearing a yes the buyer never said. On the bench, the checkbox moves 30% of Kettle's deals below stage 5 up one stage (constructed). Then:

  • Rep commit bias rises from +33.9% to +121.5%; coverage falls from 4 to 0 of 20.
  • Stage-weighted bias rises from +62.7% to +134.0%; coverage falls from 10 to 3 of 20.
  • History-based is unchanged: it reads each deal's origin and age, never its stage.
  • Reps: call ratios move to Aiko 1.69, Ben 8.15, Chiara 2.18, Dev 0.00. Dev does not move, because he still commits only signed deals.

History-based's immunity is also its blind spot. It cannot be inflated by a rep's optimism, and for the same reason it cannot see a real late-stage signal either. Analyst session 6 puts that trade-off on one bench.

Self-studyWhat about published forecast-accuracy surveys?2 min▶

Forecasting and revenue-intelligence vendors and analyst firms publish surveys on how few sales forecasts land within some band of the actual. Leaders disagree about what they are worth. Some use them as an outside anchor: if most teams miss widely, a 38.8% error is not a crisis. Others treat them as marketing, because the method and sample are usually not published and the publisher sells the fix. Both readings are reasonable, and no survey figure is quoted here for that reason. Your own twenty quarters, scored with the definitions above, are a better benchmark than any survey for the one decision that matters: which forecast your BD lead should believe next quarter.

Real world

Constructed Kettle & Co example. Before a board meeting, the reps get optimistic about the trials running in the office-tea pipeline, and three in ten deals below Contract out move up a stage. The stage-weighted range shifts up with them; across twenty replays it now covers the actual in 3 quarters of 20, down from 10. The history-based range does not move at all, because nothing it reads has changed. If your team publishes only the stage-weighted number, nobody in the room can tell optimism from progress. Publishing both, with their coverage, makes the gap visible.

Build-along

Score twenty quarters, then score your own

★ 22 min · everyone builds

The widget replays Kettle & Co's quarter twenty times in your browser and scores all three methods and all four reps with the definitions from Part 1. The outcomes come from real Olist B2B funnel rows (Brazilian marketplace seller acquisition) standing in for Kettle's history; stages, amounts, reps and the 300-deal draws are constructed and seeded. Work the five steps, copy what the widget prints, and finish by writing the same scoring for your own past quarters.

WHAT THE WIDGET DOES WHEN YOU TICK THE BOX Happy ears checkbox, off at first 20 replays of the quarter 300 deals each, seeded 3,465 real open leads who closed is real Olist verdict: average actual, smallest error methods: bias, error, range covered actual reps: commits at stage, call ratio, error Ticking happy ears re-runs all twenty replays; only the methods that read stages can move.
🔍 Click to zoom - the copper box is the whole technique: score many quarters, never one

Step 1 · Read the verdict. Copy it. The 4.57m yen is the average over twenty replays; set it beside the 5.86m yen that closed in Analyst session 4's single quarter, and you have the reason one quarter misleads.

★ Step 1 · what the widget printsAverage quarter: 4.57m yen really closed. Smallest error: history-based, 38.8%.

Step 2 · Read the method table. For each row, write one word for the bias (leans high, leans low, level) and one for the range (honest, too tight, misplaced). Then check each against the 2x2 in Part 2.

★ Step 2 · bias, error, coverage over 20 quartersMethod Bias (20 quarters) Error (20 quarters) Range covered actual Rep commit +33.9% 48.2% 4 of 20 Stage-weighted +62.7% 68.2% 10 of 20 History-based +18.6% 38.8% 17 of 20

Step 3 · Read the rep table. Find the rep who is unbiased and still useless as a single-quarter call, and the one whose number carries no information at all. Write the one-line coaching note you would hand the BD lead for each rep.

★ Step 3 · four reps, twenty quartersRep Commits at stage Call ratio Error per quarter Aiko 5 and above 0.98 68.0% Ben 4 and above 4.60 360.1% Chiara 5 and above 1.45 69.7% Dev only once signed 0.00 100.0%

Step 4 · Tick happy ears and read what changed. Compare both tables with Steps 2 and 3. Mark which rows moved and which did not, and say why in one sentence each.

★ Step 4 · happy ears onMethod Bias (20 quarters) Error (20 quarters) Range covered actual Rep commit +121.5% 121.5% 0 of 20 Stage-weighted +134.0% 134.0% 3 of 20 History-based +18.6% 38.8% 17 of 20 (unchanged) Rep Call ratio Error per quarter Aiko 1.69 97.8% Ben 8.15 715.1% Chiara 2.18 129.0% Dev 0.00 100.0%

Step 5 · Write the scorer for your own quarters. One row per past quarter and method, holding the forecast exactly as submitted on day one, with its range, and frozen from the snapshot of that day (Analyst session 1). Add what really closed. The script below scores it; run it on your data and read your own numbers, there are none to copy here.

★ Step 5 · bias, error, coverage in pandasimport pandas as pd # one row per quarter x method, frozen on the quarter's first day # columns: quarter, method, point, lo, hi, actual q = pd.read_csv("forecast_track_record.csv") def score(g: pd.DataFrame) -> pd.Series: miss = g["point"] - g["actual"] inside = (g["actual"] >= g["lo"]) & (g["actual"] <= g["hi"]) return pd.Series({ "quarters": len(g), "bias": miss.sum() / g["actual"].sum(), "error": miss.abs().mean() / g["actual"].mean(), "covered": int(inside.sum()), }) print(q.groupby("method").apply(score)) # per rep: call ratio = total commit / total closed r = pd.read_csv("rep_commits.csv") # quarter, rep, commit, closed t = r.groupby("rep")[["commit", "closed"]].sum() print((t["commit"] / t["closed"]).round(2))

If you prefer SQL, the same three numbers are SUM(point - actual) / SUM(actual), AVG(ABS(point - actual)) / AVG(actual) and SUM(CASE WHEN actual BETWEEN lo AND hi THEN 1 ELSE 0 END), grouped by method.

Score only frozen forecasts. If anyone can edit last quarter's forecast after the quarter starts, the track record measures the editing, not the forecasting. Store each forecast with its submission date and the snapshot it was made from, and score that copy.

Homework

Before Analyst session 6

30 min
  1. Collect your track record. For as many past quarters as you can (eight at least), find the forecast as submitted on day one and what really closed. Note any quarter where the submitted number no longer exists.
  2. Run the scorer from Step 5 on it, for the team number and for every method your team has used. Write down bias, error and, if a range was published, coverage.
  3. Compute each rep's call ratio over the same quarters, with their error per quarter beside it. Mark anyone above 1.3 or below 0.7, and anyone near 1 with a large error.
  4. Draft one paragraph for your BD lead: which forecast leans, which is noisy, whose range can be planned on, and which rep conversations are worth having. No adjustments applied silently.
Check yourself

Three questions

Clear all three and Analyst session 5 gets stamped in your passport.

1 · Aiko's call ratio over twenty quarters is 0.98 and her error per quarter is 68.0%. What is the fair summary?

Bias lets overs and unders cancel; error does not. Near-zero bias with a large error is "unbiased and useless" as a single-quarter call.

2 · A method publishes an 80% range. Over twenty quarters the actual fell inside it 10 times. What does that say?

About 14 to 18 of 20 is ordinary for an honest 80% range. 10 is far below it: the range is mis-sized or mis-centred, and stage-weighted's +62.7% bias points at the centre.

3 · Ben's call ratio is 4.60, steady for a year. What should the analyst do?

A systematic lean is a coaching conversation the BD lead owns. A silent correction hides the problem, stops Ben learning, and breaks the moment he changes.

Sources covered

What this session teaches, and where it came from

✓Which open leads really closed between 1 June and 30 August 2018, and the May 2018 cohort's weaker conversionOlist, "Marketing Funnel by Olist", Kaggle dataset, CC BY-NC-SA 4.0. Read at source
◐Twenty replays, Kettle & Co's stages, amounts, reps and every bias, error and call ratioConstructed and seeded (20181011); printed by the widget on this page
◐Stage-weighted and history-based 80% rangesModelled: point plus or minus 1.2816 standard deviations, a normal approximation of a sum of yes-or-no deals
◐Vendor forecast-accuracy surveysContested: method and sample rarely published; no figures quoted

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

Analyst session 5 cheat sheet · pin this

Many quarters, never oneOne quarter has a miss but no bias. This quarter said -14.5%; twenty said +18.6%.
BiasTotal (forecast - actual) / total actual. Keeps the sign: which way it leans.
ErrorMean |forecast - actual| / mean actual. Drops the sign; never smaller than |bias|.
CoverageQuarters inside the range. An honest 80% range: about 16 of 20, 14 to 18 is ordinary.
Call ratioRep's total commit / what they closed. Aiko 0.98 at 68.0% error: unbiased and useless.
Leans are conversationsShow the BD lead and the rep; never correct a rep's number silently.