← SIMRANJAISWAL.INCASE · STUCK MONEY · 07 · MACHINE LEARNING

When will this invoice be paid?

A payment-date model on 48,839 real B2B invoices: for every open invoice, how many days after due it will clear — with a band the model has to earn — which ones will slip past a week, and a $323M order book rolled into a weekly cash forecast. Built with a no-lookahead protocol, judged against the number a good collector already has, exported to plain JavaScript and scoring live on this page.

◈ REAL PUBLIC DATA · 48,839 INVOICES, 1,099 CUSTOMERS · CODE, MODEL AND EVALUATION OPEN
2.8 dMEDIAN ERROR IN DAYS · VS 3.0 FOR THE CUSTOMER'S OWN MEDIAN, 4.4 FOR "PAYS ON THE DUE DATE"
0.87ROC-AUC · "MORE THAN 7 DAYS LATE" · VS 0.80 FOR HISTORY ALONE
$11.3MOF THE $323M OPEN BOOK EXPECTED TO CLEAR OVER A WEEK LATE · ~382 INVOICES
73%OF HELD-OUT INVOICES LANDED INSIDE THE P10–P90 BAND · TARGET 80% · SAID PLAINLY
01 · THE BUSINESS QUESTION

The collector's question is who is late. The CFO's question is when the money lands — and by how much the plan will miss.

Every ledger with terms on it has an open book: invoices posted, not yet paid. Model 06 ranks which accounts to chase. This one answers the question that comes after: for each open invoice, when will it actually clear — not the due date, the real date — and, added up, what does the next quarter's cash look like? A date without a band is a guess dressed up; a forecast without a comparison to the due-date schedule hides how much is slipping. This page gives both, and it is judged against the number a good collector already has in their head: this customer's usual lateness.

02 · THE DATA

Fifty thousand real invoices from one company's receivables — dates, terms, amounts, a masked customer, and the day each one cleared.

The HighRadius B2B invoice dataset, public and anonymised: invoices posted December 2018 to May 2020, in USD and CAD, across a handful of business units. 39,158 have a clearing date; 9,681 are still open — $323.1M, the order book this page forecasts. Terms are mostly net 15; 39% of invoices clear late, 6% more than a week late. It is used here because it is exactly the shape of a receivables ledger: posting_date, due_in_date, amount, customer, clear_date.

FIELDWHAT IT ISUSED AS
posting_date · baseline_create_date · due_in_dateWhen the invoice was raised, when its terms started, when it fell dueTerms length (due − baseline), calendar features; the posting day is the model's "today"
clear_dateWhen it was actually paid (blank for open invoices)The target: days_late = clear − due, negative when early
cust_number · name_customerCustomer id and a masked name (4,197 name variants for 1,099 ids)The id, never the name — history is built per customer
total_open_amount · invoice_currencyInvoice value, USD or CADAmount (log) and the money in the forecast
business_code · cust_payment_termsBusiness unit; a terms code (NAA8, NAH4, CA10…)Unit one-hots; terms as a number of days
area_business · document typeEntirely empty; all but six rows are "RV"Dropped
03 ·TRACEHYGIENE, LOOKAHEAD, AND THE PROTOCOL

Before any model: two date encodings in one file, one customer in forty-three percent of the rows, and a rule that no invoice may know the future.

Hygiene. 1,161 rows were exact duplicates and went. Dates arrive as ISO strings in one column and YYYYMMDD integers in the next — both parsed, and checked against each other. Customer names are masked into variants ("WAL-MAR corp", "WAL-MAR trust", "WAL-MAR llc"…), so the customer id is the key, not the name. One customer accounts for 43% of invoices and $211M — and pays a median four days early, which is why the aggregate cash schedule on this book barely slips. A widely mirrored "new" copy of this dataset has scrambled due dates, some in the year 2157; this page uses the original file, and the README says which.

No lookahead. The strongest features are the customer's history: how late were they last time, how often past a week. Built carelessly, that history leaks — an invoice posted on 3 March must not "know" that an invoice posted on 1 March was paid late on 20 March. So every history feature is computed from invoices cleared before the posting day of the invoice being scored, and the count of that customer's invoices still open on that day is a feature in its own right.

The protocol. A time-based split, not a random one: train on invoices posted before 1 December 2019 (32,395), test on December to February (6,763). Random splits flatter payment models because the same customer's neighbouring invoices land on both sides; a time split is the honest version of "would this have worked last quarter".

# history strictly before the posting day (train.py) — per customer, per invoice
done = (clear < posting_day) & ~isnat(clear)          # only invoices already paid by "today"
f["prior_share_late"]  = (days_late[done] > 0).mean()
f["prior_share_late7"] = (days_late[done] > 7).mean()
f["last3_mean_late"]   = days_late[done][argsort(clear[done])[-3:]].mean()
f["open_count_at_posting"] = (~done & (posting < posting_day)).sum()   # pressure: how much is already outstanding

