Probabilistische Bedarfsprognose

Probabilistische Bedarfsprognose












Startseite » Ressourcen » Hier

Probabilistische Vorhersagen sind ein Muss bei der Bestandsoptimierung. So werden Bedarfsprognosen über Durchlaufzeiten integriert, wenn Prognosewerte mit dem Gesamtbedarf über die Durchlaufzeit übereinstimmen; im Gegensatz zur Perspektive der klassischen Prognosen, in denen Prognosen in regelmäßigen Abständen (gewöhnlicherweise täglich, wöchentlich oder monatlich) und unabhängig von den Durchlaufzeiten berechnet werden. Lokads Prognose-Engine bietet integrierte probabilistische Bedarfsprognosen, bei denen Durchlaufzeiten als Eingabedaten berücksichtigt werden. So werden von Lokads Prognose-Engine verschiedene Statistik-Muster, die in Geschäftsdaten häufig auftreten, wie etwa Saisonabhänggikeit, Trends oder Lebenszyklen von Produkte, nativ unterstützt. Auch Verzerrungen des Bedarfs, wie etwa Fehlbestände oder Aktionen werden berücksichtigt. Lokads Prognosen stellen die erwarteten Wahrscheinlichkeiten für den künftigen Bedarf jeder einzelnen Einheit dar. In diesem Abschnitt gehen wir auf die Syntax, die für Lokads Berechnung der integrierten Bedarfsprognose benutzt wird, ein.

Allgemeine Syntax

Der Prognose-Engine hat eine Funktion, die eigens probabilistischen Prognosen gewidmet ist. Die Syntax lautet, wie folgt:

Demand = forecast.demand(
  category: C1, C2, C3, C4
  hierarchy: H1, H2, H3, H4
  label: PlainText
  demandStartDate: LaunchDate
  demandEndDate: EndDate
  horizon: Leadtime
  offset: 0
  present: (max(Orders.Date) by 1) + 1
  demandDate: Orders.Date
  demandValue: Orders.Quantity
  // 'SO' für Fehlbestände
  censoredDemandDate: SO.StartDate, SO.EndDate
  inflatedDemandDate: TVAds.StartDate, TVAds.EndDate
  // 'Promos' für Aktionen
  promotionDate: Promos.StartDate, Promos.EndDate
  promotionDiscount: Pros.Discount
  promotionCategory: Promos.Type

Im Gegensatz zu den gewöhnlichen Funktionen, haben Aufruf-Funktionen benannte Argumente statt Positionsargumente. Diese benannten Argumente eignen sich für komplexe Funktionen viel besser, da sie den Quellcode viel leserlicher gestalten, auf Kosten einer eingeschränkteren Ausführlichkeit. Diese Argumente verhalten sich wie gewöhnliche Funktionsargumente, daher sind sie für Envision-Ausdrücke zulässig.

Die Funktion gibt einen Vektor Demand zurück, der dem Typ Distribution , Verteilung, entspricht (siehe auch Algebra der Verteilungen). Verteilungen sind ein erweiterter Datentyp, der Funktionen darstellt $p: \mathbb{Z} \to \mathbb{R}$. Genauer gesagt, gibt das Prognose-Engine Zufallsvariablen zurück, also Verteilungen, die positiv sind und eine Masse gleich 1 besitzen. In diesem Fall stellt $p(k)$ die Wahrscheinlichkeit des Bedarfs, das $k$ Einheiten zugeordnet ist, dar. Jedem Artikel, im Sinne von Envision, wird seine eigene Verteilung des Bedarfs zugeordnet.

Die gesamte forecast.demand-Syntax enthält viele Argumente, doch nur vier davon sind zwingend:

  • present: ein skalarer Datumswert
  • demandDate: ein Datumsvektor mit einer Artikel-Affinität
  • demandValue: ein Vektor aus Zahlen mit einer Artikel-Affinität
  • horizon: ein Verteilungsvektor

Der present-Wert stellt das Datum dar, das als erstes prognostiziert werden soll, wenn man davon ausgeht, dass die Daten bis zum vorherigen Tag vollständig vorliegen. In der Praxis schließen manche Geschäfte beispielsweise sonntags. Sollte also das früheste Datum, das im Dataset vorliegt, der Samstag sein, wäre es nicht ganz eindeutig, ob die Vorhersage am Sonntag oder am Montag starten sollte. In der veranschaulichenden Syntax weiter oben, benutzen wir max(Orders.Date) + 1, da wir davon ausgehen, dass Beobachtungen zu jedem Tag vorliegen und dass die Eingabedaten frisch vom vorherigen Tag sind.

Es wird erwartet, dass demandDate und demandValue zur selben Tabelle, in der eine Artikelaffinität, also [Id, *] in der Terminologie Envisions, eingetragen ist, gehören. Die Daten stellen den Zeitpunkt dar, an dem der Bedarf in der Vergangenheit beobachtet wurde. Der Wert stellt das Ausmaß des Bedarfs dar, der üblicherweise in Einheiten oder Stücken gezählt wird. Es werden keine Teilwerte für den Bedarf unterstützt. Diese Tabelle enthält die eigentliche Bedarfshistorie der Vorhersage des Prognose-Engines. Idealerweise sollte die Historie so lang wie möglich sein. In der Praxis sind die Vorteile von Daten über fünf Jahren eingeschränkt. Das Prognose-Engine kann sowohl mit kurzen als auch mit langen Bedarfshistorien arbeiten. Bei längeren Historien werden ältere Daten einfach statistisch irrelevant.

Das horizon stellt die probabilistischen Durchlaufzeiten dar, die bei der Prognose benutzt werden. Während die Durchlaufzeit bei der Berechnung der integrierten Bedarfsprognose als Eingabe behandelt wird, wird die Durchlaufzeit selbst auch prognostiziert. Das Prognose-Engine bietet die Möglichkeit, Durchlaufzeiten zu prognostizieren. Die Prognose der Durchlaufzeit ist aber von der eigentlichen Bedarfsprognose entkoppelt, da man so ad-hoc Änderungen an der Verteilung der Durchlaufzeiten vornehmen kann, bevor man sie im Prognose-Engine einspeist.

Abgesehen von diesen Pflichtargumenten kann die Genauigkeit der Prognosen durch weitere Daten deutlich gesteigert werden. In den folgenden Abschnitten gehen wir näher darauf ein.

Formale Definition

In diesem Abschnitt führen wir in Kürze die formale Definition der statistischen Operation, die vom Prognose-Engine bei der Berechnung der integrierten Bedarfsprognose durchgeführt wird.

Sei $y(t)$ die Bedarfsfunktion und $t$ die Zeit. Sei der integrierte Bedarf $D$, der der Zufallsvariable $\Lambda$ zugeordnet ist, die die Durchlaufzeiten darstellt, wie folgt definiert:

$$\text{D} : (y,\Lambda,t_0) \to \int_0^{\infty} \mathbf{P}[\Lambda=\lambda] \left( \int_{t_0}^{t_0+\lambda} y(t) dt \right) d\lambda$$ wobei $\mathbf{P}[\Lambda=\lambda]$ die Wahrscheinlichkeit darstellt, dass die Zufallsvariable der Durchlaufzeit, $\Lambda$, gleich $\lambda$ ist. Der Bedarf wird als integriert bezeichnet, weil es eine Integration über eine probabilistische Durchlaufzeit darstellt.

Wenn $t_0$ das aktuelle Datum darstellt, ist der Bedarf bekannt, da er bis zur Zeit $t_0$ beobachtet wird, doch danach ist er unbekannt. Das Ziel dieses Prognose-Engines ist, $\hat{D}(y, \Lambda)$ zu berechnen, eine probabilistische Schätzung dieses künftigen Bedarfs, das als Zufallsvariable ausgedrückt wird.

Kategorien, Hierarchie und Bezeichnung

Aus der Sicht des Prognose-Engines, spielen Kategorien, Hierarchie und Bezeichnungen im Plain-Text-Format eine ähnliche Rolle: sie helfen dem Prognose-Engine mit wenigen historischen Daten umzugehen.

Sie auch Prognosen mit Kategorien und einer Hierarchie.

Prognose neuer Produkte

Aus der Perspektive der Prognose ist ein neues Produkt ein Produkt, das noch nicht verkauft wurde. Dies stellt eine besondere Herausforderung für die Prognose dar, da diesem Produkt, per Definition, keine historischen Daten zugeordnet sind. Unser Prognose-Engine unterstützt die Prognose neuer Produkte über das demandStartDate-Argument. Wenn historische Startdaten bekannt sind, wird es empfohlen, diese Information in den Prognose-Engine einzuspeisen, da es zur Genauigkeit der Prognose sowohl von neuen, als auch von alten Produkte beiträgt.

Das demandStartDate-Argument erwartet ein Datum für jeden Artikel. Dieses Datum soll den ersten Tag darstellen, in dem der Bedarf nach diesem Artikel eintritt. Das Datum liegt in der Vergangenheit für Artikel, die bereits verkauft wurden und in der Zukunft, für Artikel, die noch nicht eingeführt wurden.

Außerdem bietet das demandStartDate-Argument zwei klare Vorteile. Zum einen, logischerweise, die Prognose neuer Artikel. In diesem Fall, ist es auch wichtig, das offset-Argument heranzuführen. Wenn das Offset auf Null gehalten wird - seinem Standardwert -, kann sich der Zeitraum der Prognose nicht mit dem aktiven Zeitraum des Artikels überschneiden.

Beispiel. Heute ist der 1. Juli. Der Prognosehorizont ist eine Delta-Distribution auf 7 Tagen, d.h. eine konstante Durchlaufzeit von 7 Tagen. Das Produkt A wird am 15. Juli eingeführt. Wird die Prognose heute erstellt, muss die Prognoseverteilung für Produkt A eine Delta-Distribution auf null sein, da der Horizont vor dem Startdatum von Produkt A endet. Um die erste Woche des Bedarfs nach Produkt A zu berechnen, muss das Offset für Produkt A auf 14 Tage festgelegt werden.

Der zweite Vorteil der Verwendung des demandStartDate-Arguments ist die Erhöhung der Genauigkeit für alle Artikel, nicht nur für die noch nicht eingeführten. So ist es nicht dasselbe die erste bei Startdatum verkaufte Einheit zu beobachten, als die erste verkaufte Einheit sechs Monate nach Einführung zu beobachten. Während der erste Teil mehr auf regelmäßige künftige Verkäufe deutet, deutet letzterer auf einen beschränkten Bedarf einer Handvoll Einheiten im Jahr. Der Prognose-Engine nutzt demandStartDate, um der Bedarfsprognose für alle Artikel den Feinschliff zu geben.

Zensierter und überhöhter Bedarf

Das Ziel ist die Prognose des Bedarfs. Doch oft stellen historische Daten lediglich einen ungefähren tatsächlichen Bedarf an, wodurch (absichtlich oder nicht) Verzerrungen entstehen. Zum Beispiel können historische Daten durch den Absatz dargestellt werden. Doch im Falle von Fehlbeständen, geht das Absatzvolumen zurück, während der eigentliche Bedarf evtl. gleich beliebt. Lokads Prognose-Engine wurde nativ für solche Verzerrungen entwickelt und genau dies ist auch das Ziel der censoredDemandDate- und inflatedDemandDate-Argumente. Beide Argumente erwarten einen Datumsvektor mit Artikelaffinität, d.h. (Id, Date) in Envision-Terminologie.

Wird ein Datum für einen bestimmten Artikel über das censoredDemandDate Argument als censored (zensiert) markiert, geht der Prognose-Engine davon aus, dass der Bedarf höher oder gleich dem beobachteten Wert ist. Der Engine schätzt nicht, wie hoch der Bedarf für diesen bestimmten Tag gewesen wäre, da uns dieser Wert nie bekannt sein kann. Doch durch die Erkennung dieses systematischen Fehlers, kann der Engine eine ganze Reihe von Optimierungsklassen nutzen, die eigens für diesen Fall erstellt wurden. In der Praxis tritt zensierter Bedarf hauptsächlich bei Fehlbeständen auf, die durch Absatzdaten beobachtet werden, die keine Information über die unerfüllten Erwartungen derer, die ihre Produkte nicht finden, bietet.

Ähnlich hierzu kann der Bedarf auch überhöht werden. Das inflatedDemandDate-Argument bietet die Möglichkeit auf Daten zu weisen, für die der Bedarf als niedriger oder gleich dem beobachteten Bedarf gelten sollte. Hierbei muss wieder daran erinnert werden, dass der tatsächliche Bedarf unbekannt bleibt. Doch alleine das Aufzeigen dieses systematischen Fehlers ist für das Prognose-Engine schon hilfreich. In der Praxis ist der Bedarf überhöht, wenn nicht wiederkehrende Steigerungen auf dem Markt eintreten: Zum Beispiel kann der unerwartete Sieg einer lokalen Sportmannschaft bei einem landesweiten Turnier einige Tage lang einen äußerst positiven Einfluss auf den Absatz von lokalen Supermärkten haben.

Die beiden Argumente inflatedDemandDate und censoredDemandDate Lassen einen oder zwei Vektoren als Eingabe zu. Werden zwei Vektoren bereitgestellt, werden die Paare (start, end) als inklusive Segmente behandelt, wobei das erste Datum den Anfang des Segments und das zweite Datum das Ende des Segments darstellt. Wird nur ein Vektor bereitgestellt, geht man davon aus, dass die Segmente die Dauer eines Tages haben; die Daten kennzeichnen die genauen Tage, die als überhöht oder zensiert gelten sollen.

Sollte die Zensur oder die Erhöhung des Bedarfs periodisch sein - jährlich, wöchentlich, etc. - muss der Bedarf nicht als zensiert oder erhöht markiert werden, da der Prognose-Engine solche Muster automatisch erkennt und als solche behandelt.

Prognose von Aktionen

Der Prognose-Engine bietet eine native Unterstützung für Aktionen. Dabei ist die Einführung von Daten über Aktionen optional. Doch, wenn Aktionsdatenvorliegen, wird erwartet, dass diese sowohl in der Vergangenheit, als auch in der Zukunft angegeben werden. Zuletzt kann auch noch das Argument promotionDate alleine angegeben werden. Das Argument promotionDate wird mit demselben Muster wie censoredDemandDate benutzt: Wenn ein einziger Datumsvektor angegeben wird, wird davon ausgegangen, dass der Aktionszeitraum einen Tag beträgt; wenn zwei Daten angegeben werden, stellt der erste Vektor das Anfangsdatum (einschließlich), während das zweite das Enddatum (einschließlich) darstellt.

Das promotionDiscount-Argument ist optional und kann angegeben werden, um den Prognose-Engine einen besseren Einblick über die Intensität einer bestimmten Aktion zu geben. Hier wird als Argument ein Zahlenvektor erwartet und der Prognose-Engine behandelt diese Daten als Ordinalwerte: umso höher der Nachlass, desto höher der erwartete Einfluss der Aktion. In der Praxis berechnet der Prognose-Engine den erwarteten Anstieg der Nachfrage auf Grundlage der Anstiege, die in vergangenen Aktionen beobachtet wurden. Das promotionCategory-Argument ist auch optional und kann zu Klassifizierung der Aktionen angegeben werden. Wenn dieser vorhanden ist, wird dieses Argument vom Prognose-Engine genutzt, um Ähnlichkeiten zwischen Aktionen zu testen und festzustellen, ob bei verschiedenen Aktionen derselben Kategorie ähnliche Anstiege der Nachfrage entstehen. Dieses Argument ist vom Prinzip her ähnlich zum category-Argument, außer, dass es für Aktionen, statt für Artikel, benutzt wird.

Warnung. Aktionen sind sogar mit hervorragenden Historien besonders schwierig zu prognostizieren. Lokads Erfahrung hat gezeigt, dass die meisten Unternehmen über keine hochgenaue einsetzbare Daten bzgl. Aktionen verfügen. Solche Daten können mit Sorgfalt in späteren Phasen eines Projekts vorbereitet werden. Als Faustregel gilt, dass das Sammeln von ausreichend qualitativen Daten zu Aktionen, die die Genauigkeit einer Prognose verbessern, mit deutlichem Aufwand verbunden ist. Die Eingabe von etwaigen Daten zu Aktionen in den Prognose-Engine mindert die Genauigkeit der Ergebnisse.

Wenn Daten zu den Aktionen eingegeben werden, sollten die Datumsangaben der Aktionszeiträume nicht über das Argument inflatedDemandDate markiert werden. Die Markierung eines Datums über beide Argumente promotionDate und inflatedDemandDate hat eine subtile Semantik: es deutet an, dass der Anstieg aufgrund der Aktion über ein vernünftig von einer Aktion zu erwartendem Maß erhöht wurde und die Aktion selbst würde als verzerrt gelten.