Teilen über


Entwickeln, Auswerten und Bewerten eines Vorhersagemodells für Supermarktumsätze

Dieses Lernprogramm zeigt ein End-to-End-Beispiel für einen Synapse Data Science-Workflow in Microsoft Fabric. Das Szenario erstellt ein Prognosemodell, das historische Verkaufsdaten verwendet, um Produktkategorienverkäufe in einem Superstore vorherzusagen.

Die Prognose ist eine entscheidende Ressource im Umsatz. Sie kombiniert historische Daten und Prädiktive Methoden, um Erkenntnisse über zukünftige Trends zu liefern. Prognose kann vergangene Verkäufe analysieren, um Muster zu identifizieren. Es kann auch von Verbraucherverhalten lernen, um Bestands-, Produktions- und Marketingstrategien zu optimieren. Dieser proaktive Ansatz verbessert die Anpassungsfähigkeit, Reaktionsfähigkeit und die gesamte Geschäftsleistung auf einem dynamischen Markt.

In diesem Lernprogramm werden die folgenden Schritte behandelt:

  • Laden der Daten
  • Verwenden sie explorative Datenanalyse, um die Daten zu verstehen und zu verarbeiten.
  • Trainieren eines Machine Learning-Modells mit einem Open-Source-Softwarepaket
  • Nachverfolgen von Experimenten mit MLflow und der Fabric-Autoprotokollierungsfunktion
  • Speichern des endgültigen Machine Learning-Modells und Erstellen von Vorhersagen
  • Anzeigen der Modellleistung mit Power BI-Visualisierungen

Voraussetzungen

Durchführung in einem Notebook

Um in einem Notizbuch mitzuarbeiten, haben Sie folgende Optionen:

  • Öffnen und Ausführen des integrierten Notizbuchs in der Synapse Data Science-Erfahrung
  • Hochladen Ihres Notizbuchs von GitHub in die Synapse Data Science-Erfahrung

Öffnen des integrierten Notizbuchs

Das Beispiel-Notizbuch Umsatzprognose begleitet dieses Lernprogramm.

  1. Um das Beispielnotizbuch für dieses Lernprogramm zu öffnen, befolgen Sie die Anweisungen in Vorbereiten Ihres Systems für Data Science-Lernprogramme.

  2. Fügen Sie ein Lakehouse an das Notebook an, bevor Sie mit der Ausführung von Code beginnen.

Importieren des Notizbuchs aus GitHub

Das Notebook AIsample - Superstore Forecast.ipynb ist diesem Tutorial beigefügt.

Schritt 1: Laden der Daten

Der Datensatz umfasst 9.995 Einträge von Verkäufen verschiedener Produkte. Sie enthält auch 21 Attribute. Das Notizbuch verwendet eine Datei mit dem Namen Superstore.xlsx. Diese Datei weist diese Tabellenstruktur auf:

Zeilen-ID Auftrags-ID Bestelldatum Lieferdatum Versandmodus Kunden-ID Kundenname Segment Land Stadt Staat Postleitzahl Region Produkt-ID Kategorie Unterkategorie Produktname Umsatz Menge Rabatt Gewinn
4 US-2015-108966 2015-10-11 2015-10-18 Standardklasse SO-20335 Sean O'Donnell Verbraucher USA Fort Lauderdale Florida 33311 Süden FUR-TA-10000577 Möbel Tabellen Bretford CR4500 Series Slim Rechteckiger Tisch 957,5775 5 0.45 -383.0310
11 CA-2014-115812 2014-06-09 2014-06-09 Standardklasse Standardklasse Brosina Hoffman Verbraucher USA Los Angeles Kalifornien 90032 West FUR-TA-10001539 Möbel Tabellen Rechteckige Konferenztische von Chromcraft 1706.184 9 0.2 85.3092
31 US-2015-150630 2015-09-17 2015-09-21 Standardklasse TB-21520 Tracy Blumstein Verbraucher USA Philadelphia Pennsylvania 19140 Osten OFF-EN-10001509 Büroartikel Briefumschläge Poly-String-Verschlusskuverts 3,264 2 0.2 1.1016

Der folgende Codeausschnitt definiert bestimmte Parameter, sodass Sie dieses Notizbuch mit verschiedenen Datasets verwenden können:

IS_CUSTOM_DATA = False  # If TRUE, the dataset has to be uploaded manually

IS_SAMPLE = False  # If TRUE, use only rows of data for training; otherwise, use all data
SAMPLE_ROWS = 5000  # If IS_SAMPLE is True, use only this number of rows for training

DATA_ROOT = "/lakehouse/default"
DATA_FOLDER = "Files/salesforecast"  # Folder with data files
DATA_FILE = "Superstore.xlsx"  # Data file name

EXPERIMENT_NAME = "aisample-superstore-forecast"  # MLflow experiment name

Laden Sie das Dataset herunter und laden Sie es in das Seehaus hoch.

Der folgende Codeausschnitt lädt eine öffentlich verfügbare Version des Datasets herunter und speichert dieses Dataset dann in einem Fabric Lakehouse:

Wichtig

Sie müssen dem Notizbuch ein Seehaus hinzufügen , bevor Sie es ausführen. Andernfalls wird eine Fehlermeldung angezeigt.

import os, requests
if not IS_CUSTOM_DATA:
    # Download data files into the lakehouse if they're not already there
    remote_url = "https://synapseaisolutionsa.z13.web.core.windows.net/data/Forecast_Superstore_Sales"
    file_list = ["Superstore.xlsx"]
    download_path = "/lakehouse/default/Files/salesforecast/raw"

    if not os.path.exists("/lakehouse/default"):
        raise FileNotFoundError(
            "Default lakehouse not found, please add a lakehouse and restart the session."
        )
    os.makedirs(download_path, exist_ok=True)
    for fname in file_list:
        if not os.path.exists(f"{download_path}/{fname}"):
            r = requests.get(f"{remote_url}/{fname}", timeout=30)
            with open(f"{download_path}/{fname}", "wb") as f:
                f.write(r.content)
    print("Downloaded demo data files into lakehouse.")

Einrichten der MLflow-Experimentnachverfolgung

Microsoft Fabric erfasst automatisch die Eingabeparameterwerte und Ausgabemetriken eines Machine Learning-Modells, während Sie es trainieren. Dadurch werden die Automatischprotokollierungsfunktionen von MLflow erweitert. Die Informationen werden dann am Arbeitsbereich protokolliert, wo Sie mit den MLflow-APIs oder dem entsprechenden Experiment im Arbeitsbereich darauf zugreifen und visualisieren können. Weitere Informationen über Autologging finden Sie in der Ressource Autologging in Microsoft Fabric.

So deaktivieren Sie das automatische Logging von Microsoft Fabric in einer Notizbuchsitzung, indem Sie mlflow.autolog() aufrufen und disable=True festlegen, wie im folgenden Codeausschnitt dargestellt:

# Set up MLflow for experiment tracking
import mlflow

mlflow.set_experiment(EXPERIMENT_NAME)
mlflow.autolog(disable=True)  # Turn off MLflow autologging

Lesen von Rohdaten aus dem Lakehouse

Der folgende Codeausschnitt liest Rohdaten aus dem Abschnitt Dateien des Lakehouse. Außerdem werden weitere Spalten für verschiedene Datumsteile hinzugefügt. Dieselben Informationen erstellen eine partitionierte Delta-Tabelle. Da die Rohdaten als Excel-Datei gespeichert werden, müssen Sie pandas verwenden, um sie zu lesen.

import pandas as pd
df = pd.read_excel("/lakehouse/default/Files/salesforecast/raw/Superstore.xlsx")

Schritt 2: Durchführen einer explorativen Datenanalyse

Importieren von Bibliotheken

Importieren Sie die erforderlichen Bibliotheken, bevor Sie die Analyse starten:

# Importing required libraries
import warnings
import itertools
import numpy as np
import matplotlib.pyplot as plt
warnings.filterwarnings("ignore")
plt.style.use('fivethirtyeight')
import pandas as pd
import statsmodels.api as sm
import matplotlib
matplotlib.rcParams['axes.labelsize'] = 14
matplotlib.rcParams['xtick.labelsize'] = 12
matplotlib.rcParams['ytick.labelsize'] = 12
matplotlib.rcParams['text.color'] = 'k'
from sklearn.metrics import mean_squared_error,mean_absolute_percentage_error