train = cleared & (posting_date < "2019-12-01"); test = cleared & ~train   # time split, touched once
04 ·AGEWHAT THE LEDGER SAYS BEFORE ANY MODEL

Most invoices clear within a few days either side of due. The lateness lives in the terms, the unit, and the customer's habit.

DAYS LATE AT CLEARING · 39,158 PAID INVOICES

A spike at the due date, a long right tail — the tail is where the cash forecast earns its keep

CLEAR DATE − DUE DATE, ALL PAID INVOICES · 32% CLEAR EARLY, 21% ON THE DAY, 39% LATE, 6% MORE THAN A WEEK LATE.
THE TERMS ARE THE STRUCTURAL TELL

Share paid more than 7 days late, by payment terms

NET-0 DOCUMENTS CLEAR A MEDIAN 39 DAYS LATE; NET-15, THE BULK, A MEDIAN 0 · TERMS WITH ≥ 300 INVOICES.
HABIT PREDICTS

Share paid more than 7 days late, by the customer's prior record

PRIOR SHARE OF INVOICES OVER A WEEK LATE (NO LOOKAHEAD) · A CUSTOMER WITH A 25%+ RECORD SLIPS 58% OF THE TIME.
BUSINESS UNITINVOICESMEDIAN DAYS LATEOVER 7 DAYS LATE
05 ·RANKTHE MODELS, AND WHETHER TO BELIEVE THEM

Three baselines had to be beaten, and the hardest was the collector's own number. The model beats it — modestly on the date, clearly on the slip, and with a band the baseline cannot give.

PREDICTOR OF DAYS LATEMAE, DAYS · HELD-OUT DEC–FEBWHAT IT IS
"MORE THAN 7 DAYS LATE"AUCPR-AUCBRIER
THE DATE, AND THE BAND

Actual vs predicted days late, 600 held-out invoices

DOTS = INVOICES · THE DIAGONAL IS PERFECT · VERTICAL TICKS = THE P10–P90 BAND · 73% OF INVOICES SIT INSIDE THEIR BAND AGAINST AN 80% TARGET.
WHERE THE ERROR SITS

Predicted minus actual, days

HALF THE INVOICES ARE WITHIN A DAY · THE MODEL IS LATE TO CALL THE BIG SLIPS, NOT EARLY — THE LEFT TAIL IS INVOICES THAT CLEARED LATER THAN PREDICTED.
THE SLIP FLAG

ROC — "more than 7 days late"

HELD-OUT · AUC 0.870 · THE DIAGONAL IS RANDOM.
WHAT THE FLAG BUYS YOU

Slip rate by model decile

TOP DECILE SLIPS 38% OF THE TIME AGAINST A 5.9% BASE · THE BOTTOM HALF UNDER 2%.

By history depth and by amount — where the model helps, and where nobody can

SEGMENTINVOICESMAE · MODELMAE · CUSTOMER MEDIANSLIP RATE

A first invoice from a new customer is a seven-day guess for anyone; with twenty invoices of history the error is two and a half days. Large invoices are the most predictable — they belong to the customers with the longest records. This is the honest shape of the problem: the customer's own history is most of the signal; the model's job is to combine it with terms, calendar and pressure, and to put a band on it.

WHAT THE DATE MODEL LEANS ON
GRADIENT-BOOSTING FEATURE IMPORTANCE (SHARE OF SPLIT GAIN), MEDIAN MODEL · TOP TEN OF 22 · THE DUE DAY-OF-WEEK MATTERS BECAUSE PAYMENT RUNS HAPPEN ON FIXED DAYS.
06 ·SEALTHE SCORER · RUNNING IN YOUR BROWSER

Describe an invoice and its customer. Four exported models give a date, a band, a slip probability, and the reasons — same trees as the Python.

LOADING MODEL…
REAL HELD-OUT INVOICES:

WHY · DAYS ADDED OR REMOVED BY EACH FEATURE, MEDIAN MODEL
THE DATE IS THE MODEL'S; THE INVOICE IS YOURS. CONTRIBUTIONS ARE PATH ATTRIBUTIONS ACROSS ALL 220 TREES OF THE MEDIAN MODEL AND SUM EXACTLY TO ITS OUTPUT. POSITION IS AGAINST 1,000 HELD-OUT INVOICES, BY P(SLIP) × AMOUNT.
07 ·WATCHTHE CASH FORECAST · THE OPEN BOOK, WEEK BY WEEK

9,681 open invoices, $323 million. When it is due, when the model says it lands, and how sure it is.

