Trenowanie i ocenianie modelu prognozowania szeregów czasowych
W tym notesie utworzymy program do prognozowania danych szeregów czasowych, które mają cykle sezonowe. Używamy zestawu danych NYC Property Sales z datami od 2003 do 2015 opublikowanymi przez Departament Finansów w Nowym Jorku w portalu Open Data Portal.
Wymagania wstępne
Uzyskaj subskrypcję usługi Microsoft Fabric. Możesz też utworzyć konto bezpłatnej wersji próbnej usługi Microsoft Fabric.
Zaloguj się do usługi Microsoft Fabric.
Użyj przełącznika środowiska po lewej stronie głównej, aby przełączyć się na środowisko usługi Synapse Nauka o danych.
- Znajomość notesów usługi Microsoft Fabric.
- Usługa Lakehouse do przechowywania danych w tym przykładzie. Aby uzyskać więcej informacji, zobacz Dodawanie magazynu lakehouse do notesu.
Postępuj zgodnie z instrukcjami w notesie
Możesz wykonać czynności opisane w notesie na jeden z dwóch sposobów:
- Otwórz i uruchom wbudowany notes w środowisku usługi Synapse Nauka o danych.
- Przekaż notes z usługi GitHub do środowiska usługi Synapse Nauka o danych.
Otwieranie wbudowanego notesu
W tym samouczku dołączymy przykładowy notes szeregów czasowych.
Aby otworzyć wbudowany notes przykładowy samouczka w środowisku usługi Synapse Nauka o danych:
Przejdź do strony głównej usługi Synapse Nauka o danych.
Wybierz pozycję Użyj przykładu.
Wybierz odpowiedni przykład:
- Na domyślnej karcie Kompleksowe przepływy pracy (Python), jeśli przykład dotyczy samouczka dotyczącego języka Python.
- Na karcie Kompleksowe przepływy pracy (R), jeśli przykład dotyczy samouczka języka R.
- Jeśli przykład jest przeznaczony do szybkiego samouczka, na karcie Szybkie samouczki .
Przed rozpoczęciem uruchamiania kodu dołącz usługę Lakehouse do notesu .
Importowanie notesu z usługi GitHub
AIsample — Time Series Forecasting.ipynb to notes, który towarzyszy temu samouczkowi.
Aby otworzyć towarzyszący notes na potrzeby tego samouczka, postępuj zgodnie z instrukcjami w temacie Przygotowywanie systemu do celów nauki o danych, aby zaimportować notes do obszaru roboczego.
Jeśli wolisz skopiować i wkleić kod z tej strony, możesz utworzyć nowy notes.
Przed rozpoczęciem uruchamiania kodu pamiętaj, aby dołączyć usługę Lakehouse do notesu .
Krok 1. Instalowanie bibliotek niestandardowych
Podczas tworzenia modelu uczenia maszynowego lub obsługi analizy danych ad hoc może być konieczne szybkie zainstalowanie biblioteki niestandardowej (na przykład prophet
w tym notesie) dla sesji platformy Apache Spark. W tym celu masz dwie opcje.
- Aby szybko rozpocząć pracę z nowymi bibliotekami, możesz użyć funkcji instalacji w wierszu (na przykład
%pip
,%conda
, itp.). Spowoduje to zainstalowanie tylko bibliotek niestandardowych w bieżącym notesie, a nie w obszarze roboczym.
# Use pip to install libraries
%pip install <library name>
# Use conda to install libraries
%conda install <library name>
- Alternatywnie możesz utworzyć środowisko sieci szkieletowej, zainstalować biblioteki ze źródeł publicznych lub przekazać do niego biblioteki niestandardowe, a następnie administrator obszaru roboczego może dołączyć środowisko jako domyślne dla obszaru roboczego. Wszystkie biblioteki w środowisku staną się następnie dostępne do użycia w dowolnych notesach i definicjach zadań platformy Spark w obszarze roboczym. Aby uzyskać więcej informacji na temat środowisk, zobacz tworzenie, konfigurowanie i używanie środowiska w usłudze Microsoft Fabric.
W tym notesie użyjesz %pip install
polecenia , aby zainstalować bibliotekę prophet
. Jądro PySpark zostanie uruchomione ponownie po .%pip install
Oznacza to, że przed uruchomieniem innych komórek należy zainstalować bibliotekę.
# Use pip to install Prophet
%pip install prophet
Krok 2. Ładowanie danych
Zestaw danych
W tym notesie jest używany zestaw danych danych NYC Property Sales. Obejmuje ona dane z 2003 do 2015 r., opublikowane przez Departament Finansów w Nowym Jorku w portalu Open Data Portal NYC.
Zestaw danych zawiera rekord każdej sprzedaży budynków na rynku nieruchomości w Nowym Jorku w ciągu 13 lat. Zapoznaj się z słownikiem terminów dla plików sprzedaży właściwości, aby zapoznać się z definicją kolumn w zestawie danych.
dzielnica | sąsiedztwo | building_class_category | tax_class | block | wiele | eastment | building_class_at_present | adres | 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 | MIASTO ALFABETU | 07 WYNAJEM - WALKUP APARTAMENTY | 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 | MIASTO ALFABETU | 07 WYNAJEM - WALKUP APARTAMENTY | 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 |
Celem jest utworzenie modelu, który prognozuje miesięczną łączną sprzedaż na podstawie danych historycznych. W tym celu użyjesz Proroka, biblioteki prognozowania typu open source opracowanej przez Facebooka. Prorok opiera się na modelu addytywnego, w którym trendy nieliniowe pasują do codziennych, cotygodniowych i rocznych sezonowości oraz efektów świątecznych. Prorok najlepiej sprawdza się w zestawach danych szeregów czasowych, które mają silne efekty sezonowe i kilka sezonów danych historycznych. Ponadto Prorok niezawodnie obsługuje brakujące dane i wartości odstające.
Prorok używa modelu szeregów czasowych, który składa się z trzech składników:
- trend: Prorok zakłada kawałek mądry stały wskaźnik wzrostu, z automatycznym wyborem punktów zmian
- sezonowość: Domyślnie prorok używa Serii Fourier do dopasowania do sezonowości tygodniowej i rocznej
- święta: Prorok wymaga wszystkich przeszłych i przyszłych wystąpień świąt. Jeśli święto nie powtórzy się w przyszłości, Prorok nie uwzględni go w prognozie.
Ten notes agreguje dane co miesiąc, więc ignoruje święta.
Przeczytaj oficjalny dokument , aby uzyskać więcej informacji na temat technik modelowania proroka.
Pobieranie zestawu danych i przekazywanie do usługi Lakehouse
Źródło danych składa się z 15 .csv
plików. Pliki te zawierają zapisy sprzedaży nieruchomości z pięciu dzielnic w Nowym Jorku, w latach 2003-2015. Dla wygody nyc_property_sales.tar
plik przechowuje wszystkie te .csv
pliki, kompresując je do jednego pliku. Ten plik jest .tar
hostem publicznie dostępnego magazynu obiektów blob.
Napiwek
Za pomocą parametrów pokazanych w tej komórce kodu można łatwo zastosować ten notes do różnych zestawów danych.
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
Ten kod pobiera publicznie dostępną wersję zestawu danych, a następnie przechowuje ten zestaw danych w usłudze Fabric Lakehouse.
Ważne
Przed uruchomieniem tego notesu upewnij się, że dodasz magazyn lakehouse . Niepowodzenie w tym celu spowoduje wystąpienie błędu.
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}")
Rozpocznij nagrywanie czasu wykonywania tego notesu.
# Record the notebook running time
import time
ts = time.time()
Konfigurowanie śledzenia eksperymentów MLflow
Aby rozszerzyć możliwości rejestrowania MLflow, automatyczne rejestrowanie automatycznie przechwytuje wartości parametrów wejściowych i metryk wyjściowych modelu uczenia maszynowego podczas trenowania. Te informacje są następnie rejestrowane w obszarze roboczym, w którym interfejsy API MLflow lub odpowiedni eksperyment w obszarze roboczym mogą uzyskiwać do niego dostęp i wizualizować je. Odwiedź ten zasób , aby uzyskać więcej informacji na temat automatycznego rejestrowania.
# Set up the MLflow experiment
import mlflow
mlflow.set_experiment(EXPERIMENT_NAME)
mlflow.autolog(disable=True) # Disable MLflow autologging
Uwaga
Jeśli chcesz wyłączyć automatyczne rejestrowanie usługi Microsoft Fabric w sesji notesu, wywołaj mlflow.autolog()
i ustaw polecenie disable=True
.
Odczytywanie nieprzetworzonych danych daty z lakehouse
df = (
spark.read.format("csv")
.option("header", "true")
.load("Files/NYC_Property_Sales_Dataset/csv")
)
Krok 3. Rozpoczęcie eksploracyjnej analizy danych
Aby przejrzeć zestaw danych, możesz ręcznie zbadać podzestaw danych, aby lepiej zrozumieć ten zestaw danych. Za pomocą display
funkcji można wydrukować ramkę danych. Możesz również wyświetlić widoki wykresów, aby łatwo wizualizować podzestawy zestawu danych.
display(df)
Ręczny przegląd zestawu danych prowadzi do wczesnych obserwacji:
Wystąpienia cen sprzedaży w wysokości 0,00 USD. Zgodnie ze słownikiem warunków oznacza to przeniesienie własności bez środków pieniężnych. Innymi słowy, nie przepływa gotówki w transakcji. Należy usunąć sprzedaż z wartościami $0.00
sales_price
z zestawu danych.Zestaw danych obejmuje różne klasy budynku. Jednak ten notes koncentruje się na budynkach mieszkalnych, które zgodnie z słownikiem warunków są oznaczone jako "A". Zestaw danych należy filtrować tak, aby zawierał tylko budynki mieszkalne. W tym celu dołącz kolumny
building_class_at_time_of_sale
lubbuilding_class_at_present
. Musisz uwzględnićbuilding_class_at_time_of_sale
tylko dane.Zestaw danych zawiera wystąpienia, w których
total_units
wartości są równe 0 lubgross_square_feet
równe 0. Należy usunąć wszystkie wystąpienia, w którychtotal_units
lubgross_square_units
wartości są równe 0.Niektóre kolumny — na przykład
apartment_number
,tax_class
,build_class_at_present
itp. — mają brakujące wartości lub NULL. Załóżmy, że brakujące dane obejmują błędy duchowne lub nieistniejące dane. Analiza nie zależy od tych brakujących wartości, więc można je zignorować.Kolumna
sale_price
jest przechowywana jako ciąg z poprzedzanym znakiem "$". Aby kontynuować analizę, należy przedstawić tę kolumnę jako liczbę. Kolumnę należy rzutowaćsale_price
jako liczbę całkowitą.
Konwersja i filtrowanie typów
Aby rozwiązać niektóre zidentyfikowane problemy, zaimportuj wymagane biblioteki.
# Import libraries
import pyspark.sql.functions as F
from pyspark.sql.types import *
Rzutowanie danych sprzedaży z ciągu na liczbę całkowitą
Użyj wyrażeń regularnych, aby oddzielić część liczbową ciągu od znaku dolara (na przykład w ciągu $300,000
, podzielić $
i 300,000
), a następnie rzutować część liczbową jako liczbę całkowitą.
Następnie przefiltruj dane, aby uwzględnić tylko wystąpienia spełniające wszystkie te warunki:
- Wartość
sales_price
jest większa niż 0 - Wartość
total_units
jest większa niż 0 - Wartość
gross_square_feet
jest większa niż 0 - Jest
building_class_at_time_of_sale
typu 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%"'
)
Agregacja co miesiąc
Zasób danych śledzi sprzedaż nieruchomości codziennie, ale takie podejście jest zbyt szczegółowe dla tego notesu. Zamiast tego agreguj dane co miesiąc.
Najpierw zmień wartości daty, aby pokazywać tylko dane dotyczące miesiąca i roku. Wartości daty nadal zawierają dane roku. Można na przykład odróżnić od grudnia 2005 r. do grudnia 2006 r.
Ponadto zachowaj tylko kolumny istotne dla analizy. Należą do nich sales_price
: , total_units
gross_square_feet
i sales_date
. Należy również zmienić nazwę sales_date
na month
.
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)
Agregowanie sale_price
total_units
wartości i według gross_square_feet
miesięcy. Następnie pogrupuj dane według month
wartości i zsumuj wszystkie wartości w każdej grupie.
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)
Konwersja Pyspark na bibliotekę Pandas
Ramki danych Pyspark obsługują duże zestawy danych. Jednak ze względu na agregację danych rozmiar ramki danych jest mniejszy. Sugeruje to, że teraz można używać ramek danych biblioteki pandas.
Ten kod rzutuje zestaw danych z ramki danych pyspark na ramkę danych biblioteki pandas.
import pandas as pd
df_pandas = summary_df.toPandas()
display(df_pandas)
Wizualizacja
Możesz zbadać trend handlu nieruchomościami w Nowym Jorku, aby lepiej zrozumieć dane. Prowadzi to do wglądu w potencjalne wzorce i trendy sezonowości. Dowiedz się więcej o wizualizacji danych usługi Microsoft Fabric w tym zasobie.
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()
Podsumowanie obserwacji z eksploracyjnej analizy danych
- Dane pokazują wyraźny wzorzec cykliczny w cykli rocznej; oznacza to, że dane mają roczną sezonowość
- Miesiące letnie wydają się mieć wyższe wolumeny sprzedaży w porównaniu do miesięcy zimowych
- W porównaniu lat z wysoką sprzedażą i latami o niskiej sprzedaży różnica przychodów między wysokimi miesiącami sprzedaży a niskimi miesiącami sprzedaży w wysokich latach sprzedaży przekracza - w ujęciu bezwzględnym - różnicę przychodów między wysokimi miesiącami sprzedaży a niskimi miesiącami sprzedaży w niskich latach sprzedaży.
Na przykład w 2004 r. różnica przychodów między najwyższym miesiącem sprzedaży a najniższym miesiącem sprzedaży wynosi:
$900,000,000 - $500,000,000 = $400,000,000
W przypadku roku 2011 obliczanie różnicy przychodów dotyczy:
$400,000,000 - $300,000,000 = $100,000,000
Staje się to ważne później, kiedy należy zdecydować między efektami mnożenia i dodawania sezonowości.
Krok 4. Trenowanie i śledzenie modelu
Dopasowanie modelu
Dane wejściowe proroka to zawsze dwukolumna ramka danych. Jedna kolumna wejściowa to kolumna czasowa o nazwie ds
, a jedna kolumna wejściowa to kolumna wartości o nazwie y
. Kolumna godziny powinna mieć format danych daty, godziny lub daty/godziny (na przykład YYYY_MM
). Zestaw danych w tym miejscu spełnia ten warunek. Kolumna wartości musi być formatem danych liczbowych.
W przypadku dopasowania modelu należy zmienić tylko nazwę kolumny czasu na ds
kolumnę i wartość na y
, a następnie przekazać dane do proroka. Aby uzyskać więcej informacji, zapoznaj się z dokumentacją interfejsu API języka Python proroka.
df_pandas["ds"] = pd.to_datetime(df_pandas["month"])
df_pandas["y"] = df_pandas["total_sales"]
Prorok jest zgodny z konwencją scikit-learn . Najpierw utwórz nowe wystąpienie proroka, ustaw określone parametry (na przykładseasonality_mode
), a następnie dopasuj to wystąpienie do zestawu danych.
Chociaż stały współczynnik dodawania jest domyślnym efektem sezonowości dla Proroka, należy użyć "mnożenia" sezonowości dla parametru efektu sezonowości. Analiza w poprzedniej sekcji wykazała, że ze względu na zmiany w amplitudzie sezonowości prosta sezonowość dodawania nie pasuje do wszystkich danych.
Ustaw parametr weekly_seasonality na wyłączony, ponieważ dane zostały zagregowane według miesięcy. W związku z tym dane tygodniowe nie są dostępne.
Użyj metod Markov Chain Monte Carlo (MCMC), aby uchwycić szacunki niepewności sezonowości. Domyślnie prorok może dostarczyć szacunków niepewności na temat trendu i hałasu obserwacji, ale nie dla sezonowości. McMC wymaga więcej czasu przetwarzania, ale umożliwiają algorytmowi zapewnienie szacunków niepewności dotyczących sezonowości oraz trendu i szumu obserwacji. Aby uzyskać więcej informacji, zapoznaj się z dokumentacją Interwałów niepewności proroka.
Dostrajanie poufności automatycznego wykrywania punktów zmian za pomocą parametru changepoint_prior_scale . Algorytm proroka automatycznie próbuje znaleźć wystąpienia w danych, w których trajektorie nagle się zmieniają. Znalezienie poprawnej wartości może być trudne. Aby rozwiązać ten problem, możesz wypróbować różne wartości, a następnie wybrać model z najlepszą wydajnością. Aby uzyskać więcej informacji, przeczytaj dokumentację Proroka 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
Krzyżowa walidacja
Prorok ma wbudowane narzędzie do krzyżowego sprawdzania poprawności. To narzędzie może oszacować błąd prognozowania i znaleźć model z najlepszą wydajnością.
Technika krzyżowego sprawdzania poprawności może weryfikować wydajność modelu. Ta technika szkoli model w podzestawie zestawu danych i uruchamia testy na wcześniej niezapieszczanym podzestawie zestawu danych. Ta technika umożliwia sprawdzenie, jak dobrze model statystyczny uogólnia niezależny zestaw danych.
W przypadku krzyżowego sprawdzania poprawności zarezerwuj konkretny przykład zestawu danych, który nie był częścią zestawu danych trenowania. Następnie przetestuj wytrenowany model na tym przykładzie przed wdrożeniem. Jednak takie podejście nie działa w przypadku danych szeregów czasowych, ponieważ jeśli model widział dane z miesięcy stycznia 2005 r. i marca 2005 r., i próbujesz przewidzieć miesiąc luty 2005 r., model może zasadniczo oszukiwać, ponieważ może zobaczyć, gdzie trend danych prowadzi. W rzeczywistych aplikacjach celem jest prognozowanie na przyszłość, jak niezamierzonych regionów.
Aby to obsłużyć, i uczynić test niezawodnym, podziel zestaw danych na podstawie dat. Użyj zestawu danych do określonej daty (na przykład pierwszych 11 lat danych) na potrzeby trenowania, a następnie użyj pozostałych niezaużytych danych do przewidywania.
W tym scenariuszu zacznij od 11 lat danych treningowych, a następnie wykonaj miesięczne przewidywania przy użyciu horyzontu jednego roku. W szczególności dane szkoleniowe zawierają wszystko od 2003 do 2013 roku. Następnie pierwszy przebieg obsługuje przewidywania od stycznia 2014 r. do stycznia 2015 r. Następny przebieg obsługuje przewidywania w lutym 2014 r. do lutego 2015 r. itd.
Powtórz ten proces dla każdego z trzech wytrenowanych modeli, aby zobaczyć, który model działa najlepiej. Następnie porównaj te przewidywania z rzeczywistymi wartościami, aby ustalić jakość przewidywania najlepszego modelu.
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
Model rejestrowania za pomocą biblioteki MLflow
Zarejestruj modele, aby śledzić ich parametry i zapisać modele do późniejszego użycia. Wszystkie istotne informacje o modelu są rejestrowane w obszarze roboczym pod nazwą eksperymentu. Model, parametry i metryki wraz z elementami automatycznego rejestrowania MLflow jest zapisywany w jednym przebiegu MLflow.
# Setup MLflow
from mlflow.models.signature import infer_signature
Przeprowadzanie eksperymentów
Eksperyment uczenia maszynowego służy jako podstawowa jednostka organizacji i kontroli dla wszystkich powiązanych przebiegów uczenia maszynowego. Przebieg odpowiada pojedynczemu wykonaniu kodu modelu. Śledzenie eksperymentów uczenia maszynowego odnosi się do zarządzania wszystkimi różnymi eksperymentami i ich składnikami. Obejmuje to parametry, metryki, modele i inne artefakty oraz ułatwia organizowanie wymaganych składników określonego eksperymentu uczenia maszynowego. Śledzenie eksperymentów uczenia maszynowego umożliwia również łatwe duplikowanie poprzednich wyników z zapisanymi eksperymentami. Dowiedz się więcej o eksperymentach uczenia maszynowego w usłudze Microsoft Fabric. Po określeniu kroków, które zamierzasz uwzględnić (na przykład dopasować i ocenić model Proroka w tym notesie), możesz uruchomić eksperyment.
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)
Wizualizowanie modelu za pomocą proroka
Prorok ma wbudowane funkcje wizualizacji, które mogą pokazywać wyniki dopasowania modelu.
Czarne kropki oznaczają punkty danych używane do trenowania modelu. Niebieska linia jest przewidywaniem, a jasnoniebieski obszar pokazuje interwały niepewności. Utworzono trzy modele z różnymi changepoint_prior_scale
wartościami. Przewidywania tych trzech modeli są wyświetlane w wynikach tego bloku kodu.
for idx, pack in enumerate(zip(models, forecasts)):
m, forecast = pack
fig = m.plot(forecast)
fig.suptitle(f"changepoint = {changepoint_priors[idx]}")
Najmniejsza changepoint_prior_scale
wartość na pierwszym wykresie prowadzi do niedopasowania zmian trendu. Największy changepoint_prior_scale
na trzecim wykresie może spowodować nadmierne dopasowanie. Dlatego drugi wykres wydaje się być optymalnym wyborem. Oznacza to, że drugi model jest najbardziej odpowiedni.
Wizualizowanie trendów i sezonowości za pomocą proroka
Prorok może również łatwo wizualizować podstawowe trendy i sezony. Wizualizacje drugiego modelu są wyświetlane w wynikach tego bloku kodu.
BEST_MODEL_INDEX = 1 # Set the best model index according to the previous results
fig2 = models[BEST_MODEL_INDEX].plot_components(forecast)
Na tych wykresach jasnoniebieskie cieniowanie odzwierciedla niepewność. Górny wykres przedstawia silny, długotrwały trend oscylujący. W ciągu kilku lat wielkość sprzedaży wzrośnie i spadnie. Niższy wykres pokazuje, że sprzedaż ma tendencję do szczytu w lutym i wrześniu, osiągając maksymalne wartości dla roku w tych miesiącach. Wkrótce po tych miesiącach, w marcu i październiku, spadną do wartości minimalnych roku.
Oceń wydajność modeli przy użyciu różnych metryk, na przykład:
- błąd średniokwadratowy (MSE)
- Błąd średniokwadratowy (RMSE)
- średni błąd bezwzględny (MAE)
- średni błąd procentu bezwzględnego (MAPE)
- mediana bezwzględnego błędu procentu (MDAPE)
- symmetric mean absolute percentage error (SMAPE) (symmetric mean absolute percentage error (SMAPE)
Oceń pokrycie przy użyciu wartości yhat_lower
i yhat_upper
. Zwróć uwagę na różne horyzonty, w których przewidujesz jeden rok w przyszłości, 12 razy.
display(df_metrics[BEST_MODEL_INDEX])
W przypadku metryki MAPE dla tego modelu prognozowania przewidywania, które przedłużają jeden miesiąc na przyszłość, zwykle obejmują błędy o około 8%. Jednak w przypadku przewidywań rok w przyszłości błąd wzrasta do około 10%.
Krok 5. Ocenianie modelu i zapisywanie wyników przewidywania
Teraz przelić model i zapisać wyniki przewidywania.
Przewidywanie za pomocą funkcji Predict Transformer
Teraz możesz załadować model i użyć go do przewidywania. Użytkownicy mogą operacjonalizować modele uczenia maszynowego za pomocą funkcji PREDICT, skalowalnej funkcji usługi Microsoft Fabric obsługującej ocenianie wsadowe w dowolnym aucie obliczeniowym. Dowiedz się więcej o PREDICT
usłudze i sposobie jej używania w usłudze Microsoft Fabric w tym zasobie.
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.")