Anzeigen der Rohdaten

Um das Dataset selbst besser zu verstehen, überprüfen Sie manuell eine Teilmenge der Daten. Verwenden Sie die display Funktion, um den DataFrame zu drucken. Die Chart Ansichten können ganz einfach Teilmengen des Datasets visualisieren:

display(df)

In diesem Tutorial wird ein Notizbuch behandelt, das sich hauptsächlich auf Furniture Kategorien-Verkaufsprognosen konzentriert. Dieser Ansatz beschleunigt die Berechnung und zeigt die Leistung des Modells an. Dieses Notizbuch verwendet jedoch anpassungsfähige Techniken. Sie können diese Techniken erweitern, um den Umsatz anderer Produktkategorien vorherzusagen. Der folgende Codeausschnitt wählt als Produktkategorie aus Furniture :

# Select "Furniture" as the product category
furniture = df.loc[df['Category'] == 'Furniture']
print(furniture['Order Date'].min(), furniture['Order Date'].max())

Vorverarbeitung der Daten

Reale Geschäftsszenarien müssen häufig Umsätze in drei unterschiedlichen Kategorien vorhersagen:

  • Bestimmte Produktkategorie
  • Bestimmte Kundenkategorie
  • Spezifische Kombination aus Produktkategorie und Kundenkategorie

Der folgende Codeausschnitt legt unnötige Spalten ab, um die Daten vorab zu verarbeiten. Einige der Spalten (Row ID, ,Order ID, und Customer ID) sind nicht erforderlich, Customer Nameda sie keine Relevanz haben. Wir möchten den Gesamtumsatz für eine bestimmte Produktkategorie (Furniture) über das Bundesland und die Region hinweg prognostizieren. Daher können wir die Spalten State, Region, Country, City und Postal Code ablegen. Um den Umsatz für einen bestimmten Standort oder eine bestimmte Kategorie zu prognostizieren, müssen wir möglicherweise den Vorverarbeitungsschritt entsprechend anpassen.

# Data preprocessing
cols = ['Row ID', 'Order ID', 'Ship Date', 'Ship Mode', 'Customer ID', 'Customer Name', 
'Segment', 'Country', 'City', 'State', 'Postal Code', 'Region', 'Product ID', 'Category', 
'Sub-Category', 'Product Name', 'Quantity', 'Discount', 'Profit']
# Drop unnecessary columns
furniture.drop(cols, axis=1, inplace=True)
furniture = furniture.sort_values('Order Date')
furniture.isnull().sum()

Der Datensatz ist auf täglicher Basis strukturiert. Wir müssen die Order Date Spalte neu abtasten, da wir ein Modell entwickeln möchten, um den Umsatz monatlich zu prognostizieren.

Gruppieren Sie zunächst die Kategorie Furniture nach Order Date. Berechnen Sie als Nächstes die Summe der Sales Spalte für jede Gruppe, um den Gesamtumsatz für jeden eindeutigen Order Date Wert zu ermitteln. Resampeln Sie die Sales-Spalte mit der MS-Frequenz, um die Daten monatlich zu aggregieren. Berechnen Sie schließlich den mittleren Verkaufswert für jeden Monat. Der folgende Codeausschnitt zeigt die folgenden Schritte:

# Data preparation
furniture = furniture.groupby('Order Date')['Sales'].sum().reset_index()
furniture = furniture.set_index('Order Date')
furniture.index
y = furniture['Sales'].resample('MS').mean()
y = y.reset_index()
y['Order Date'] = pd.to_datetime(y['Order Date'])
y['Order Date'] = [i+pd.DateOffset(months=67) for i in y['Order Date']]
y = y.set_index(['Order Date'])
maximim_date = y.reset_index()['Order Date'].max()

Zeigen Sie im folgenden Codeausschnitt die Auswirkungen von Order Date auf Sales innerhalb der Furniture-Kategorie an:

# Impact of order date on the sales
y.plot(figsize=(12, 3))
plt.show()

