Baseline Peramalan

Baseline naive dan seasonal naive serta alasan keduanya sulit dikalahkan.

Daftar isi

Peramalan yang rumit baru bermakna apabila dibandingkan dengan titik acuan yang sederhana dan tidak berpihak. Topik ini membahas dua baseline peramalan paling dasar, yaitu baseline naive dan baseline seasonal naive, beserta alasan keduanya sulit dikalahkan. Praktiknya meramal 14 hari terakhir dari deret harian sintetis berpola mingguan melalui skrip baseline-naive.py, lengkap dengan gambar perbandingan yang disimpan ke berkas gambar-baseline.png.

Baseline naive dan seasonal naive#

Baseline naive meramal masa depan dengan satu nilai terakhir yang teramati. Apabila data berhenti pada hari TT, peramalan untuk semua horizon hh, yaitu jarak langkah ke depan dari titik peramalan, ditulis sebagai berikut.

y^T+h=yT \hat{y}_{T+h} = y_{T}

Baseline seasonal naive memperbaiki kelemahan rumus itu pada deret berpola berulang dengan meminjam nilai dari satu periode sebelumnya. Untuk deret harian dengan pola mingguan berperiode m=7m = 7, peramalannya ditulis sebagai berikut.

y^T+h=yT+h−m \hat{y}_{T+h} = y_{T+h-m}

Kedua baseline tidak memiliki parameter yang perlu disesuaikan, sehingga keduanya dihitung dalam satu baris kode dan hasilnya selalu sama pada data yang sama. Kesederhanaan itu justru sumber kekuatannya. Baseline naive menangkap level, yaitu nilai dasar terkini deret, sedangkan baseline seasonal naive menangkap level dan pola musiman sekaligus. Kedua sinyal itu sering menyumbang porsi terbesar dari variasi sebuah deret operasional. Model kandidat apa pun dengan demikian menghadapi ambang yang sudah tinggi sejak awal.

Pilihan antara keduanya mengikuti struktur deret yang dihadapi. Baseline naive menjadi titik acuan untuk deret yang tidak menunjukkan pola berulang yang jelas, misalnya catatan suhu ruangan tanpa siklus harian. Pada deret semacam itu, nilai terakhir merupakan tebakan terbaik yang dapat diberikan oleh satu angka saja. Baseline seasonal naive dipilih apabila pola berulang terlihat pada periode tetap, baik harian, mingguan, maupun tahunan. Istilah naive pada keduanya menyatakan ketiadaan proses belajar, bukan kepastian bahwa peramalannya buruk.

Mengukur kedua baseline pada 14 hari terakhir#

Pengukuran mengikuti disiplin pemisahan temporal, yaitu 105 hari pertama menjadi data latih dan 14 hari terakhir menjadi data uji. Ukuran kesalahan yang dipakai adalah MAE (mean absolute error), yaitu rata-rata selisih mutlak antara nilai aktual yy dan nilai ramalan y^\hat{y} sepanjang horizon.

MAE=1h∑i=1h∣yT+i−y^T+i∣ \mathrm{MAE} = \frac{1}{h} \sum_{i=1}^{h} \left| y_{T+i} - \hat{y}_{T+i} \right|

Sebagai pembanding, skrip juga menghitung regresi tren linear, yaitu garis lurus yang dipasangkan terhadap indeks hari. Model ini tampak lebih maju karena melakukan pembelajaran parameter, tetapi tidak diberi komponen musiman. Skrip berikut menghitung ketiga peramalan sekaligus, mencetak MAE masing-masing, lalu menggambar perbandingannya pada 35 hari terakhir.

python baseline-naive.py
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
from sklearn.metrics import mean_absolute_error

# deret harian sintetis 17 pekan: level + tren + musiman mingguan + derau
rng = np.random.default_rng(42)
n = 119
waktu = np.arange(n)
deret = 40 + 0.15 * waktu + 6.0 * np.sin(2 * np.pi * waktu / 7) + rng.normal(0, 2.0, n)

