Freigeben über


Trainieren und Auswerten eines Zeitreihenvorhersagemodells

In diesem Notebook erstellen wir ein Programm zur Vorhersage von Zeitreihendaten mit saisonalen Zyklen. Wir verwenden die Daten der Jahre 2003 bis 2015 aus dem DataSet NYC Property Sales, das vom NYC Department of Finance auf dem NYC Open Data Portal veröffentlicht wurde.

Voraussetzungen

Ein Notebook für das Tutorial

Sie können in einem Notebook eine von zwei Methoden befolgen:

  • Öffnen Sie das integrierte Notebook in der Synapse Data Science-Umgebung, und führen Sie es aus.
  • Laden Sie Ihr Notebook von GitHub in die Synapse Data Science-Umgebung hoch.

Öffnen des integrierten Notebooks

Das Notebook Zeitreihen ist diesem Tutorial als Beispiel beigefügt.

So öffnen Sie das integrierte Beispiel-Notebook für das Tutorial in der Synapse Data Science-Umgebung:

  1. Wechseln Sie zur Synapse Data Science-Startseite.

  2. Wählen Sie Beispiel verwenden aus.

  3. Wählen Sie das zugehörige Beispiel aus:

    • Wählen Sie es auf der Standardregisterkarte End-to-End-Workflows (Python) aus, wenn es sich bei dem Beispiel um ein Python-Tutorial handelt.
    • Wählen Sie es auf der Registerkarte End-to-End-Workflows (R) aus, wenn es sich bei dem Beispiel um ein R-Tutorial handelt.
    • Wählen Sie es auf der Registerkarte Schnelltutorials aus, wenn es sich bei dem Beispiel um ein Schnelltutorial handelt.
  4. Fügen Sie ein Lakehouse an das Notebook an, bevor Sie mit der Ausführung von Code beginnen.

Importieren des Notebooks von GitHub

AIsample – Time Series Forecasting.ipynb ist das Notebook, das dieses Tutorial begleitet.

Um das zugehörige Notebook für dieses Tutorial zu öffnen, befolgen Sie die Anweisungen unter Vorbereiten Ihres Systems für Data-Science-Tutorials zum Importieren des Notebooks in Ihren Arbeitsbereich.

Wenn Sie den Code lieber von dieser Seite kopieren und einfügen möchten, können Sie auch ein neues Notebook erstellen.

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

Schritt 1: Installieren von benutzerdefinierten Bibliotheken

Wenn Sie ein Machine Learning-Modell entwickeln oder Ad-hoc-Datenanalysen durchführen, müssen Sie u.U. schnell eine Bibliothek (wie z.B. prophet) für Ihre Apache Spark-Sitzung installieren. Um dies zu tun, haben Sie zwei Möglichkeiten.

  1. Sie können die Inline-Installationsfunktionen (z.B. %pip, %conda, usw.) verwenden, damit die neuen Bibliotheken sofort verwendet werden können. Mit dieser Installationsoption würden die Bibliotheken nur im aktuellen Notebook und nicht im Arbeitsbereich installiert.
# Use pip to install libraries
%pip install <library name>

# Use conda to install libraries
%conda install <library name>
  1. Alternativ können Sie eine Fabric-Umgebung erstellen, Bibliotheken aus öffentlichen Quellen installieren oder benutzerdefinierte Bibliotheken darauf hochladen, und dann kann Ihr Arbeitsbereichsadministrator die Umgebung als Standard für den Arbeitsbereich anfügen. Alle Bibliotheken in der Umgebung werden dann für die Verwendung in allen Notebooks und Spark-Auftragsdefinitionen im Arbeitsbereich verfügbar. Weitere Informationen zu Umgebungen finden Sie unter Erstellen, Konfigurieren und Verwenden einer Umgebung in Microsoft Fabric.

Für dieses Notebook verwenden Sie %pip install zum Installieren der prophet-Bibliothek. Der PySpark-Kernel wird nach %pip install neu gestartet. Dies bedeutet, dass Sie die Bibliothek installieren müssen, bevor Sie andere Zellen ausführen.

# Use pip to install Prophet
%pip install prophet