Vor einer statistischen Analyse müssen Sie das statsmodels Python-Modul importieren. Dieses Modul bietet Klassen und Funktionen, um viele statistische Modelle zu schätzen. Außerdem werden Klassen und Funktionen zur Durchführung statistischer Tests und statistischer Datensuche bereitgestellt. Der folgende Codeausschnitt zeigt diesen Schritt:

import statsmodels.api as sm

Durchführen einer statistischen Analyse

Eine Zeitreihe verfolgt diese Datenelemente in festgelegten Intervallen nach, um die Variation dieser Elemente im Zeitreihenmuster zu bestimmen:

  • Ebene: Die grundlegende Komponente, die den Mittelwert für einen bestimmten Zeitraum darstellt

  • Trend-: Beschreibt, ob die Zeitreihe im Laufe der Zeit abnimmt, konstant bleibt oder zunimmt.

  • Saisonalität: Beschreibt das periodische Signal in der Zeitreihe und sucht nach zyklischen Vorkommen, die sich auf die zunehmenden oder abnehmenden Zeitreihenmuster auswirken

  • Rauschen/Restwert: Bezieht sich auf die zufälligen Schwankungen und Variabilität in den Zeitreihendaten, die das Modell nicht erklären kann.

Der folgende Codeausschnitt zeigt diese Elemente für Ihr Dataset nach der Vorverarbeitung:

# Decompose the time series into its components by using statsmodels
result = sm.tsa.seasonal_decompose(y, model='additive')

# Labels and corresponding data for plotting
components = [('Seasonality', result.seasonal),
              ('Trend', result.trend),
              ('Residual', result.resid),
              ('Observed Data', y)]

# Create subplots in a grid
fig, axes = plt.subplots(nrows=4, ncols=1, figsize=(12, 7))
plt.subplots_adjust(hspace=0.8)  # Adjust vertical space
axes = axes.ravel()

# Plot the components
for ax, (label, data) in zip(axes, components):
    ax.plot(data, label=label, color='blue' if label != 'Observed Data' else 'purple')
    ax.set_xlabel('Time')
    ax.set_ylabel(label)
    ax.set_xlabel('Time', fontsize=10)
    ax.set_ylabel(label, fontsize=10)
    ax.legend(fontsize=10)

plt.show()

Die Plots beschreiben die Saisonalität, Trends und Lärm in den Prognosedaten. Sie können die zugrunde liegenden Muster erfassen und Modelle entwickeln, die genaue Vorhersagen machen, die Resilienz gegen zufällige Schwankungen aufweisen.

Schritt 3: Trainieren und Nachverfolgen des Modells

Nachdem Sie nun die Daten verfügbar haben, definieren Sie das Prognosemodell. Wenden Sie in diesem Notizbuch den saisonalen autoregressiven integrierten gleitenden Durchschnitt mit exogenen Faktoren (SARIMAX)-Prognosemodell an. SARIMAX kombiniert autoregressive (AR) und gleitende Mittelwerte (MA)-Komponenten, saisonale Unterschiede und externe Vorhersager, um genaue und flexible Prognosen für Zeitreihendaten zu erstellen.

Außerdem verwenden Sie MLflow und Fabric für das Autologging, um die Experimente zu protokollieren. Laden Sie hier die Delta-Tabelle aus dem Lakehouse. Sie können andere Delta-Tabellen verwenden, die das Seehaus als Quelle betrachten. Der folgende Codeausschnitt importiert die erforderlichen Bibliotheken:

# Import required libraries for model evaluation
from sklearn.metrics import mean_squared_error, mean_absolute_percentage_error

Optimieren von Hyperparametern

SARIMAX berechnet die Parameter, die im regulären, autoregressiven integrierten gleitenden Mittelwert (ARIMA)-Modusp (, d, q) beteiligt sind, und fügt die Saisonalitätsparameter (P, D, Q, s) hinzu. Diese SARIMAX-Modellargumente sind Ordnung (p, d, q) bzw. saisonale Ordnung (P, D, Q, s). Um das Modell zu trainieren, müssen wir daher zunächst sieben Parameter optimieren.