# 14 hari terakhir disisihkan sebagai data uji (protokol temporal)
h = 14
latih, uji = deret[: n - h], deret[n - h :]

# baseline naive: setiap hari uji diprediksi dengan nilai terakhir data latih
pred_naive = np.full(h, latih[-1])

# baseline seasonal naive: nilai pada hari yang sama pekan sebelumnya
pred_musim = deret[n - h - 7 : n - 7]

# pembanding: regresi tren linear tanpa komponen musiman
koef = np.polyfit(waktu[: n - h], latih, 1)
pred_tren = np.polyval(koef, waktu[n - h :])

print(f"MAE baseline naive             : {mean_absolute_error(uji, pred_naive):.3f}")
print(f"MAE baseline seasonal naive    : {mean_absolute_error(uji, pred_musim):.3f}")
print(f"MAE regresi tren tanpa musiman : {mean_absolute_error(uji, pred_tren):.3f}")

# gambar 35 hari terakhir beserta peramalan 14 hari dari kedua baseline
mulai = n - h - 35
fig, ax = plt.subplots(figsize=(7, 4))
ax.plot(waktu[mulai : n - h], deret[mulai : n - h], color="#334155", linewidth=1.2, label="Data latih")
ax.plot(waktu[n - h :], uji, color="#0f766e", marker="o", markersize=3, linewidth=1.2, label="Aktual (data uji)")
ax.plot(waktu[n - h :], pred_naive, color="#b45309", linestyle="--", linewidth=1.5, label="Baseline naive")
ax.plot(waktu[n - h :], pred_musim, color="#7c3aed", linestyle="-.", linewidth=1.5, label="Baseline seasonal naive")
ax.axvline(n - h - 0.5, color="#94a3b8", linestyle=":", linewidth=1)
ax.text(n - h - 1, 68, "asal peramalan", ha="right", fontsize=9, color="#475569")
ax.set_ylim(28, 72)
ax.set_xlabel("Hari ke-")
ax.set_ylabel("Jumlah pengunjung")
ax.set_title("Dua baseline peramalan pada 14 hari terakhir")
ax.legend(loc="upper left", fontsize=9)
fig.tight_layout()
fig.savefig("gambar-baseline.png", dpi=110)
print("Gambar disimpan ke gambar-baseline.png")
text Keluaran
MAE baseline naive             : 7.347
MAE baseline seasonal naive    : 1.484
MAE regresi tren tanpa musiman : 3.336
Gambar disimpan ke gambar-baseline.png

Perbandingan baseline naive dan seasonal naive pada 14 hari terakhir
Perbandingan baseline naive dan seasonal naive pada 14 hari terakhir

MAE baseline naive mencapai 7.347. Nilai terakhir data latih kebetulan berada di lembah pola mingguan, sehingga seluruh 14 hari uji diprediksi dengan angka rendah yang sama. Baseline seasonal naive mengikuti gelombang mingguan dan mencatat MAE 1.484. Regresi tren yang memakai pembelajaran parameter hanya mencatat 3.336, lebih baik daripada naive tetapi tetap kalah dari seasonal naive yang tidak mempelajari parameter apa pun. Pada gambar, garis seasonal naive terlihat nyaris menempel pada kurva aktual, sedangkan garis naive tampak datar dan jauh di bawah kurva aktual. Perbandingan ini menunjukkan bahwa bertambahnya kecanggihan model belum tentu diikuti bertambahnya ketepatan pada data uji.

Satu catatan teknis menyertai rumus seasonal naive. Baseline ini pada dasarnya merupakan peramalan satu langkah, sehingga nilai pekan sebelumnya yang dipinjam untuk hari kedelapan hingga keempat belas memang sudah teramati pada saat peramalan dibuat. Interpretasi itu konsisten dengan pemakaian seasonal naive pada evaluasi berjalan, ketika peramalan baru dibuat setiap hari setelah data hari itu tersedia.

