Machine Learning · Prognose und Bestandsoptimierung · Lebensmitteleinzelhandel
Die Nachfrage hinter dem leeren Regal
Wenn ein Frischeprodukt ausverkauft ist, sagen die Verkaufszahlen nicht mehr die Wahrheit. Wir schätzen die Nachfrage hinter dem leeren Regal, mit einem Intervall, und machen daraus die Bestellung für morgen.
Überblick
FreshRetailNet-50K ist ein öffentlicher Datensatz mit Verkäufen von Frischware: 50.000 Produktzeitreihen aus 898 Filialen, mit stündlichen Verkäufen und einem stündlichen Kennzeichen, ob das Produkt vorrätig war. In den Daten ist das Produkt in 19,7 % der Verkaufsstunden nicht vorrätig, und an 44 % der Produkttage ist es mindestens einmal ausverkauft. In diesen Stunden verzeichnen die Daten fast keine Verkäufe. Eine Prognose, die auf erfassten Verkäufen trainiert ist, hält ein leeres Regal deshalb für eine ruhige Stunde, und ihre Prognosen fallen zu niedrig aus.
Wir schätzen die Nachfrage, die jeder Fehlbestand verdeckt, als Zahl mit einem 80-%-Intervall. Das Modell lernt nur aus Stunden, deren Antwort wir kennen. Wir nehmen einen Tag, der durchgehend vorrätig war, übertragen das Fehlbestandsmuster eines real ausverkauften Tages darauf, verbergen diese Stunden und lernen, sie zu rekonstruieren. Dabei nutzt das Modell den Rest dieses Tages, die eigene Historie des Produkts, den Rabatt, den Kalender, das Wetter und die Kategorie. In 167 Filialen, die es nie gesehen hatte, enthielt das Intervall in 80,0 % der Fälle den wahren Wert. Unsere erste Version schaffte das an tatsächlich ausverkauften Tagen nur in 71 % der Fälle, weil diese Tage nachfragestärker sind, als ihre Stunden mit Ware vermuten lassen. Das Training auf den vorrätigen Stunden ausverkaufter Tage brachte diesen Test wieder auf 79,5 %. Beide Tests verbergen Stunden, deren Verkäufe wir tatsächlich beobachtet haben. Die Nachfrage nach einem Ausverkauf lässt sich nie beobachten; ihr Intervall beruht daher auf einer Annahme: dass sie sich wie die Stunden verhält, die wir testen können. Über den gesamten Datensatz erhöht unsere zentrale Schätzung die erfassten Verkäufe um 17 %.
Anschließend machen probabilistische Prognosen aus der rekonstruierten Nachfrage Bestellungen. Getestet haben wir sie an der zurückgehaltenen Testwoche des Datensatzes. Eine Bestellstrategie bestellt dann jeden Abend die Menge bis zu einem Prognosequantil, abzüglich des Bestands, der noch verkauft werden kann. Der Bestand altert nach dem FIFO-Prinzip, und seine Haltbarkeit ist eine Annahme von 1, 2 oder 3 Tagen, die Sie einstellen. Ein simuliertes Replay der Testwoche zeigt Abschriften und entgangene Verkäufe im Vergleich zur Bestellung auf Basis erfasster Verkäufe. In diesem Replay kostet ein entgangener Verkauf doppelt so viel wie eine abgeschriebene Einheit, und die Nachfrage enthält unsere Schätzung. Die Bestellung auf Basis unserer Schätzung senkte dann die Gesamtkosten aus Abschriften und entgangenen Verkäufen um 4,6 %, 5,6 % und 10,9 % bei einer Haltbarkeit von 1, 2 und 3 Tagen. Hätten die Fehlbestände überhaupt keine Nachfrage verdeckt, lägen beide Strategien innerhalb von 1,3 % beieinander. Der Gewinn hängt außerdem davon ab, dass entgangene Verkäufe mehr kosten als Abschriften. Kostet ein entgangener Verkauf gleich viel wie eine abgeschriebene Einheit oder weniger und haben die Fehlbestände keine Nachfrage verdeckt, kostet die Bestellung auf Basis unserer Schätzung 1 bis 5 % mehr. Bei Kosten von 1 für einen entgangenen Verkauf schrumpft der Wert für 3 Tage von −10,9 % auf −0,2 %. Bei 2 oder 3 Tagen Haltbarkeit bestellen beide Strategien am oberen Ende unseres Prognosebereichs (P95); diese beiden Werte sind daher am unsichersten. Die Verkäufe sind in den skalierten Einheiten des Datensatzes angegeben. Jede rekonstruierte Zahl ist unsere Schätzung, nie eine Beobachtung. Das Regal im Film ist ein 3D-Rendering, das den Tag eines Produkts aus den Daten nachspielt.
Was wir entwickelt haben
- Rekonstruktion zensierter Nachfrage. LightGBM-Quantilmodelle von P10 bis P90, trainiert durch das Verbergen von Stunden, in denen Ware vorrätig war. Sie werden mit split-conformal-Prüfungen an separaten Filialen kalibriert und an 167 zurückgehaltenen Filialen validiert. Eine dieser Prüfungen verwendet nur real ausverkaufte Tage.
- Probabilistische Prognosen für die zurückgehaltene Woche, jeweils einen Tag im Voraus. Sie werden auf erfassten Verkäufen und auf rekonstruierter Nachfrage trainiert und mit CRPS, pinball loss, WAPE und Bias gegen einfache Baselines bewertet.
- Eine Bestellniveau-Strategie, die die Alterung verfolgt. Sie verkauft nach dem FIFO-Prinzip über eine angenommene Haltbarkeit von 1 bis 3 Tagen. Das Bestellquantil wird für jedes Kostenverhältnis an zwei Backtest-Wochen abgestimmt und dann für die zurückgehaltene Woche eingefroren.
- Ein simuliertes Replay, das mit einem leeren Regal beginnt. Es grenzt das Ergebnis zweifach ein: einmal mit einer Nachfrage, die unsere Schätzung enthält, und einmal nur mit erfassten Verkäufen.
- Ein interaktives Replay von 2.000 Zeitreihen, alle aus zurückgehaltenen Filialen. In Ihrem Browser können Sie Filiale und Produkt wählen, erfasste oder geschätzte Nachfrage anzeigen, die Kosten eines entgangenen Verkaufs gegenüber einer abgeschriebenen Einheit verschieben und die Haltbarkeit ändern. Die Strategie wird live neu abgestimmt und nachgespielt.
Tech-Stack
Python, pandas, NumPy, LightGBM (Quantilregression), split-conformal-Kalibrierung · three.js (physikalisch basiertes Rendering, akkumulierte Tiefenschärfe und weiche Schatten) · Vanilla-JavaScript für den Optimierer im Browser
Zahlen
Alle Zahlen stammen aus unseren eigenen Läufen auf FreshRetailNet-50K (Dingdong-Inc, CC BY 4.0). Die Verkäufe sind in den skalierten Einheiten des Datensatzes angegeben.
| Kennzahl | Wie wir sie ermittelt haben |
|---|---|
| 19,7 % der Verkaufsstunden ohne Bestand | Stündliche Bestandskennzeichen, 06:00–22:00 Uhr, über alle 50.000 Zeitreihen und 97 Tage. An 44,0 % der Produkttage war das Produkt mindestens einmal ausverkauft, an 4,0 % den ganzen Tag. |
| 80,0 % Intervallabdeckung (Ziel 80 %) | 444.393 Produkttage aus 167 zurückgehaltenen Filialen. Ein reales Fehlbestandsmuster wurde auf vorrätige Stunden übertragen, diese Stunden wurden verborgen, und wir prüften, ob die wahre Summe in unserem P10–P90-Intervall lag. |
| 79,5 % Abdeckung an real ausverkauften Tagen | 222.549 zurückgehaltene Tage, an denen die Ware um 12:00 Uhr oder später ausging. Wir verbargen die 3 vorrätigen Stunden, die 2 Stunden vor dem Fehlbestand enden. Ohne Training auf ausverkauften Tagen lag die Abdeckung bei 71,4 %, und die Schätzung war um 39 % zu niedrig. |
| 40 % Fehler in verborgenen Stunden (WAPE des P50) | Dieselben 444.393 Tage. Dieselben Stunden an kürzlichen vorrätigen Tagen ergeben 49 % Fehler. Die Hochrechnung der vorrätigen Stunden mit dem üblichen Stundenprofil ergibt 60 %. |
| +17 % durch Fehlbestände verdeckte Nachfrage | Summe unserer P50-Schätzungen über alle 2,1 Millionen Produkttage mit Fehlbestand, verglichen mit den gesamten erfassten Verkäufen. Eine Summe von Medianen unterschätzt die Gesamtmenge. Summiert man stattdessen die P10- und P90-Anteile je Tag, ergeben sich 8 % und 30 %. |
| 2,4 % niedrigerer CRPS in der zurückgehaltenen Woche | Prognose, trainiert auf rekonstruierter Nachfrage, gegenüber demselben Modell, trainiert auf erfassten Verkäufen: 0,192 vs. 0,197 (skalierter CRPS, niedriger ist besser). Bewertet an den 206.562 zurückgehaltenen Produkttagen, die vorrätig blieben und an denen erfasste Verkäufe der Nachfrage entsprechen. Eine Baseline aus empirischen Quantilen über 28 Tage erreicht 0,240. |
| 42 % vs. 56 % zu niedrige Prognosen an ausverkauften Tagen | Anteil der zurückgehaltenen ausverkauften Tage, an denen der Prognosemedian unter den tatsächlich erfassten Verkäufen liegt, die eine Untergrenze für die Nachfrage dieses Tages sind. Prognose auf rekonstruierter Nachfrage gegenüber Prognose auf erfassten Verkäufen. Diese Prüfung belohnt hohe Prognosen; lesen Sie sie daher zusammen mit dem Bias an vorrätigen Tagen: +3,1 % vs. −6,4 %. |
| −4,6 % / −5,6 % / −10,9 % Replay-Kosten bei einer Haltbarkeit von 1 / 2 / 3 Tagen | Kosten = (2 × entgangene Verkäufe + abgeschriebene Einheiten) je Nachfrageeinheit, über die zurückgehaltene Woche für alle 50.000 Zeitreihen, beginnend mit einem leeren Regal. Replay-Nachfrage = erfasste Verkäufe plus unsere P50-Schätzung für die Fehlbestandsstunden. Wir vergleichen die Bestellung auf Basis unserer Schätzung mit der Bestellung auf Basis erfasster Verkäufe. Das Bestellquantil jeder Strategie wurde an den zwei Wochen davor abgestimmt. Zieht man die verdeckte Nachfrage stattdessen aus unserem Intervall (200 Ziehungen), ergeben sich −4,0 % / −7,2 % / −12,6 %. |
| Innerhalb von 1,3 %, wenn nichts verdeckt war | Dasselbe Replay mit erfassten Verkäufen als einziger Nachfrage: +1,3 % / −0,3 % / +0,8 %. |
| −5 % bis +5 % bei Kosten eines entgangenen Verkaufs von 0,5 bis 1 abgeschriebenen Einheiten | Dasselbe Replay, andere Kostenverhältnisse. Mit unserer Schätzung als Nachfrage: −5,5 % bis −0,2 %. Nur mit erfassten Verkäufen: +0,8 % bis +5,4 %; die Bestellung auf Basis unserer Schätzung kostet also mehr, wenn nichts verdeckt war und entgangene Verkäufe billig sind. Bei 2 und 3 Tagen Haltbarkeit liegen beide abgestimmten Strategien an der P95-Obergrenze unseres Prognosebereichs. |
| 20,4 % vs. 23,0 % Abschriften bei 1 Tag Haltbarkeit | Replay wie oben. Die Bestellung auf Basis unserer Schätzung führt zu Abschriften von 20,4 % der Nachfrage und zu 7,2 % entgangenen Verkäufen. Die Bestellung auf Basis erfasster Verkäufe führt zu 23,0 % Abschriften und 6,7 % entgangenen Verkäufen. Bestellt man die gestrigen Verkäufe mal einem abgestimmten Faktor, kostet das 0,600 je Nachfrageeinheit, gegenüber 0,347 bei unserer Strategie. |
| 42 ms für Neuabstimmung und Replay im Browser | Median von 10 Läufen in Headless-Chromium auf unserem Laptop mit M1 Pro. Jeder Lauf stimmt 37 Bestellquantile × 2 Strategien an 14 Backtest-Tagen ab und spielt dann die 7-Tage-Woche nach, über 2.000 Zeitreihen. Auf Smartphones dauert es länger. |
Standbilder
Live ausprobieren
Eine interaktive Ansicht, die in Ihrem Browser läuft. Erst wenn Sie sie öffnen, wird etwas geladen.