Die Bestellparameter:

  • p: Die Reihenfolge der AR-Komponente, die die Anzahl der letzten Beobachtungen in der Zeitreihe darstellt, die verwendet wird, um den aktuellen Wert vorherzusagen.

    In der Regel sollte dieser Parameter einen nicht negativen ganzzahligen Wert aufweisen. Allgemeine Werte befinden sich im Bereich von 0 bis 3. Je nach den spezifischen Datenmerkmalen sind jedoch höhere Werte möglich. Ein höherer p Wert gibt einen längeren Speicher vergangener Werte im Modell an.

  • d: Die Unterschiedlichkeitsreihenfolge, die die Anzahl der Male darstellt, mit denen die Zeitreihe differenziert werden muss, um die Stationarität zu erreichen.

    Dieser Parameter sollte einen nicht negativen ganzzahligen Wert aufweisen. Allgemeine Werte befinden sich im Bereich von 0 bis 2. Ein d Wert von 0 bedeutet, dass die Zeitreihe bereits stationär ist. Größere Werte deuten darauf hin, dass die Anzahl der unterschiedlichen Vorgänge, die erforderlich sind, um sie stationär zu machen, höher ist.

  • q: Die Reihenfolge der MA-Komponente. Dieser Parameter stellt die Anzahl vergangener Fehlerterme des weißen Rauschens dar, die zur Vorhersage des aktuellen Wertes verwendet werden.

    Dieser Parameter sollte einen nicht negativen ganzzahligen Wert aufweisen. Allgemeine Werte befinden sich im Bereich von 0 bis 3, aber bestimmte Zeitreihen erfordern möglicherweise höhere Werte. Ein höherer q Wert gibt eine stärkere Abhängigkeit von früheren Fehlerbegriffen an, um Vorhersagen zu treffen.

Die Saisonbestellparameter

  • P: Die saisonbedingte Reihenfolge der AR-Komponente, ähnlich dem Parameter p, aber die die Saisonkomponente abdeckt.
  • D: Die saisonale Differenzierung, ähnlich wie der d-Parameter, betrifft jedoch den saisonalen Teil.
  • Q: Die saisonbedingte Reihenfolge der MA-Komponente, ähnlich wie der q Parameter, aber die Saisonkomponente abdecken
  • s: Die Anzahl der Zeitschritte pro Saisonzyklus (z. B. 12 für monatliche Daten mit jährlicher Saisonalität)
# Hyperparameter tuning
p = d = q = range(0, 2)
pdq = list(itertools.product(p, d, q))
seasonal_pdq = [(x[0], x[1], x[2], 12) for x in list(itertools.product(p, d, q))]
print('Examples of parameter combinations for Seasonal ARIMA...')
print('SARIMAX: {} x {}'.format(pdq[1], seasonal_pdq[1]))
print('SARIMAX: {} x {}'.format(pdq[1], seasonal_pdq[2]))
print('SARIMAX: {} x {}'.format(pdq[2], seasonal_pdq[3]))
print('SARIMAX: {} x {}'.format(pdq[2], seasonal_pdq[4]))

SARIMAX hat andere Parameter:

  • enforce_stationarity: Ob das Modell die Stationarität der Zeitreihendaten erzwingen soll, bevor das SARIMAX-Modell angepasst wird.

    Ein enforce_stationarity Wert von True (Standard) gibt an, dass das SARIMAX-Modell die Stationarität für die Daten der Zeitreihe erzwingen soll. Vor der Anpassung des Modells wendet das SARIMAX-Modell dann automatisch die Differenzierung auf die Daten an, um sie stationär zu machen, wie die Ordnungen d und D vorgeben. Dies ist eine gängige Praxis, da viele Zeitreihenmodelle, einschließlich SARIMAX, davon ausgehen, dass stationäre Daten existieren.

    Bei einer nicht stationären Zeitreihe (z. B. einer Serie, die Trends oder Saisonalitäten zeigt), empfiehlt es sich, enforce_stationarity auf True festzulegen und dem SARIMAX-Modell die Differenzierung zu überlassen, um die Stationarität zu erreichen. Legen Sie für eine stationäre Zeitreihe (z. B. eine ohne Trends oder Saisonalität) enforce_stationarity auf False fest, um unnötige Unterschiede zu vermeiden.

  • enforce_invertibility: Steuert, ob das Modell während des Optimierungsprozesses die Invertierbarkeit für die geschätzten Parameter erzwingen soll.

    Ein enforce_invertibility Wert von True (Der Standardwert) gibt an, dass das SARIMAX-Modell die Invertierbarkeit für die geschätzten Parameter erzwingen soll. Die Invertierbarkeit stellt sicher, dass ein gut definiertes Modell und dass die geschätzten AR- und MA-Koeffizienten innerhalb des Bereichs der Stationarität landen.

    Die Invertierbarkeitserzwingung trägt dazu bei, dass das SARIMAX-Modell den theoretischen Anforderungen für ein stabiles Zeitreihenmodell entspricht. Es hilft auch, Probleme mit der Modellschätzung und Stabilität zu verhindern.