Schritt 2: Laden der Daten

Dataset

Dieses Notizbuch verwendet das DataSet "NYC Property Sales". Es deckt Daten von 2003 bis 2015 ab, die vom NYC Department of Finance im NYC Open Data Portal veröffentlicht wurden.

Im DataSet sind alle Gebäudeverkäufe auf dem Immobilienmarkt von New York City über einen Zeitraum von 13 Jahren erfasst. Die Definition für die Spalten der Tabelle finden Sie unter Glossary of Terms for Property Sales Files.

Bezirk Stadtteil building_class_category tax_class Block Grundstück Östlich building_class_at_present Adresse apartment_number zip_code residential_units commercial_units total_units land_square_feet gross_square_feet year_built tax_class_at_time_of_sale building_class_at_time_of_sale sale_price sale_date
Manhattan ALPHABET CITY 07 VERMIETUNGEN - ETAGENWOHNUNGEN 0,0 384,0 17.0 C4 225 EAST 2ND STREET 10009.0 10,0 0,0 10,0 2145.0 6670.0 1900.0 2.0 C4 275000.0 2007-06-19
Manhattan ALPHABET CITY 07 RENTALS - WALKUP APARTMENTS 2.0 405.0 12.0 C7 508 EAST 12TH STREET 10009.0 28,0 2.0 30.0 3872.0 15428.0 1930.0 2.0 C7 7794005.0 2007-05-21

Ziel ist es, ein Modell zu erstellen, das den monatlichen Gesamtumsatz basierend auf historischen Daten prognostiziert. Dazu verwenden Sie Prophet, eine open Source Prognosebibliothek, die von Facebook entwickelt wurde. Prophet basiert auf einem additiven Modell, in dem nichtlineare Trends mit täglichen, wöchentlichen und jährlichen Saisonalitäten und Feiertagseffekten angepasst werden. Prophet funktioniert am besten mit Zeitreihen-DataSets, die starke saisonale Effekte aufweisen und viele Saisons von historischen Daten umfassen. Außerdem kann Prophet fehlende Daten und Datenausreißer zuverlässig verarbeiten.

Prophet verwendet ein zersetzbares Zeitreihenmodell, das aus drei Komponenten besteht:

  • Trend: Prophet geht von einer stückweise konstanten Wachstumsrate mit automatischer Auswahl der Änderungspunkte aus
  • Saisonalität: Standardmäßig verwendet Prophet Fourier-Reihen zur Anpassung der wöchentlichen und jährlichen Saisonalität
  • Feiertage: Prophet benötigt alle vergangenen und zukünftigen Feiertage. Wenn ein Feiertag in Zukunft nicht wiederholt wird, wird Prophet ihn nicht in die Prognose aufnehmen.

In diesem Notebook werden die Daten auf monatlicher Basis zusammengeführt, so dass die Feiertage nicht berücksichtigt werden.

Lesen Sie das offizielle Dokument, um weitere Informationen zu den Prophet-Modellierungstechniken zu finden.

Herunterladen des DataSet und Hochladen in ein Lakehouse

Die Datenquelle besteht aus 15 .csv Dateien. Diese Dateien enthalten Aufzeichnungen über Immobilienverkäufe aus fünf New Yorker Stadtbezirken zwischen 2003 und 2015. Aus Gründen der Einfachheit enthält die nyc_property_sales.tar Datei alle diese .csv Dateien und komprimiert sie in eine Datei. Diese .tar Datei wird von einem öffentlich verfügbaren BLOB-Speicher gehostet.

Tipp

Mit den Parametern, die in dieser Codezelle angezeigt werden, können Sie dieses Notebook ganz einfach auf verschiedene DataSets anwenden.

URL = "https://synapseaisolutionsa.blob.core.windows.net/public/NYC_Property_Sales_Dataset/"
TAR_FILE_NAME = "nyc_property_sales.tar"
DATA_FOLDER = "Files/NYC_Property_Sales_Dataset"
TAR_FILE_PATH = f"/lakehouse/default/{DATA_FOLDER}/tar/"
CSV_FILE_PATH = f"/lakehouse/default/{DATA_FOLDER}/csv/"