Mengapa baseline sulit dikalahkan#

Kedua baseline tanpa parameter ini sulit dikalahkan karena keduanya memuat sinyal terkuat pada mayoritas deret, yaitu level dan musiman. Sisa variasi setelah kedua sinyal itu diserap umumnya berupa derau yang tidak dapat diramal oleh model apa pun, dan derau itulah yang menetapkan batas bawah kesalahan. Model yang lebih kompleks tidak menambah kemampuan meramal derau, melainkan menambah kerentanan menyesuaikan diri pada derau, kecenderungan yang dikenal sebagai overfitting. Setiap penambahan parameter dengan demikian harus dibayar dengan perbaikan nyata pada data uji, bukan sekadar tampilan yang lebih meyakinkan.

Disiplin perbandingannya sederhana dan tidak boleh dilanggar. Model kandidat dan baseline diukur pada data uji temporal yang sama dengan ukuran kesalahan yang sama, lalu angkanya dilaporkan berdampingan. Kandidat dinyatakan bermanfaat hanya bila MAE-nya lebih rendah daripada kedua baseline, bukan sekadar daripada satu baseline yang lemah.

Pola ini terlihat pada eksperimen sebelumnya. Baseline seasonal naive tidak memiliki parameter, sehingga tidak ada kemampuannya yang terpakai untuk menyesuaikan derau pada data latih, dan kesalahannya nyaris sama pada data latih maupun data uji. Model dengan banyak parameter justru membuka celah di antara kedua skor tersebut, karena sebagian kemampuannya terpakai untuk menyesuaikan derau pada data latih. Semakin banyak parameter yang disesuaikan, semakin lebar celah itu, dan semakin besar pula kebutuhan akan data uji yang bersih untuk membuktikan perbaikannya.

Kesalahan umum#

Kesalahan pada topik ini umumnya terjadi pada cara membandingkan model dengan baseline, bukan pada perhitungan baseline itu sendiri.

  • Membandingkan model dengan baseline pada pemisahan acak. Pemisahan acak menyembunyikan kesulitan ekstrapolasi sehingga kemenangan model menjadi palsu. Seluruh perbandingan dilakukan pada data uji temporal yang menempatkan baseline dan model dalam tugas yang sama.
  • Hanya menyandingkan baseline naive pada deret berpola musiman kuat. Baseline yang tidak sesuai struktur deret terlalu mudah dikalahkan, sehingga laporan perbandingannya memberi kesan berlebihan atas kemampuan model. Baseline seasonal naive ikut disertakan setiap kali pola berulang terlihat.
  • Melaporkan skor data latih sebagai bukti kemenangan atas baseline. Model dengan parameter yang dilatih pada data latih hampir selalu menang di atas data yang sama, dan keunggulan itu tidak berpindah ke data baru. Perbandingan dilaporkan dari skor data uji saja.
  • Memilih titik potong data uji setelah melihat hasil peramalan. Jendela uji yang dipindah-pindah sampai model tampak unggul menyisipkan informasi uji ke dalam keputusan, sehingga perbandingannya menjadi menyesatkan. Titik potong ditetapkan sejak awal, misalnya 14 hari terakhir, lalu dipakai untuk seluruh model.

Ringkasan#

  • Baseline naive menempel pada nilai terakhir yang teramati, sedangkan baseline seasonal naive menyalin nilai dari satu periode sebelumnya.
  • Pada deret sintetis berpola mingguan, MAE seasonal naive sebesar 1.484 mengalahkan naive 7.347 dan regresi tren 3.336.
  • Keduanya sulit dikalahkan karena sudah memuat level dan musiman, dua sinyal terkuat pada kebanyakan deret.
  • Model kandidat baru diterima hanya bila mengalahkan kedua baseline pada data uji temporal yang sama.

Referensi#