Chapter Moving Average ditutup dengan dua keluhan: bobot yang sama untuk seluruh isi jendela terasa kasar karena data terbaru umumnya lebih relevan, dan lebar jendela k mengendalikan pertukaran kehalusan-lawan-lag secara serba kasar. Simple exponential smoothing (SES) menjawab kedua keluhan itu sekaligus: seluruh riwayat deret ikut dihitung, bobotnya menurun secara geometris mengikuti usia data, dan satu parameter α mengendalikan seberapa cepat bobot itu menurun. SES paling tepat untuk deret yang hanya bergerak di sekitar level tetap — tanpa tren, tanpa musiman — sehingga satu angka level yang terus diperbarui sudah memadai sebagai prediksi. Chapter ini menghitung bobot eksponensial tersebut, mengerjakan rekursinya dengan tangan pada penjualan kopi sebuah warung, menyetel α, lalu menguji batas jujur alat ini pada harga beras yang bertren.

Bobot yang Menurun secara Eksponensial #

Moving average memberi bobot 1/k kepada seluruh observasi di dalam jendela dan bobot nol kepada observasi di luarnya — pemotongan tajam yang membuang informasi riwayat panjang. SES mengganti pemotongan itu dengan barisan bobot yang menurun secara geometris. Observasi yang berumur k periode memperoleh bobot:

text
w(k) = α × (1 − α)^k

w(0) = α                  bobot observasi terkini
w(1) = α × (1 − α)        bobot observasi satu periode sebelumnya
w(2) = α × (1 − α)²       dua periode sebelumnya, dan seterusnya

Barisan inilah alasan nama “exponential”: bobot menurun mengikuti pangkat (1 − α), dan jumlah seluruh barisan tak hingga tepat 1. Tabel berikut memperlihatkan bobot nyata untuk α = 0.3:

Usia observasiBobotBobot kumulatif
terkini (k = 0)0.30000.3000
1 periode lalu0.21000.5100
2 periode lalu0.14700.6570
3 periode lalu0.10290.7599
4 periode lalu0.07200.8319
5 periode lalu0.05040.8824
6 periode lalu0.03530.9176
lebih tua0.08241.0000

Angka pada tabel dibulatkan ke empat desimal. Dengan α = 0.3, tujuh observasi terbaru menyerap 91.76 persen bobot; MA(7) memberi nol persen kepada seluruh riwayat lama, sedangkan SES hanya mengecilkan pengaruhnya. Parameter α juga menentukan panjang memori: α = 0.1 membuat sepuluh observasi terbaru hanya menyerap 65.13 persen bobot (1 − 0.9¹⁰), sedangkan α = 0.7 membuat tiga observasi terbaru menyerap 97.30 persen (1 − 0.3³). Pembahasan formal keluarga exponential smoothing tersedia pada NIST/SEMATECH e-Handbook .

Rekursi Level dan Inisialisasi #

Menghitung rata-rata terbobot seluruh riwayat pada setiap periode terasa mahal, tetapi SES mengerjakannya dengan satu baris perhitungan berulang (rekursi). Level deret pada periode t diperbarui menurut:

text
Lt = α × Yt + (1 − α) × Lt-1

ŷt+1 = Lt

Rumus pertama dibaca sebagai percampuran: level baru adalah α bagian observasi baru ditambah (1 − α) bagian level lama, sehingga gejolak satu periode tidak serta-merta memindahkan prediksi. Prediksi periode berikutnya adalah level itu sendiri; forecast SES berupa angka tunggal yang sama untuk semua horizon karena model tidak menyimpan arah.

Rekursi membutuhkan satu nilai awal; pilihan paling sederhana adalah L1 = Y1, alternatif yang lazim adalah mean beberapa observasi awal. Dampak pilihan ini mengecil seiring bertambahnya data, karena bobot yang menempel pada nilai awal terus dikali (1 − α) setiap periode.

Bentuk rekursi dan bentuk rata-rata terbobot identik — rekursi yang dibuka untaian demi untaian menghasilkan jumlah tertimbang seluruh observasi dan nilai awal:

text
Lt = α × Yt + α(1 − α) × Yt-1 + α(1 − α)² × Yt-2 + ...
     + α(1 − α)^(t-2) × Y2 + (1 − α)^(t-1) × L1

Komputer cukup menyimpan satu angka (level terkini), bukan seluruh deret; bobot pada bentuk terbobot persis barisan w(k), dan sisa bobot (1 − α)^(t-1) jatuh ke nilai awal L1.

Contoh Manual: Penjualan Kopi Warung #

Deret latihan kita adalah penjualan kopi sebuah warung selama sepuluh minggu (data fiktif), dalam gelas per minggu:

Minggu12345678910
Penjualan205192200185210193215188202210