Ein AR(1) Modell ist die Standardeinstellung. Dies bezieht sich auf (1, 0, 0). Es ist jedoch üblich, verschiedene Kombinationen der Bestellparameter und saisonalen Bestellparameter auszuprobieren und die Modellleistung für ein Dataset zu bewerten. Die entsprechenden Werte können von einer Zeitreihe zu einer anderen variieren.

Die Bestimmung der optimalen Werte umfasst häufig die Analyse der Autokorrelationsfunktion (ACF) und der partiellen Autokorrelationsfunktion (PACF) der Zeitreihendaten. Es umfasst auch häufig die Verwendung von Modellauswahlkriterien - z. B. das Akaike-Informationskriterium (AIC) oder das Bayesische Informationskriterium (BIC).

Optimieren Sie die Hyperparameter, wie im folgenden Codeausschnitt gezeigt:

# Tune the hyperparameters to determine the best model
for param in pdq:
    for param_seasonal in seasonal_pdq:
        try:
            mod = sm.tsa.statespace.SARIMAX(y,
                                            order=param,
                                            seasonal_order=param_seasonal,
                                            enforce_stationarity=False,
                                            enforce_invertibility=False)
            results = mod.fit(disp=False)
            print('ARIMA{}x{}12 - AIC:{}'.format(param, param_seasonal, results.aic))
        except:
            continue

Nach der Auswertung der vorherigen Ergebnisse können Sie die Werte sowohl für die Ordnungsparameter als auch für die saisonalen Ordnungsparameter bestimmen. Die Wahl ist order=(0, 1, 1) und seasonal_order=(0, 1, 1, 12), die die niedrigste AIC (z. B. 279,58) bieten. Verwenden Sie diese Werte, um das Modell zu trainieren. Der folgende Codeausschnitt zeigt diesen Schritt:

Trainieren des Modells

# Model training 
mod = sm.tsa.statespace.SARIMAX(y,
                                order=(0, 1, 1),
                                seasonal_order=(0, 1, 1, 12),
                                enforce_stationarity=False,
                                enforce_invertibility=False)
results = mod.fit(disp=False)
print(results.summary().tables[1])

Dieser Code visualisiert eine Zeitreihenprognose für Möbelumsatzdaten. Die dargestellten Ergebnisse zeigen sowohl die beobachteten Daten als auch die 1-Schritt-Voraus-Prognose mit einem schattierten Bereich für konfidenzintervalle an. Die folgenden Codeausschnitte zeigen die Visualisierung:

# Plot the forecasting results
pred = results.get_prediction(start=maximim_date, end=maximim_date+pd.DateOffset(months=6), dynamic=False) # Forecast for the next 6 months (months=6)
pred_ci = pred.conf_int() # Extract the confidence intervals for the predictions
ax = y['2019':].plot(label='observed')
pred.predicted_mean.plot(ax=ax, label='One-step ahead forecast', alpha=.7, figsize=(12, 7))
ax.fill_between(pred_ci.index,
                pred_ci.iloc[:, 0],
                pred_ci.iloc[:, 1], color='k', alpha=.2)
ax.set_xlabel('Date')
ax.set_ylabel('Furniture Sales')
plt.legend()
plt.show()
# Validate the forecasted result
predictions = results.get_prediction(start=maximim_date-pd.DateOffset(months=6-1), dynamic=False)
# Forecast on the unseen future data
predictions_future = results.get_prediction(start=maximim_date+ pd.DateOffset(months=1),end=maximim_date+ pd.DateOffset(months=6),dynamic=False)