EXPERIMENT_NAME = "aisample-timeseries" # MLflow experiment name

Dieser Code lädt eine öffentlich verfügbare Version des DataSets herunter und speichert dieses DataSet dann in einem Fabric Lakehouse.

Wichtig

Fügen Sie ein Lakehouse zum Notebook hinzu, bevor Sie ihn ausführen. Andernfalls kommt es zu einem Fehler.

import os

if not os.path.exists("/lakehouse/default"):
    # Add a lakehouse if the notebook has no default lakehouse
    # A new notebook will not link to any lakehouse by default
    raise FileNotFoundError(
        "Default lakehouse not found, please add a lakehouse for the notebook."
    )
else:
    # Verify whether or not the required files are already in the lakehouse, and if not, download and unzip
    if not os.path.exists(f"{TAR_FILE_PATH}{TAR_FILE_NAME}"):
        os.makedirs(TAR_FILE_PATH, exist_ok=True)
        os.system(f"wget {URL}{TAR_FILE_NAME} -O {TAR_FILE_PATH}{TAR_FILE_NAME}")

    os.makedirs(CSV_FILE_PATH, exist_ok=True)
    os.system(f"tar -zxvf {TAR_FILE_PATH}{TAR_FILE_NAME} -C {CSV_FILE_PATH}")

Starten Sie die Aufzeichnung der Laufzeit, die zum Ausführen dieses Notebooks benötigt wird.

# Record the notebook running time
import time

ts = time.time()

Einrichten der MLflow-Experimentnachverfolgung

Zur Erweiterung der MLflow-Protokollierungs-Funktionen erfasst das Autologging automatisch die Werte von Eingabeparametern und Ausgabemetriken eines Machine Learning-Modells während seines Trainings. Diese Informationen werden dann im Arbeitsbereich protokolliert, wo sie mithilfe der MLflow-APIs oder der entsprechenden Experimente im Arbeitsbereich angezeigt und visualisiert werden können. Besuchen Sie diese Ressource , um weitere Informationen zur automatischen Protokollierung zu finden.

# Set up the MLflow experiment
import mlflow

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

Hinweis

Wenn Sie die automatische Microsoft Fabric-Protokollierung in einer Notebooksitzung deaktivieren möchten, rufen Sie mlflow.autolog() auf und legen Sie disable=True fest.

Lesen von Rohdatumsdaten aus dem Lakehouse

df = (
    spark.read.format("csv")
    .option("header", "true")
    .load("Files/NYC_Property_Sales_Dataset/csv")
)

Schritt 3: Beginn der explorativen Datenanalyse

Um das DataSet zu überprüfen, wird empfohlen, manuell eine Teilmenge der Daten zu untersuchen, um ein besseres Verständnis zu erlangen. Für diese Aufgabe können Sie die display-Funktion verwenden, um den DataFrame zu auszudrucken. Sie können außerdem die Chart-Ansichten anzeigen, um Teilmengen des DataSets einfach zu visualisieren.

display(df)

Eine manuelle Überprüfung des DataSets führt zu einigen frühen Beobachtungen:

  • Instanzen mit Verkaufspreisen von $0,00. Nach dem Glossar der Fachbegriffe handelt es sich dabei um eine Eigentumsübertragung ohne Gegenleistung in bar. Anders ausgedrückt: Kein Cashflow in der Transaktion. Sie sollten Verkäufe mit $0,00 sales_price aus dem DataSet entfernen.

  • Das DataSet deckt unterschiedliche Gebäudeklassen ab. Dieses Notebook konzentriert sich jedoch auf Wohngebäude, die nach dem Glossar der Fachbegriffe als Typ "A" gekennzeichnet sind. Sie sollten das DataSet filtern, um nur Wohngebäude einzuschließen. Schließen Sie dazu entweder die building_class_at_time_of_sale Spalten oder die building_class_at_present Spalten ein. Sie müssen nur die building_class_at_time_of_sale Daten einschließen.

  • Das DataSet beinhaltet Instanzen, bei denen total_units Werte gleich 0 oder gross_square_feet Werte gleich 0 sind. Sie sollten alle Instanzen entfernen, in denen total_units oder gross_square_units Werte gleich 0 sind.

  • Einige Spalten , wie z. B. apartment_number, tax_class, build_class_at_present usw. – beinhalten fehlende Werte oder NULL-Werte. Gehen Sie davon aus, dass es sich bei den fehlenden Daten um Schreibfehler oder um nicht vorhandene Daten handelt. Die Analyse hängt nicht von diesen fehlenden Werten ab, sodass Sie sie ignorieren können.

  • Die sale_price Spalte wird als Zeichenfolge mit einem vorangestellten Zeichen "$" gespeichert. Um mit der Analyse fortzufahren, stellen Sie diese Spalte als Zahl dar. Sie sollten die sale_price Spalte in eine ganze Zahl umwandeln.

