Un operatore della ristorazione fresca è venuto da noi con una domanda semplice: potete prevedere la domanda di domani per piatto, per sede, con sufficiente precisione da farci smettere di buttare margine e di andare in rottura di stock a pranzo? Diciotto mesi dopo, la piattaforma prevede con il 98% di precisione in produzione. Si presume che la parte più difficile fosse il machine learning. Non lo era.
Il modello che fa la previsione è un regressore a gradient boosting a cui sono state innestate alcune variabili di stagionalità. Un data scientist competente può mettere in piedi qualcosa di questa famiglia in un pomeriggio. Avevamo una prima versione rispettabile in meno di tre settimane — abbastanza precisa nel backtest da far annuire tutti nella stanza.
Abbiamo poi passato cinque mesi a costruire tutto ciò che trasforma «un backtest preciso» in «un numero su cui un responsabile operativo scommette la sua giornata». Questo divario è tutto il mestiere, e quasi nessuno ne parla perché non è affascinante. Eccolo, allora.
01Il modello in tre settimane
Prevedere la domanda di un'attività stabile e ben registrata è, francamente, un problema risolto. Avete un obiettivo (unità vendute), un calendario e un mucchio di righe storiche. Progettate qualche decina di variabili — giorno della settimana, finestre di lag, medie mobili, festività, una join con i dati meteo — e lasciate che una libreria di boosting trovi le interazioni. Non è nella matematica che i progetti muoiono.
Ciò che le tre settimane ci hanno realmente comprato è la certezza che il segnale esistesse, semplicemente. Il backtest ci diceva che la domanda era prevedibile con uno o due punti percentuali di scarto, a condizione di avere input puliti. È il via libera. Non è il prodotto.
Un buon numero di backtest è l'artefatto più pericoloso del machine learning. Sembra il traguardo quando è a malapena lo sparo di partenza. I backtest girano su dati che sono stati puliti, uniti e allineati nel tempo da un essere umano che già conosce la risposta. La produzione non ha nessuno di questi lussi.
02Dove sono finiti i cinque mesi
Ecco il bilancio onesto dei cinque mesi successivi. Nulla di tutto ciò è modellazione. Tutto questo è ciò che ha reso il modello utilizzabile.
- Un'ingestione che sopravvive alla realtà. I flussi di vendita arrivano in ritardo, duplicati o non arrivano affatto. Un POS si riavvia e riproduce la giornata precedente. Abbiamo costruito un'ingestione idempotente che può essere rieseguita in sicurezza e che mette in quarantena le righe di cui non si fida, anziché avvelenare il set di addestramento.
- Un feature store dotato di memoria. Le variabili su cui il modello si addestra devono essere calcolabili al momento della previsione, con i soli dati di cui disporreste effettivamente in quell'istante — senza sbirciare nel futuro. Far rispettare questa correttezza point-in-time ha richiesto settimane di lavoro e ha permesso di intercettare due fughe di dati che avevano gonfiato il backtest iniziale.
- Backfill e replay. Quando lo storico di una sede era errato, dovevamo ricostruire tutte le previsioni a valle per quella sede senza arrestare il sistema live. Il replay è quella tubatura che nessuno mostra nelle demo e di cui tutti hanno bisogno.
- Il monitoraggio prima delle funzionalità. Abbiamo rilasciato gli allarmi di drift e di freschezza prima di rilasciare metà dell'interfaccia. Una previsione silenziosamente errata è peggio di una previsione visibilmente assente.
- L'override umano. Apre una nuova sede, arriva un festival, chiude una strada. Il modello non può saperlo. I pianificatori avevano bisogno di un modo autorizzato per correggere il numero e di far sì che il sistema imparasse da quella correzione.
Il modello risponde a una domanda. La piattaforma decide quale domanda, con quali dati, per chi, e cosa succede quando la risposta è sbagliata.
— Sul perché la confezione è il vero lavoro03Il contratto sui dati
La cosa a più alto effetto leva che abbiamo costruito non è stata un miglioramento del modello. È stato un contratto sui dati: uno schema esplicito e validato tra ogni sorgente a monte e la nostra pipeline. Tipi di colonna, intervalli consentiti, finestre di freschezza, politiche sui valori nulli — tutto dichiarato, tutto verificato alla porta.
Prima del contratto, una previsione poteva degradarsi in silenzio perché un fornitore POS aveva cambiato un campo valuta dai centesimi ai dollari senza avvisarci. Dopo il contratto, quel cambiamento viene respinto all'ingestione con un errore con un nome ed escalation — e l'ultima buona previsione resta sullo schermo invece di una nuova, sicura di sé e sbagliata.
# ogni sorgente è validata alla porta, non dopo che ha avvelenato l'addestramento sales_daily: units: int >= 0 # rifiuta i negativi — i rimborsi vanno altrove revenue: decimal(10,2) # centesimi → segnalato in v3, ora applicato site_id: fk(sites) # sede sconosciuta → quarantena, escalation al reperibile recorded_at: freshness <= 6h # flusso scaduto → mantieni l'ultima buona previsione on_violation: quarantine + alert # mai: addestrarci sopra in silenzio
Questo è il cuore poco affascinante di ogni sistema ML in produzione che abbiamo consegnato. Il modello è una funzione; il contratto è ciò che garantisce che la funzione riceva gli input che è stata addestrata ad aspettarsi. Saltatelo e non avrete una piattaforma di previsione — avrete un generatore di numeri casuali molto costoso che ci azzecca quasi sempre.
04Il drift è una funzionalità, non un fallimento
Ogni modello si degrada. I gusti evolvono, arriva un nuovo menu, un concorrente apre di fronte. La domanda non è mai se il mondo si sottrarrà al vostro modello — è se lo apprenderete da una dashboard o da una telefonata furiosa.
Trattiamo il rilevamento del drift come una funzionalità di prodotto di primo livello. La piattaforma confronta continuamente le distribuzioni degli input live e l'errore live con i riferimenti di addestramento. Quando l'uno o l'altro supera una soglia, fa tre cose, nell'ordine:
- Avvisa qualcuno — un essere umano preciso, con la sede, la metrica e di quanto si è spostata.
- Protegge l'output — allargando gli intervalli di confidenza o ripiegando su un riferimento più semplice e più robusto, anziché fidarsi di un modello che ora estrapola.
- Programma un riaddestramento — con i nuovi dati, condizionato alla stessa soglia di backtest che l'originale doveva superare.
Mantenuta in produzione, non solo nel backtest.
I frigoriferi vuoti a pranzo, ridotti di oltre la metà.
Margine che un tempo veniva buttato a fine giornata.
Notate che il numero di punta — 98% — non è il più interessante. I numeri interessanti sono i due che lo circondano, perché sono questi che l'azienda sente. La precisione è l'input; meno spreco e meno rotture di stock sono l'output. Una piattaforma che ottimizza il primo ignorando il secondo è un progetto da laboratorio.
05La dashboard che qualcuno consulta alle 8 del mattino
La previsione è consumata da uno chef all'inizio di un servizio, su un tablet, caffè alla mano, in novanta secondi. Questo vincolo ha plasmato più decisioni di quanto abbia fatto l'architettura del modello.
Imponeva che la risposta fosse una quantità, non una distribuzione di probabilità. Imponeva che «non sono d'accordo, ecco perché» entrasse in un solo tap. Imponeva che lo schermo mostrasse la previsione di ieri a fronte di ciò che è realmente accaduto, perché la fiducia si guadagna rendendosi visibilmente responsabili, non mostrandosi sicuri di sé. Un modello incapace di mostrare il proprio storico alla persona che vi si appoggia verrà ignorato in silenzio in meno di una settimana.
Non lo score F1. Non l'RMSE. Il test di accettazione è stato uno chef, alla seconda settimana, che dice «sì, ormai faccio semplicemente quello che dice». Questa frase vale più di qualsiasi metrica offline, e la si guadagna solo progettando gli ultimi novanta secondi con la stessa cura del modello.
06Note ai noi del passato
Se state per avviare qualcosa di questa forma, ecco cosa diremmo al team che ha iniziato diciotto mesi fa:
- Mettete a budget la confezione, non il modello. Partite dal presupposto che il modello rappresenti il 15% dello sforzo e pianificate deliberatamente l'85% restante. I team che mancano le scadenze sono quelli che hanno messo a budget l'opposto.
- Scrivete prima il contratto sui dati. Prima di qualsiasi variabile. Farà emergere una fuga di dati nel vostro backtest e vi eviterà di consegnare un numero che non potete difendere.
- Rilasciate il monitoraggio prima dell'interfaccia. Non potete gestire ciò che non potete vedere, e una previsione errata che nessuno ha notato è la modalità di guasto che fa perdere contratti.
- Progettate l'override. Gli esseri umani sapranno sempre cose che il modello ignora. Date loro una leva autorizzata e imparatene, altrimenti aggireranno l'intero sistema con un foglio di calcolo.
- Rendete il modello responsabile sullo schermo. Mostrate il suo storico accanto alla sua previsione. La fiducia è tanto una decisione di interfaccia quanto una questione di matematica.
Il machine learning era la parte facile. Lo diciamo non per sminuire il modello — è davvero buono — ma per indicare dove risiede realmente la difficoltà. L'hype vende le tre settimane. I cinque mesi sono ciò per cui pagate davvero un team di ingegneria.