Penjualan naik-turun di sekitar mean 200 gelas, dan slope regresi waktunya hanya 0.78 gelas per minggu — deret nyaris datar, kandidat ideal SES. Kita kerjakan dua versi sekaligus, α = 0.3 dan α = 0.7, dengan inisialisasi L1 = Y1 = 205. Tiga langkah pertama dihitung terbuka (nilai penuh dibawa sepanjang perhitungan; tampilan dibulatkan ke dua desimal):

text
alpha = 0.3:
L2 = 0.3 × 192 + 0.7 × 205   = 57.6 + 143.5   = 201.10
L3 = 0.3 × 200 + 0.7 × 201.10 = 60.0 + 140.77 = 200.77
L4 = 0.3 × 185 + 0.7 × 200.77 = 55.5 + 140.54 = 196.04

alpha = 0.7:
L2 = 0.7 × 192 + 0.3 × 205   = 134.4 + 61.5   = 195.90
L3 = 0.7 × 200 + 0.3 × 195.90 = 140.0 + 58.77 = 198.77

Bentuk terbobot dapat diperiksa langsung: L3 versi α = 0.3 sama dengan 0.3 × 200 + 0.21 × 192 + 0.49 × 205 = 60 + 40.32 + 100.45 = 200.77 — identik dengan hasil rekursi. Tabel kerja lengkap sepuluh minggu:

text
t     Yt      L (alpha=0.3)   L (alpha=0.7)
1     205     205.00          205.00
2     192     201.10          195.90
3     200     200.77          198.77
4     185     196.04          189.13
5     210     200.23          203.74
6     193     198.06          196.22
7     215     203.14          209.37
8     188     198.60          194.41
9     202     199.62          199.72
10    210     202.73          206.92

forecast minggu 11 = L10:  alpha=0.3 -> 202.73,  alpha=0.7 -> 206.92

Dua kolom level menampilkan dua karakter. Lonjakan minggu ke-7 (215 gelas) menggeser level α = 0.3 sebesar 5.08 gelas, tetapi menggeser level α = 0.7 sebesar 13.14 gelas — α besar merespons cepat, α kecil meredam. Di ujung deret, forecast α = 0.7 sebesar 206.92 menempel pada dua minggu terakhir yang naik (202, 210), sedangkan forecast α = 0.3 sebesar 202.73 lebih dekat ke level jangka panjang 200.

Menyetel Alpha: Kehalusan versus Kecepatan #

Parameter α mengatur pertukaran kehalusan lawan kecepatan respons — pertukaran yang sama dengan lebar jendela k pada moving average, tetapi dengan kendali kontinu. Akibat pilihan α diukur dengan MAE prediksi satu-langkah seluruh deret kopi (definisi MAE mengikuti chapter Evaluasi Forecast):

text
MAE satu-langkah pada kopi:
alpha = 0.1  ->  10.06
alpha = 0.3  ->  10.77
alpha = 0.7  ->  13.39
alpha = 1.0  ->  16.56   (identik naive forecast)

Pada deret datar seperti kopi, perata lebih kuat menang: α = 0.1 dan α = 0.3 mengalahkan α = 0.7, dan semua mengalahkan α = 1. Kasus α = 1 layak disorot: rumus rekursi runtuh menjadi Lt = Yt, sehingga prediksi selalu menyalin observasi terakhir — persis naive forecast ŷt = Yt-1 yang diadu pada chapter Evaluasi Forecast. SES adalah perumuman naive: α = 1 memberi naive, α mengecil menempelkan prediksi pada mean riwayat.

SES dengan statsmodels #

Pustaka statsmodels menyediakan SES melalui kelas SimpleExpSmoothing (dokumentasi di statsmodels.org ). Cuplikan berikut memasang α = 0.3 yang sama dengan hitungan manual, lalu membandingkan hasilnya:

python
import numpy as np
from statsmodels.tsa.holtwinters import SimpleExpSmoothing

kopi = np.asarray([205, 192, 200, 185, 210, 193, 215, 188, 202, 210],
                  dtype=float)

L = kopi[0]  # rekursi manual: inisialisasi L1 = Y1 = 205
for yt in kopi[1:]:
    L = 0.3 * yt + 0.7 * L

hasil = SimpleExpSmoothing(kopi, initialization_method="estimated").fit(  # alpha sama, inisialisasi ditaksir dari data
    smoothing_level=0.3, optimized=False)

print(f"forecast manual        : {L:.2f}")
print(f"level awal statsmodels : {hasil.params['initial_level']:.2f}")
print(f"forecast statsmodels   : {hasil.forecast(1)[0]:.2f}")
print(f"selisih keduanya       : {abs(L - hasil.forecast(1)[0]):.2f}")

Output yang Dihasilkan:

text
forecast manual        : 202.73
level awal statsmodels : 195.73
forecast statsmodels   : 202.47
selisih keduanya       : 0.26