Typkonvertierung und -filterung

Um einige der bezeichneten Probleme zu beheben, importieren Sie die erforderlichen Bibliotheken.

# Import libraries
import pyspark.sql.functions as F
from pyspark.sql.types import *

Umwandeln der Umsatzdaten von Zeichenfolge in ganze Zahl

Verwenden Sie reguläre Ausdrücke, um den numerischen Teil der Zeichenkette vom Dollarzeichen zu trennen (z. B. in der Zeichenkette $300,000 trennen Sie $ und 300,000), und wandeln Sie dann den numerischen Teil in eine ganze Zahl um.

Filtern Sie als Nächstes die Daten so, dass nur Instanzen einbezogen werden, die alle diese Bedingungen erfüllen:

  1. Die sales_price ist größer als 0
  2. Die total_units ist größer als 0
  3. Die gross_square_feet ist größer als 0
  4. Die building_class_at_time_of_sale ist vom Typ A
df = df.withColumn(
    "sale_price", F.regexp_replace("sale_price", "[$,]", "").cast(IntegerType())
)
df = df.select("*").where(
    'sale_price > 0 and total_units > 0 and gross_square_feet > 0 and building_class_at_time_of_sale like "A%"'
)

Aggregation auf monatlicher Basis

Die Datenquelle verfolgt die Immobilienverkäufe auf einer Tagesbasis, aber dieser Ansatz ist zu detailliert für dieses Notebook. Fügen Sie stattdessen die Daten auf Monatsbasis hinzu.

Ändern Sie zunächst die Datumswerte so, dass nur Monats- und Jahresdaten angezeigt werden. Die Datumswerte beinhalten weiterhin die Jahresdaten. Sie können zwischen z. B. Dezember 2005 und Dezember 2006 unterscheiden.

Darüber hinaus behalten Sie nur die für die Analyse relevanten Spalten bei. Dazu gehören sales_price, total_units, gross_square_feet und sales_date. Sie müssen auch sales_date in month umbenennen.

monthly_sale_df = df.select(
    "sale_price",
    "total_units",
    "gross_square_feet",
    F.date_format("sale_date", "yyyy-MM").alias("month"),
)
display(monthly_sale_df)

Fassen Sie die Werte sale_price, total_units und gross_square_feet nach Monaten zusammen. Gruppieren Sie dann die Daten nach month, und addieren Sie alle Werte innerhalb jeder Gruppe.

summary_df = (
    monthly_sale_df.groupBy("month")
    .agg(
        F.sum("sale_price").alias("total_sales"),
        F.sum("total_units").alias("units"),
        F.sum("gross_square_feet").alias("square_feet"),
    )
    .orderBy("month")
)

display(summary_df)

Konvertierung von Pyspark zu Pandas

Pyspark DataFrames verarbeiten große Datasets gut. Aufgrund der Datenzusammenfassung ist die Größe des DataFrame jedoch geringer. Dies legt nahe, dass Sie jetzt Pandas DataFrames verwenden können.

Dieser Code überträgt das DataSet aus einem Pyspark DataFrame in ein Pandas DataFrame.

import pandas as pd

df_pandas = summary_df.toPandas()
display(df_pandas)

Visualisierung