Each open invoice gets a p10, a median and a p90 for days late. Four hundred Monte-Carlo draws through that band turn the book into a weekly schedule with its own band, set against the schedule the due dates promise. On this ledger the two lines nearly coincide — the dominant customer pays early and most terms are net 15 — which is itself the finding: the aggregate is healthy; the risk is concentrated in a tail of ~382 invoices worth $11.3M, listed below.

DUE-DATE SCHEDULEFORECAST · MEDIANP10–P90 BAND

Weekly cash, due vs forecast

WEEKS FROM 24 FEB 2020 · BARS = AMOUNT DUE THAT WEEK · LINE AND BAND = FORECAST CLEARING, 400 SIMULATIONS · INVOICES TREATED AS INDEPENDENT, SO REAL BANDS ARE WIDER.
CUMULATIVE DUECUMULATIVE FORECAST · MEDIAN, WITH BAND

Cumulative cash collected

THE GAP BETWEEN THE TWO LINES IS THE SLIP · SMALL ON THIS BOOK, BUT THE BAND SAYS HOW SMALL.

The chase list — open invoices by amount × probability of slipping past a week

#AMOUNTDUEP(SLIP > 7 D)EXPECTED DAYS LATE · BANDUNIT · HISTORY

The first row is the kind of thing a ranked list exists for: a $654k invoice from a customer with two prior invoices and a one-in-four chance of slipping — not the latest, not the most likely, but the most expensive to be wrong about. Rows two and three are the opposite: modest amounts, a long record, and a 97% probability of clearing a month late. Different calls, same list.

08 ·WATCHTHE MODEL CARD, AND WHAT WOULD MAKE IT WRONG
CARD
Intended useA cash forecast with bands for treasury, and a chase list ranked by expected late value for collections. Decision support for humans; exclusions and disputes run before any score, as in case 04.
Training dataHighRadius B2B invoices, one company, posted Dec 2018 – Nov 2019 (32,395 invoices); tested on Dec 2019 – Feb 2020 (6,763); open book Feb – May 2020 (9,681).
Not valid forAny other ledger, and this one after a change of terms policy. Mostly net-15, one dominant early payer, USD and CAD mixed without conversion (CAD is 8% of invoices). The method transfers; the model does not.
Known failure modesNew customers (seven-day error, nothing to learn from yet). Big slips: the model is late to call them, not early. The p10–p90 band covers 73%, not 80% — widen by the measured factor before use. The Monte-Carlo forecast treats invoices as independent; a customer who slips, slips on every invoice at once, so real bands are wider. December's dip in lateness (1.4% vs 7%) is a year-end effect the model has seen once.
MonitoringWeekly: forecast vs actual cash by week; MAE and band coverage on invoices cleared that week; slip-flag calibration by decile; population-stability index on prior_share_late and term_days. Re-fit monthly, and immediately after any terms change.
ExplainabilityPer-invoice path contributions in days (shown above), summing exactly to the prediction; global importance by split gain; the baseline comparison published alongside every metric.
09 · THE TAKEAWAY

A cash forecast is a payment-date model with a band, added up. Most of what there is to know about when an invoice clears is already in the customer's own history — the model's honest gain over that is seven percent on the date and seven AUC points on the slip. What the model adds that no median can is the band, the probability, and the roll-up: a weekly schedule the treasury can plan on, and a short list of invoices where being wrong is expensive. On this book the aggregate barely slips; the $11.3M tail is the whole story, and it fits on one page.

A MACHINE-LEARNING PROJECT ON PUBLIC DATA, NOT CLIENT WORK. DATASET: THE HIGHRADIUS B2B INVOICE DATASET (ANONYMISED; ONE COMPANY'S RECEIVABLES, DEC 2018 – MAY 2020; 50,000 ROWS, 48,839 AFTER DE-DUPLICATION). ALL MODEL METRICS ARE ON A TIME-BASED HOLD-OUT (INVOICES POSTED DEC 2019 – FEB 2020) SCORED ONCE; DESCRIPTIVE CHARTS USE ALL PAID INVOICES. THE IN-BROWSER MODELS REPRODUCE THE PYTHON MODELS TO WITHIN 1E-6. THE FORECAST IS A MONTE-CARLO ROLL-UP OF PER-INVOICE BANDS AND TREATS INVOICES AS INDEPENDENT. AMOUNTS ARE AS RECORDED (USD AND CAD, UNCONVERTED). CODE (TRAIN.PY), MODEL.JSON, EVALUATION.JSON AND A README ARE PUBLIC AT /ML/INVOICE-PAYMENT-DATE/.

Have an open book and a cash plan that keeps missing? A payment-date model with bands on your own ledger is a Seal-sized piece of work: two to four weeks, fixed fee, forecast and chase list included. It starts with a TRACE of where the dates come from.

Start with a TRACE → train.py README model.json