Opracowywanie, ocenianie i ocenianie modelu prognozowania sprzedaży superstore
Ten samouczek przedstawia pełny przykład przepływu pracy usługi Synapse Nauka o danych w usłudze Microsoft Fabric. Scenariusz tworzy model prognozowania, który używa historycznych danych sprzedaży do przewidywania sprzedaży kategorii produktów w superstore.
Prognozowanie jest kluczowym elementem aktywów w sprzedaży. Łączy ona dane historyczne i metody predykcyjne, aby zapewnić wgląd w przyszłe trendy. Prognozowanie umożliwia analizowanie przeszłości sprzedaży w celu identyfikowania wzorców i poznawania zachowań konsumentów w celu optymalizacji strategii spisu, produkcji i marketingu. To proaktywne podejście zwiększa elastyczność, czas reakcji i ogólną wydajność firm na dynamicznym rynku.
W tym samouczku opisano następujące kroki:
- Ładowanie danych
- Korzystanie z eksploracyjnej analizy danych w celu zrozumienia i przetworzenia danych
- Trenowanie modelu uczenia maszynowego przy użyciu pakietu oprogramowania open source i śledzenie eksperymentów za pomocą biblioteki MLflow i funkcji automatycznego rejestrowania sieci szkieletowej
- Zapisywanie końcowego modelu uczenia maszynowego i przewidywanie
- Wyświetlanie wydajności modelu za pomocą wizualizacji usługi Power BI
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.
- W razie potrzeby utwórz magazyn lakehouse usługi Microsoft Fabric zgodnie z opisem w temacie Tworzenie magazynu lakehouse w usłudze Microsoft Fabric.
Postępuj zgodnie z instrukcjami w notesie
Możesz wybrać jedną z tych opcji, które należy wykonać w notesie:
- Otwórz i uruchom wbudowany notes w środowisku usługi Synapse Nauka o danych
- Przekazywanie notesu z usługi GitHub do środowiska usługi Synapse Nauka o danych
Otwieranie wbudowanego notesu
Przykładowy notes prognozowania sprzedaży jest dołączony do tego samouczka.
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
Notes AIsample — Superstore Forecast.ipynb 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. Ładowanie danych
Zestaw danych zawiera 9995 wystąpień sprzedaży różnych produktów. Zawiera również 21 atrybutów. Ta tabela pochodzi z pliku Superstore.xlsx używanego w tym notesie:
Identyfikator wiersza | Identyfikator zamówienia | Data zamówienia | Ship Date | Tryb wysyłki | Identyfikator klienta | Nazwa klienta | Segment | Country | City | Stan | Kod pocztowy | Region (Region) | Identyfikator produktu | Kategoria | Podkategora | Nazwa produktu | Sprzedaż | Ilość | Rabat | Profit (Zysk) |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
100 | USA-2015-108966 | 2015-10-11 | 2015-10-18 | Standardowa, klasa | SO-20335 | Sean O'Donnell | Produkty konsumenckie | Stany Zjednoczone | Fort Lauderdale | Floryda | 33311 | Południe | FUR-TA-10000577 | Meble | Tabele | Bretford CR4500 Series Slim Prostokątna tabela | 957.5775 | 5 | 0,45 | -383.0310 |
11 | CA-2014-115812 | 2014-06-09 | 2014-06-09 | Standardowa, klasa | Standardowa, klasa | Brosina Hoffman | Produkty konsumenckie | Stany Zjednoczone | Los Angeles | Kalifornia | 90032 | Zachód | FUR-TA-10001539 | Meble | Tabele | Tabele konferencji prostokątnych chromcraft | 1706.184 | 9 | 0,2 | 85.3092 |
31 | USA-2015-150630 | 2015-09-17 | 2015-09-21 | Standardowa, klasa | TB-21520 | Tracy Blumstein | Produkty konsumenckie | Stany Zjednoczone | Filadelfia | Pensylwania | 19140 | Wschód | OFF-EN-10001509 | Materiały biurowe | Koperty | Wielociągowe koperty krawata | 3.264 | 2 | 0,2 | 1.1016 |
Zdefiniuj te parametry, aby można było używać tego notesu z różnymi zestawami danych:
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
Pobieranie zestawu danych i przekazywanie do usługi Lakehouse
Ten kod pobiera publicznie dostępną wersję zestawu danych, a następnie przechowuje go w usłudze Fabric Lakehouse:
Ważne
Pamiętaj, aby dodać magazyn lakehouse do notesu przed jego uruchomieniem. W przeciwnym razie zostanie wyświetlony błąd.
import os, requests
if not IS_CUSTOM_DATA:
# Download data files into the lakehouse if they're not already there
remote_url = "https://synapseaisolutionsa.blob.core.windows.net/public/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.")
Konfigurowanie śledzenia eksperymentów MLflow
Usługa Microsoft Fabric automatycznie przechwytuje wartości parametrów wejściowych i metryk wyjściowych modelu uczenia maszynowego podczas jego trenowania. Rozszerza to możliwości automatycznego rejestrowania MLflow. Informacje są następnie rejestrowane w obszarze roboczym, gdzie można uzyskać do niego dostęp i zwizualizować je za pomocą interfejsów API platformy MLflow lub odpowiedniego eksperymentu w obszarze roboczym. Aby dowiedzieć się więcej na temat automatycznego rejestrowania, zobacz Automatyczne rejestrowanie w usłudze Microsoft Fabric.
Aby wyłączyć automatyczne rejestrowanie usługi Microsoft Fabric w sesji notesu, wywołaj mlflow.autolog()
i ustaw polecenie disable=True
:
# Set up MLflow for experiment tracking
import mlflow
mlflow.set_experiment(EXPERIMENT_NAME)
mlflow.autolog(disable=True) # Turn off MLflow autologging
Odczytywanie danych pierwotnych z lakehouse
Odczytywanie danych pierwotnych z sekcji Pliki w lakehouse. Dodaj więcej kolumn dla różnych części daty. Te same informacje są używane do tworzenia partycjonowanej tabeli różnicowej. Ponieważ dane pierwotne są przechowywane jako plik programu Excel, należy użyć biblioteki pandas, aby je odczytać:
import pandas as pd
df = pd.read_excel("/lakehouse/default/Files/salesforecast/raw/Superstore.xlsx")
Krok 2. Wykonywanie eksploracyjnej analizy danych
Importowanie bibliotek
Przed rozpoczęciem analizy zaimportuj wymagane biblioteki:
# 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
Wyświetlanie danych pierwotnych
Ręcznie przejrzyj podzbiór danych, aby lepiej zrozumieć sam zestaw danych i użyć display
funkcji do wydrukowania ramki danych. Chart
Ponadto widoki mogą łatwo wizualizować podzestawy zestawu danych.
display(df)
Ten notes koncentruje się głównie na prognozowaniu Furniture
sprzedaży kategorii. Przyspiesza to obliczanie i pomaga pokazać wydajność modelu. Jednak w tym notesie używane są techniki dostosowywalne. Możesz rozszerzyć te techniki, aby przewidzieć sprzedaż innych kategorii produktów.
# Select "Furniture" as the product category
furniture = df.loc[df['Category'] == 'Furniture']
print(furniture['Order Date'].min(), furniture['Order Date'].max())
Wstępne przetwarzanie danych
Rzeczywiste scenariusze biznesowe często muszą przewidywać sprzedaż w trzech różnych kategoriach:
- Określona kategoria produktu
- Określona kategoria klienta
- Określona kombinacja kategorii produktów i kategorii klientów
Najpierw upuść niepotrzebne kolumny, aby wstępnie przetworzyć dane. Niektóre kolumny (Row ID
, Order ID
,Customer ID
i Customer Name
) są niepotrzebne, ponieważ nie mają wpływu. Chcemy prognozować ogólną sprzedaż w całym stanie i regionie dla określonej kategorii produktów (Furniture
), abyśmy mogli usunąć State
kolumny , , Region
Country
, City
, i Postal Code
. Aby prognozować sprzedaż dla określonej lokalizacji lub kategorii, może być konieczne odpowiednie dostosowanie kroku przetwarzania wstępnego.
# 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()
Zestaw danych jest codziennie ustrukturyzowany. Musimy ponownie użyć kolumny Order Date
, ponieważ chcemy opracować model prognozowania sprzedaży co miesiąc.
Najpierw pogrupuj kategorię Furniture
według Order Date
. Następnie oblicz sumę Sales
kolumny dla każdej grupy, aby określić łączną sprzedaż dla każdej unikatowej Order Date
wartości. Zmień próbkowanie kolumny Sales
z częstotliwością MS
, aby agregować dane według miesięcy. Na koniec oblicz średnią wartość sprzedaży dla każdego miesiąca.
# 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()
Zademonstrowanie wpływu Order Date
na Sales
kategorię Furniture
:
# Impact of order date on the sales
y.plot(figsize=(12, 3))
plt.show()
Przed rozpoczęciem analizy statystycznej statsmodels
należy zaimportować moduł języka Python. Udostępnia klasy i funkcje do szacowania wielu modeli statystycznych. Udostępnia również klasy i funkcje do przeprowadzania testów statystycznych i eksploracji danych statystycznych.
import statsmodels.api as sm
Przeprowadzanie analizy statystycznej
Szereg czasowy śledzi te elementy danych w ustalonych odstępach czasu, aby określić odmianę tych elementów we wzorcu szeregów czasowych:
Poziom: podstawowy składnik reprezentujący średnią wartość dla określonego okresu
Trend: opisuje, czy szereg czasowy zmniejsza się, pozostaje stały, czy zwiększa się w czasie
Sezonowość: opisuje okresowy sygnał w szeregach czasowych i wyszukuje cykliczne wystąpienia wpływające na rosnące lub malejące wzorce szeregów czasowych
Szum/reszty: odnosi się do losowych wahań i zmienności danych szeregów czasowych, których model nie może wyjaśnić.
W tym kodzie obserwujesz te elementy dla zestawu danych po wstępnym przetwarzaniu:
# 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()
Wykresy opisują sezonowość, trendy i szumy w danych prognozowania. Możesz przechwytywać podstawowe wzorce i opracowywać modele, które tworzą dokładne przewidywania odporne na losowe wahania.
Krok 3. Trenowanie i śledzenie modelu
Teraz, gdy masz dostępne dane, zdefiniuj model prognozowania. W tym notesie zastosuj model prognozowania o nazwie sezonowa automatyczna zintegrowana średnia ruchoma z czynnikami egzogennymi (SARIMAX). SARIMAX łączy składniki autoregresywne (AR) i średniej ruchomej (MA), sezonowe różnice i zewnętrzne predyktory, aby zapewnić dokładne i elastyczne prognozy dla danych szeregów czasowych.
Do śledzenia eksperymentów używa się również automatycznego rejestrowania MLflow i sieci szkieletowej. Tutaj załaduj tabelę delty z lakehouse. Możesz użyć innych tabel różnicowych, które uważają lakehouse za źródło.
# Import required libraries for model evaluation
from sklearn.metrics import mean_squared_error, mean_absolute_percentage_error
Dostrajanie hiperparametrów
SARIMAX uwzględnia parametry związane z regularnym automatycznym trybem zintegrowanej średniej ruchomej (ARIMA) (, , ) i dodaje parametry sezonowości (P
, D
, , Q
s
). q
d
p
Te argumenty modelu SARIMAX są nazywane kolejnością (, d
, q
) i kolejnością sezonową (P
p
, D
, Q
, s
), odpowiednio. W związku z tym, aby wytrenować model, musimy najpierw dostroić siedem parametrów.
Parametry zamówienia:
p
: Kolejność składnika AR reprezentująca liczbę wcześniejszych obserwacji w szeregach czasowych używanych do przewidywania bieżącej wartości.Zazwyczaj ten parametr powinien być nieujemną liczbą całkowitą. Wspólne wartości znajdują się w zakresie
0
od do3
, chociaż wyższe wartości są możliwe, w zależności od określonych cech danych. Wyższap
wartość wskazuje dłuższą pamięć poprzednich wartości w modelu.d
: Kolejność różnicowa, reprezentująca liczbę razy, w których szeregi czasowe muszą być różnicowane, aby osiągnąć nieruchomość.Ten parametr powinien być nieujemną liczbą całkowitą. Typowe wartości należą do zakresu
0
od .2
Wartośćd
oznacza, że szereg czasowy0
jest już nieruchomy. Wyższe wartości wskazują liczbę operacji różnicowych wymaganych do jej stacjonowania.q
: kolejność składnika MA reprezentująca liczbę poprzednich terminów błędu białego szumu używanych do przewidywania bieżącej wartości.Ten parametr powinien być nieujemną liczbą całkowitą. Typowe wartości znajdują się w zakresie
0
od do3
, ale wyższe wartości mogą być konieczne w przypadku niektórych szeregów czasowych. Wyższa wartość wskazuje silniejsząq
zależność od poprzednich terminów błędów w celu przewidywania.
Parametry zamówienia sezonowego:
P
: Kolejność sezonowa składnika AR, podobna dop
, ale dla części sezonowejD
: Sezonowa kolejność różnic, podobna dod
, ale dla części sezonowejQ
: Kolejność sezonowa składnika MA podobna doq
kolejności sezonowejs
: liczba kroków czasu na cykl sezonowy (na przykład 12 dla danych miesięcznych z sezonowością roczną)
# 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 ma inne parametry:
enforce_stationarity
: Czy model powinien wymuszać stacjonarność danych szeregów czasowych przed dopasowaniem modelu SARIMAX.Jeśli
enforce_stationarity
ustawionoTrue
wartość (wartość domyślna), oznacza to, że model SARIMAX powinien wymuszać nieruchomość na danych szeregów czasowych. Następnie model SARIMAX automatycznie stosuje różnice w danych, aby były nieruchome, zgodnie zd
wymaganiami iD
, przed dopasowaniem modelu. Jest to powszechna praktyka, ponieważ wiele modeli szeregów czasowych, w tym SARIMAX, zakłada, że dane są nieruchome.W przypadku niestacjonarnych szeregów czasowych (na przykład wykazuje trendy lub sezonowość), dobrym rozwiązaniem jest ustawienie
enforce_stationarity
True
wartości , a model SARIMAX obsłuży różnice w celu osiągnięcia nieruchomości. W przypadku nieruchomych szeregów czasowych (na przykład bez trendów lub sezonowości) należy ustawić takenforce_stationarity
, abyFalse
uniknąć niepotrzebnych różnic.enforce_invertibility
: określa, czy model powinien wymuszać niewzgodność z szacowanych parametrów podczas procesu optymalizacji.Jeśli
enforce_invertibility
jest ustawiona wartośćTrue
(wartość domyślna), oznacza to, że model SARIMAX powinien wymuszać niewzmierność na szacowanych parametrach. Niewzrócenie gwarantuje, że model jest dobrze zdefiniowany, oraz że szacowane współczynniki AR i MA lądują w zakresie nieruchomości.Wymuszanie odwracalności pomaga zapewnić, że model SARIMAX jest zgodny z teoretycznymi wymaganiami dotyczącymi stabilnego modelu szeregów czasowych. Pomaga również zapobiegać problemom z szacowaniem modelu i stabilnością.
Wartość domyślna AR(1)
to model. Odnosi się to do .(1, 0, 0)
Typowym rozwiązaniem jest jednak wypróbowanie różnych kombinacji parametrów zamówienia i parametrów zamówienia sezonowego oraz ocena wydajności modelu dla zestawu danych. Odpowiednie wartości mogą się różnić od jednej serii czasowej do innej.
Określenie optymalnych wartości często obejmuje analizę funkcji autokorelacji (ACF) i częściowej funkcji autokorelacji (PACF) danych szeregów czasowych. Często wiąże się to również z zastosowaniem kryteriów wyboru modelu — na przykład kryterium informacyjnego Akaike (AIC) lub kryterium informacyjnego Bayesa (BIC).
Dostrajanie hiperparametrów:
# 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
Po dokonaniu oceny powyższych wyników można określić wartości zarówno parametrów zamówienia, jak i parametrów zamówienia sezonowego. Wybór to order=(0, 1, 1)
i seasonal_order=(0, 1, 1, 12)
, które oferują najniższą AIC (na przykład 279,58). Użyj tych wartości, aby wytrenować model.
Szkolenie modelu
# 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])
Ten kod wizualizuje prognozę szeregów czasowych dla danych sprzedaży mebli. Nakreślone wyniki pokazują zarówno obserwowane dane, jak i prognozę z jednym krokiem z cieniowanym regionem dla interwału ufności.
# 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)
Użyj predictions
polecenia , aby ocenić wydajność modelu, kontrastując z rzeczywistymi wartościami. Wartość predictions_future
wskazuje przyszłe prognozowanie.
# 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)
Krok 4. Generowanie wyników modelu i zapisywanie przewidywań
Zintegruj rzeczywiste wartości z prognozowanymi wartościami, aby utworzyć raport usługi Power BI. Zapisz te wyniki w tabeli w 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}")
Krok 5. Wizualizowanie w usłudze Power BI
Raport usługi Power BI przedstawia średni bezwzględny błąd procentowy (MAPE) 16,58. Metryka MAPE definiuje dokładność metody prognozowania. Reprezentuje dokładność prognozowanych ilości, w porównaniu z rzeczywistymi ilościami.
MAPE to prosta metryka. 10% MAPE oznacza, że odchylenie średnie między prognozowanych wartości a wartościami rzeczywistymi wynosi 10%, niezależnie od tego, czy odchylenie było dodatnie, czy ujemne. Standardy pożądanych wartości MAPE różnią się w różnych branżach.
Jasnoniebieska linia na tym wykresie reprezentuje rzeczywiste wartości sprzedaży. Ciemnoniebieska linia reprezentuje prognozowane wartości sprzedaży. Porównanie rzeczywistej i prognozowanej sprzedaży pokazuje, że model skutecznie przewiduje sprzedaż dla Furniture
kategorii w ciągu pierwszych sześciu miesięcy 2023 r.
Na podstawie tej obserwacji możemy mieć pewność, że możliwości prognozowania modelu są oparte na ogólnej sprzedaży w ciągu ostatnich sześciu miesięcy 2023 r. i rozszerzają się na rok 2024. To zaufanie może informować o strategicznych decyzjach dotyczących zarządzania zapasami, zaopatrzenia w surowce i innych zagadnień związanych z działalnością biznesową.