Sie können den Immobilienhandelstrend von New York City untersuchen, um die Daten besser zu verstehen. Dies führt zu Einblicken in potenzielle Muster und Saisontrends. Weitere Informationen zur Microsoft Fabric-Datenvisualisierung finden Sie in dieser Ressource.

import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

f, (ax1, ax2) = plt.subplots(2, 1, figsize=(35, 10))
plt.sca(ax1)
plt.xticks(np.arange(0, 15 * 12, step=12))
plt.ticklabel_format(style="plain", axis="y")
sns.lineplot(x="month", y="total_sales", data=df_pandas)
plt.ylabel("Total Sales")
plt.xlabel("Time")
plt.title("Total Property Sales by Month")

plt.sca(ax2)
plt.xticks(np.arange(0, 15 * 12, step=12))
plt.ticklabel_format(style="plain", axis="y")
sns.lineplot(x="month", y="square_feet", data=df_pandas)
plt.ylabel("Total Square Feet")
plt.xlabel("Time")
plt.title("Total Property Square Feet Sold by Month")
plt.show()

Zusammenfassung der Beobachtungen aus der explorativen Datenanalyse

  • Die Daten zeigen ein klares, jährlich wiederkehrendes Muster; das bedeutet, dass die Daten eine jährliche Saisonabhängigkeit aufweisen
  • Die Sommermonate scheinen im Vergleich zu Wintermonaten höhere Verkaufsvolumen aufzuweisen
  • Bei einem Vergleich von Jahren mit hohen Umsätzen und Jahren mit niedrigen Umsätzen übersteigt die Umsatzdifferenz zwischen umsatzstarken und umsatzschwachen Monaten in Jahren mit hohen Umsätzen - in absoluten Werten - die Umsatzdifferenz zwischen umsatzstarken und umsatzschwachen Monaten in Jahren mit niedrigen Umsätzen.

Im Jahr 2004 zum Beispiel ist der Umsatzunterschied zwischen dem umsatzreichsten und dem umsatzschwächsten Monat annähernd gleich:

$900,000,000 - $500,000,000 = $400,000,000

Für 2011 stellt sich die Berechnung der Umsatzdifferenz wie folgt dar:

$400,000,000 - $300,000,000 = $100,000,000

Dies wird später wichtig, wenn Sie zwischen multiplikativen und additiven saisonalen Auswirkungen entscheiden müssen.

Schritt 4: Training und Verfolgung des Modells

Modellanpassung

Die Eingabe von Prophet ist immer ein DataFrame mit zwei Spalten. Eine Eingabespalte ist eine Zeitspalte mit dem Namen ds, und eine Eingabespalte ist eine Wertspalte mit dem Namen y. Die Zeitspalte sollte ein Datums-, Zeit- oder Datetime-Datenformat haben (z. B. YYYY_MM). Das DataSet erfüllt diese Bedingung. Die Wertspalte muss ein numerisches Datenformat haben.

Für die Modellanpassung müssen Sie nur die Zeitspalte in ds und die Wertspalte in y umbenennen und die Daten an Prophet übergeben. Weitere Informationen finden Sie in der Prophet-Python-API-Dokumentation.

df_pandas["ds"] = pd.to_datetime(df_pandas["month"])
df_pandas["y"] = df_pandas["total_sales"]