Der folgende Codeausschnitt verwendet predictions, um die Leistung des Modells zu bewerten, indem er sie mit den tatsächlichen Werten vergleicht. Der predictions_future Wert gibt die zukünftige Prognose an.

# Log the model and parameters
model_name = f"{EXPERIMENT_NAME}-Sarimax"
with mlflow.start_run(run_name="Sarimax") as run:
    mlflow.statsmodels.log_model(results,model_name,registered_model_name=model_name)
    mlflow.log_params({"order":(0,1,1),"seasonal_order":(0, 1, 1, 12),'enforce_stationarity':False,'enforce_invertibility':False})
    model_uri = f"runs:/{run.info.run_id}/{model_name}"
    print("Model saved in run %s" % run.info.run_id)
    print(f"Model URI: {model_uri}")
mlflow.end_run()
# Load the saved model
loaded_model = mlflow.statsmodels.load_model(model_uri)

Schritt 4: Bewertung des Modells und Speichern von Vorhersagen

Der folgende Codeausschnitt integriert die tatsächlichen Werte in die prognostizierten Werte, um einen Power BI-Bericht zu erstellen. Darüber hinaus speichert das System diese Ergebnisse in einer Tabelle im Lakehouse.

# Data preparation for Power BI visualization
Future = pd.DataFrame(predictions_future.predicted_mean).reset_index()
Future.columns = ['Date','Forecasted_Sales']
Future['Actual_Sales'] = np.NAN
Actual = pd.DataFrame(predictions.predicted_mean).reset_index()
Actual.columns = ['Date','Forecasted_Sales']
y_truth = y['2023-02-01':]
Actual['Actual_Sales'] = y_truth.values
final_data = pd.concat([Actual,Future])
# Calculate the mean absolute percentage error (MAPE) between 'Actual_Sales' and 'Forecasted_Sales' 
final_data['MAPE'] = mean_absolute_percentage_error(Actual['Actual_Sales'], Actual['Forecasted_Sales']) * 100
final_data['Category'] = "Furniture"
final_data[final_data['Actual_Sales'].isnull()]
input_df = y.reset_index()
input_df.rename(columns = {'Order Date':'Date','Sales':'Actual_Sales'}, inplace=True)
input_df['Category'] = 'Furniture'
input_df['MAPE'] = np.NAN
input_df['Forecasted_Sales'] = np.NAN
# Write back the results into the lakehouse
final_data_2 = pd.concat([input_df,final_data[final_data['Actual_Sales'].isnull()]])
table_name = "Demand_Forecast_New_1"
spark.createDataFrame(final_data_2).write.mode("overwrite").format("delta").save(f"Tables/{table_name}")
print(f"Spark DataFrame saved to delta table: {table_name}")

Schritt 5: Visualisieren in Power BI

Der Power BI-Bericht zeigt einen mittleren absoluten Prozentfehler (MAPE) von 16,58 an. Die MAPE-Metrik definiert die Genauigkeit einer Prognosemethode. Sie stellt die Genauigkeit der prognostizierten Mengen im Vergleich zu den tatsächlichen Mengen dar.

MAPE ist eine einfache Metrik. Eine 10% MAPE bedeutet, dass die durchschnittliche Abweichung zwischen den prognostizierten und tatsächlichen Werten 10%beträgt, unabhängig davon, ob die Abweichung positiv oder negativ war. Die Standards wünschenswerter MAPE-Werte variieren in verschiedenen Branchen.

Die hellblaue Linie in diesem Diagramm stellt die tatsächlichen Umsatzwerte dar. Die dunkelblaue Linie stellt die prognostizierten Umsatzwerte dar. Der Vergleich der tatsächlichen und prognostizierten Umsätze zeigt, dass das Modell in den ersten sechs Monaten 2023 den Umsatz für die Furniture Kategorie effektiv vorhersagt.

Screenshot eines Power BI-Berichts.

Basierend auf dieser Beobachtung können wir vertrauen in die Prognosefähigkeiten des Modells für den Gesamtumsatz in den letzten sechs Monaten 2023 und bis 2024. Dieses Vertrauen kann strategische Entscheidungen über die Bestandsverwaltung, die Beschaffung von Rohstoffen und andere geschäftsbezogene Überlegungen informieren.