Mari kita bedah kode di atas:

  1. Baris 7-9 (loop manual): rekursi L1 = Y1 dikerjakan ulang untuk pembanding; setelah loop selesai, L menyimpan L10.
  2. Baris 12-13 (SimpleExpSmoothing dan fit): argumen smoothing_level=0.3 mematok α dan optimized=False mematikan optimasi, sehingga hasil selalu sama setiap dijalankan.
  3. Baris 15-18 (empat baris cetak): forecast manual dan forecast statsmodels berselisih 0.26 gelas — kecil, tetapi bukan nol.

Sumber selisihnya satu: inisialisasi. Rekursi manual memulai dari L1 = Y1 = 205, sedangkan statsmodels menaksir level awal lewat regresi waktu pada sepuluh observasi pertama; intercept regresi kopi adalah 195.73. Selisih titik berangkat 9.27 gelas menyusut menjadi 0.26 gelas karena bobot inisialisasi terus tergerus faktor (1 − α) tiap minggu. Pada deret cukup panjang, pilihan inisialisasi nyaris tak berpengaruh; pada deret pendek pengaruhnya terasa, jadi sebutkan inisialisasi yang dipakai saat melaporkan hasil.

Batas Jujur: Deret yang Bertren #

SES hanya menyimpan level, sehingga deret yang bergerak searah berada di luar wilayah kerjanya. Ujilah langsung pada dua belas bulan harga beras — deret dengan slope 181.82 Rp per bulan dari chapter Tren dan Musiman:

python
beras = [12500, 12800, 12700, 13100, 13400, 13300,
         13600, 13900, 13800, 14200, 14500, 14400]

alpha = 0.3
L = beras[0]
error = []
for t in range(1, len(beras)):
    error.append(beras[t] - L)   # forecast bulan t = L sebelum pembaruan
    L = alpha * beras[t] + (1 - alpha) * L

print(f"error prediksi Des : {error[-1]:.2f}")
print(f"error bertanda +   : {sum(e > 0 for e in error)} dari {len(error)}")
print(f"forecast SES t=13  : {L:.2f}")
print(f"regresi tren t=13  : 14698.48")  # chapter Tren dan Musiman
print(f"jarak SES ke tren  : {14698.48 - L:.2f}")

Output yang Dihasilkan:

text
error prediksi Des : 434.59
error bertanda +   : 11 dari 11
forecast SES t=13  : 14095.79
regresi tren t=13  : 14698.48
jarak SES ke tren  : 602.69

Mari kita bedah kode di atas:

  1. Baris 5-9 (loop): setiap bulan, level lama menjadi forecast, error dicatat, lalu level diperbarui — sama persis dengan rekursi kopi, hanya datanya yang bertren.
  2. Baris 11 (error bertanda +): sebelas prediksi satu-langkah dan sebelas error, semuanya positif — aktual selalu berada di atas prediksi.
  3. Baris 13-14 (banding tren): forecast SES untuk Januari (t = 13) sebesar 14095.79 tertinggal 602.69 Rp dari prediksi regresi tren 14698.48.

Error positif sebelas kali berturut-turut bukan kebetulan. Pada deret berslope b, level SES tertinggal dengan jarak stabil di sekitar b × (1 − α) / α — untuk beras, 181.82 × 0.7 / 0.3 ≈ 424.25 Rp, dan error Des sebesar 434.59 berdiam di dekat angka itu. Menaikkan α hanya memperkecil ketertinggalan: α = 0.7 memangkas jarak menjadi 181.82 × 0.3 / 0.7 ≈ 77.92 Rp dan forecast t = 13 naik ke 14392.06 — tetap di bawah arah data; hanya α = 1 yang menghapusnya, dan α = 1 bukan lagi smoothing melainkan naive. Chapter Evaluasi Forecast mengajarkan bahwa barisan error yang berpola menandai model kehilangan struktur; polanya di sini satu tanda, dan strukturnya bernama tren.

Kapan Memakai SES #

SES tepat bila deret berperilaku seperti kopi warung kita: level kira-kira tetap, gejolak tanpa arah, tanpa pola musiman berperiode tetap. Deret demikian mendekati deret stasioner — konsep dari chapter Pengenalan Time Series saat mean paruh awal dan paruh akhir beras kita bandingkan. Sebaliknya, bila mean deret bergerak searah, SES tertinggal seperti pada beras dan komponen tren wajib ikut dimodelkan.

Tiga pertimbangan praktis memperkuat posisi SES: hanya satu parameter sehingga layak pada deret pendek; rekursinya murah dan mudah diperbarui setiap data tiba; dan SES menjadi baseline pembanding yang jujur — model rumit wajib mengalahkannya sebelum kerumitannya layak dibayar, persis semangat pembandingan dengan naive pada chapter Evaluasi Forecast. Bila data berpindah level mendadak namun tetap tanpa arah, naikkan α; bila muncul arah yang konsisten, saatnya menambahkan komponen slope — tugas yang dikerjakan Holt pada chapter berikutnya.