Prophet folgt der Scikit-Learn-Konvention. Erstellen Sie zunächst eine neue Instanz von Prophet, setzen Sie bestimmte Parameter (z. B. seasonality_mode) und passen Sie diese Instanz dann an den Datensatz an.

  • Obwohl ein konstanter zusätzlicher Faktor der Standard-Saisonaleffekt für Prophet ist, sollten Sie die "multiplikative" Saisonabhängigkeit für den Saisonaleffekt-Parameter verwenden. Die Analyse im vorangegangenen Abschnitt hat gezeigt, dass eine einfache additive Saisonalität aufgrund der Veränderungen in der Amplitude der Saisonabhängigkeit nicht gut zu den Daten passt.

  • Setzen Sie den Parameter weekly_seasonality auf "aus", da die Daten auf Monatsbasis zusammengefasst wurden. Wöchentliche Daten sind also nicht verfügbar.

  • Verwenden Sie Markov-Chain-Monte-Carlo-Methoden (MCMC), um die Schätzungen der saisonalen Unsicherheit zu erfassen. Standardmäßig kann Prophet Unsicherheitsschätzungen für den Trend und das beobachtungsspezifische Rauschen liefern, aber nicht für die Saisonabhängigkeit. Die MCMC-Methoden erfordern mehr Verarbeitungszeit, ermöglichen es dem Algorithmus jedoch, Unsicherheitsschätzungen für die Saisonabhängigkeit, den Trend und das beobachtungsspezifische Rauschen zu liefern. Lesen Sie die Dokumentation Prophet Unsicherheitsintervalle für weitere Informationen.

  • Stellen Sie die Sensibilität der automatischen Erkennung von Änderungspunkten über den Parameter changepoint_prior_scale ein. Der Prophet-Algorithmus versucht automatisch, Stellen in den Daten zu finden, an denen sich die Trajektorien abrupt ändern. Es kann schwierig werden, den richtigen Wert zu finden. Um dies zu beheben, können Sie verschiedene Werte ausprobieren und dann das Modell mit der besten Leistung auswählen. Weitere Informationen finden Sie in der Dokumentation Prophet Trend Changepoints.

from prophet import Prophet

def fit_model(dataframe, seasonality_mode, weekly_seasonality, chpt_prior, mcmc_samples):
    m = Prophet(
        seasonality_mode=seasonality_mode,
        weekly_seasonality=weekly_seasonality,
        changepoint_prior_scale=chpt_prior,
        mcmc_samples=mcmc_samples,
    )
    m.fit(dataframe)
    return m

Kreuzvalidierung im Vergleich

Prophet verfügt über ein integriertes Kreuzvalidierungs-Tool. Dieses Tool kann den Prognosefehler schätzen und das Modell mit der besten Leistung finden.

Die Kreuzvalidierungs-Technik kann die Modelleffizienz überprüfen. Bei dieser Technik wird das Modell auf einer Teilmenge des Datensatzes trainiert, und die Tests werden auf einer zuvor nicht gesehenen Teilmenge des Datensatzes durchgeführt. Mit dieser Technik kann überprüft werden, wie gut ein statistisches Modell in einem unabhängigen Datensatz verallgemeinert werden kann.

Für die Kreuzvalidierung wird eine bestimmte Probe des Datensatzes reserviert, die nicht Teil des Trainingsdatensatzes war. Testen Sie dann das trainierte Modell an dieser Probe, bevor Sie es verwenden. Dieser Ansatz funktioniert jedoch nicht bei Zeitreihendaten, denn wenn das Modell Daten aus den Monaten Januar 2005 und März 2005 gesehen hat und Sie versuchen, eine Vorhersage für den Monat Februar 2005 zu treffen, kann das Modell im Grunde schummeln, denn es könnte sehen, wohin der Datentrend führt. In realen Anwendungen geht es darum, Prognosen für die Zukunft vorzunehmen, und zwar für die ungesehenen Regionen.

Um dies zu bewältigen und den Test zuverlässig zu gestalten, teilen Sie den Datensatz auf der Grundlage der Datumsangaben auf. Verwenden Sie das DataSet bis zu einem bestimmten Datum (z. B. die Daten der ersten 11 Jahren) für die Schulung, und verwenden Sie dann die restlichen, ungesehenen Daten für die Vorhersage.

Beginnen Sie in diesem Szenario mit 11 Jahren Schulungsdaten, und erstellen Sie dann monatliche Vorhersagen mithilfe eines Einjahreshorizonts. Die Trainingsdaten enthalten alle Daten von 2003 bis 2013. Der erste Durchlauf behandelt dann die Vorhersagen von Januar 2014 bis Januar 2015. Der nächste Durchlauf behandelt Vorhersagen von Februar 2014 bis Februar 2015 usw.

Wiederholen Sie diesen Vorgang für jedes der drei trainierten Modelle, um zu sehen, welches Modell am besten funktioniert. Vergleichen Sie dann diese Vorhersagen mit realen Werten, um die Vorhersagequalität des besten Modells bestimmen.

