Bekerja dengan objek peramalan

Merancang Pipeline Peramalan untuk Produksi

Rami Krispin

Senior Manager, Data Science and Engineering

Bekerja dengan objek peramalan

  • Persiapan data
  • Melatih dan menguji beberapa model peramalan
  • Evaluasi kinerja model
  • Paket statsforecast
    • mlforecast di latihan
Merancang Pipeline Peramalan untuk Produksi

Partition Latih

Deret Waktu

Partition Uji

Partition Uji

Merancang Pipeline Peramalan untuk Produksi

Pustaka yang diperlukan

import pandas as pd 
import datetime 
Merancang Pipeline Peramalan untuk Produksi

Pustaka yang diperlukan

from statsforecast import StatsForecast

from statsforecast.models import (
    DynamicOptimizedTheta,
    SeasonalNaive,
    AutoARIMA,
    HoltWinters,
    MSTL
)

from utilsforecast.plotting import plot_series
Merancang Pipeline Peramalan untuk Produksi

Format data statsforecast

Format input data:

  1. unique_id - ID deret
  2. ds - cap waktu deret
  3. y - nilai deret
Merancang Pipeline Peramalan untuk Produksi

Persiapan data - memuat data

ts = pd.read_csv("data/data.csv")
ts["ds"] = pd.to_datetime(ts["ds"])
ts = ts.sort_values("ds")
ts = ts[["unique_id", "ds", "y"]]

os.environ['NIXTLA_ID_AS_COL'] = '1'
 unique_id        ds             y
0    1    2022-11-11 23:00:00    456403
1    1    2022-11-12 00:00:00    458842
2    1    2022-11-12 01:00:00    455111
3    1    2022-11-12 02:00:00    448035
4    1    2022-11-12 03:00:00    438165
Merancang Pipeline Peramalan untuk Produksi

Persiapan data - pembagian latih/uji

  • Bagi deret waktu menjadi data latih dan uji
    • menggunakan datetime.timedelta
    • sisakan 72 jam terakhir sebagai data uji
test_length = 72

train_end = end  - datetime.timedelta(hours = test_length)

train = ts[ts["ds"] <= train_end]
test = ts[ts["ds"] > train_end]
Merancang Pipeline Peramalan untuk Produksi

Persiapan data

plot_series(train, engine = "plotly")

Deret Waktu

plot_series(test, engine = "plotly")

Partition Uji

Merancang Pipeline Peramalan untuk Produksi

Peramalan dengan StatsModels

# Inisiasi model dengan musiman per jam
auto_arima = AutoARIMA()
s_naive = SeasonalNaive(season_length=24)
theta =  DynamicOptimizedTheta(season_length=24)

# Inisiasi model dengan musiman per jam dan mingguan mstl1 = MSTL(season_length=[24, 24 * 7], trend_forecaster=AutoARIMA(), alias="MSTL_ARIMA_trend") mstl2 = MSTL(season_length=[24, 24 * 7], trend_forecaster=HoltWinters(), alias="MSTL_Holt_trend")
Merancang Pipeline Peramalan untuk Produksi

Peramalan dengan StatsModels

# Gabungkan model ke dalam daftar
stats_models = [auto_arima, s_naive, theta, mstl1, mstl2]

# Inisiasi objek model sf = StatsForecast( models=stats_models, freq="h", fallback_model = AutoARIMA(), n_jobs= -1)
Merancang Pipeline Peramalan untuk Produksi

Peramalan dengan StatsModels

# Gabungkan model ke dalam daftar
stats_models = [auto_arima, s_naive, theta, mstl1, mstl2]

# Inisiasi objek model sf = StatsForecast( models=stats_models, freq="h", fallback_model = AutoARIMA(), n_jobs= -1)
# Buat peramalan forecast_stats = sf.forecast(df=train, h=72, level=[95])
Merancang Pipeline Peramalan untuk Produksi

Peramalan dengan StatsModels

p = sf.plot(test, forecast_stats, engine = "plotly", level=[95])
p.update_layout(height=400)

Plot Peramalan

Merancang Pipeline Peramalan untuk Produksi

Evaluasi model

def mape(y, yhat):
    mape = mean(abs(y - yhat)/ y) 
    return mape

def rmse(y, yhat):
    rmse = (mean((y - yhat) ** 2 )) ** 0.5
    return rmse

def coverage(y, lower, upper):
    coverage = sum((y <= upper) & (y >= lower)) / len(y)
    return coverage
Merancang Pipeline Peramalan untuk Produksi

Evaluasi model

fc = forecast_stats.merge(test, how="left", on="ds")
fc_performance = None

for i in [str(m) for m in stats_models]:
    m = mape(y = fc["y"], yhat = fc[i])
    r = rmse(y = fc["y"], yhat = fc[i])
    c = coverage(y = fc["y"], lower = fc[i + "-lo-95"], upper = fc[i + "-hi-95"])

perf = {"model": i, "mape": m, "rmse": r, "coverage": c} if fc_performance is None: fc_performance = pd.DataFrame([perf]) else: fc_performance = pd.concat([fc_performance, pd.DataFrame([perf])]) fc_performance.reset_index(drop=True, inplace=True)
Merancang Pipeline Peramalan untuk Produksi

Evaluasi model

print(fc_performance.sort_values("rmse"))
     model                    mape        rmse            coverage
1    SeasonalNaive            0.041340    22410.483959    1.000000
4    MSTL_Holt_trend          0.053939    30201.299395    0.513889
3    MSTL_ARIMA_trend         0.053771    30428.240235    0.666667
2    DynamicOptimizedTheta    0.090566    45189.869437    0.916667
0    AutoARIMA                0.149790    70483.617198    1.000000
Merancang Pipeline Peramalan untuk Produksi

Evaluasi model

print(fc_performance.sort_values("rmse"))
     model                    mape        rmse            coverage
1    SeasonalNaive            0.041340    22410.483959    1.000000
4    MSTL_Holt_trend          0.053939    30201.299395    0.513889
3    MSTL_ARIMA_trend         0.053771    30428.240235    0.666667
2    DynamicOptimizedTheta    0.090566    45189.869437    0.916667
0    AutoARIMA                0.149790    70483.617198    1.000000

Dapatkah kita meningkatkan hasil?

  • Pengaturan berbeda untuk akurasi lebih baik
  • Eksperimen sangat membantu
Merancang Pipeline Peramalan untuk Produksi

Ayo berlatih!

Merancang Pipeline Peramalan untuk Produksi

Preparing Video For Download...