from prophet.diagnostics import cross_validation
from prophet.diagnostics import performance_metrics

def evaluation(m):
    df_cv = cross_validation(m, initial="4017 days", period="30 days", horizon="365 days")
    df_p = performance_metrics(df_cv, monthly=True)
    future = m.make_future_dataframe(periods=12, freq="M")
    forecast = m.predict(future)
    return df_p, future, forecast

Protokollieren eines Modells mit MLflow

Protokollieren Sie die Modelle, um ihre Parameter nachzuverfolgen, und speichern Sie die Modelle für die spätere Verwendung. Alle diese Informationen werden unter dem Experiment-Namen im Arbeitsbereich protokolliert. Das Modell, die Parameter und Metriken werden zusammen mit den MLflow-Elementen für die automatische Protokollierung in einem MLflow-Durchgang gespeichert.

# Setup MLflow
from mlflow.models.signature import infer_signature

Durchführen von Experimenten

Ein Experiment des maschinellen Lernens dient als primäre Einheit für die Organisation und Steuerung aller zugehörigen Durchläufe des maschinellen Lernens. Eine Ausführung entspricht einer einzelnen Ausführung des Modellcodes. Die Nachverfolgung von Experimenten des maschinellen Lernens bezieht sich auf den Prozess der Verwaltung aller verschiedenen Experimente und ihrer Komponenten. Dies umfasst Parameter, Metriken, Modelle und andere Artefakte und hilft dabei, die erforderlichen Komponenten eines bestimmten maschinellen Lernexperiments zu organisieren. Die Verfolgung von Experimenten des maschinellen Lernens ermöglicht auch die einfache Vervielfältigung früherer Ergebnisse mit gespeicherten Experimenten. Weitere Informationen zu Machine-Learning-Experimenten in Microsoft Fabric. Sobald Sie die Schritte festgelegt haben, die Sie einbeziehen wollen (z. B. die Anpassung und Auswertung des Prophet-Modells in diesem Notebook), können Sie das Experiment durchführen.

model_name = f"{EXPERIMENT_NAME}-prophet"

models = []
df_metrics = []
forecasts = []
seasonality_mode = "multiplicative"
weekly_seasonality = False
changepoint_priors = [0.01, 0.05, 0.1]
mcmc_samples = 100

for chpt_prior in changepoint_priors:
    with mlflow.start_run(run_name=f"prophet_changepoint_{chpt_prior}"):
        # init model and fit
        m = fit_model(df_pandas, seasonality_mode, weekly_seasonality, chpt_prior, mcmc_samples)
        models.append(m)
        # Validation
        df_p, future, forecast = evaluation(m)
        df_metrics.append(df_p)
        forecasts.append(forecast)
        # Log model and parameters with MLflow
        mlflow.prophet.log_model(
            m,
            model_name,
            registered_model_name=model_name,
            signature=infer_signature(future, forecast),
        )
        mlflow.log_params(
            {
                "seasonality_mode": seasonality_mode,
                "mcmc_samples": mcmc_samples,
                "weekly_seasonality": weekly_seasonality,
                "changepoint_prior": chpt_prior,
            }
        )
        metrics = df_p.mean().to_dict()
        metrics.pop("horizon")
        mlflow.log_metrics(metrics)

Screenshot des Eigenschaftenpanels.

Visualisieren eines Modells mit Prophet

Die integrierten Prophet-Anzeige-Funktionen können die Ergebnisse der Modellanpassung anzeigen.

Die schwarzen Punkte sind Datenpunkte, die zum Trainieren des Modells verwendet werden. Die blaue Linie ist die Vorhersage, und der hellblaue Bereich zeigt die Unsicherheitsintervalle. Sie haben drei Modelle mit unterschiedlichen changepoint_prior_scale Werten erstellt. Die Vorhersagen dieser drei Modelle werden in den Ergebnissen dieses Codeblocks angezeigt.

for idx, pack in enumerate(zip(models, forecasts)):
    m, forecast = pack
    fig = m.plot(forecast)
    fig.suptitle(f"changepoint = {changepoint_priors[idx]}")

Der kleinste changepoint_prior_scale Wert in der ersten Grafik führt zu einer unzureichenden Anpassung der Trendänderungen. Der größte changepoint_prior_scale Wert im dritten Diagramm könnte zu einer Überanpassung führen. Die zweite Grafik scheint also die optimale Wahl zu sein. Dies impliziert, dass das zweite Modell das am besten geeignete ist.

Prophet kann auch mühelos die zugrunde liegenden Trends und Saisonalitäten visualisieren. Visualisierungen des zweiten Modells werden in den Ergebnissen dieses Codeblocks angezeigt.

BEST_MODEL_INDEX = 1  # Set the best model index according to the previous results
fig2 = models[BEST_MODEL_INDEX].plot_components(forecast)

Screenshot eines Diagramms mit den jährlichen Trends bei den Preisdaten.

In diesen Grafiken spiegelt die hellblaue Schattierung die Unsicherheit wider. Die obere Grafik zeigt einen starken, lang anhaltenden Schwankungstrend. Im Laufe einiger Jahre steigen und fallen die Absatzzahlen. Die untere Grafik zeigt, dass die Verkäufe in der Regel im Februar und September ihren Höhepunkt erreichen und in diesen Monaten die höchsten Werte des Jahres erreichen. Kurz nach diesen Monaten fallen sie im März und Oktober auf die Mindestwerte des Jahres.

Bewerten Sie die Leistung der Modelle mithilfe verschiedener Metriken, z. B.:

  • Mittlere quadratische Abweichung (Mean Squared Error, MSE)
  • Mittlere quadratische Gesamtabweichung (Root Mean Squared Error, RMSE)
  • Mittlere absolute Abweichung (Mean Absolute Error, MAE)
  • Mittlerer absoluter Prozentfehler (Mean Absolute Percent Error, MAPE)
  • Medianer absoluter Prozentfehler (Median Absolute Percent Error, MDAPE)
  • Symmetrischer mittlerer absoluter Prozentfehler (Symmetric Mean Absolute Percentage Error, SMAPE)

Werten Sie die Abdeckung mithilfe der Schätzungen yhat_lower und yhat_upper aus. Berücksichtigen Sie die unterschiedlichen Horizonte, in denen Sie ein Jahr in die Zukunft vorhersagen, und das 12 Mal.

display(df_metrics[BEST_MODEL_INDEX])

Mit der MAPE-Metrik sind bei diesem Prognosemodell Vorhersagen, die einen Monat in die Zukunft reichen, typischerweise mit Fehlern von etwa 8 % verbunden. Für Vorhersagen von einem Jahr in die Zukunft steigt der Fehler jedoch auf etwa 10 %.

Schritt 5: Bewerten des Modells und Speichern der Vorhersageergebnisse

Bewerten Sie nun das Modell und speichern Sie die Ergebnisse der Vorhersage.

Machen Sie Vorhersagen mit Predict Transformer

Nun können Sie das Modell laden und für Vorhersagen verwenden. Benutzer können Machine-Learning-Modelle mit PREDICT operativ einsetzen, einer skalierbaren Microsoft Fabric-Funktion, die Batch-Scoring in jeder Computer-Engine unterstützt. Erfahren Sie mehr über PREDICT und die Verwendung in Microsoft Fabric unter dieser Ressource.

from synapse.ml.predict import MLFlowTransformer

spark.conf.set("spark.synapse.ml.predict.enabled", "true")

model = MLFlowTransformer(
    inputCols=future.columns.values,
    outputCol="prediction",
    modelName=f"{EXPERIMENT_NAME}-prophet",
    modelVersion=BEST_MODEL_INDEX,
)

test_spark = spark.createDataFrame(data=future, schema=future.columns.to_list())

batch_predictions = model.transform(test_spark)

display(batch_predictions)
# Code for saving predictions into lakehouse
batch_predictions.write.format("delta").mode("overwrite").save(
    f"{DATA_FOLDER}/predictions/batch_predictions"
)
# Determine the entire runtime
print(f"Full run cost {int(time.time() - ts)} seconds.")