Model-model klasikal deret waktu seperti ARIMA dibangun di atas satu asumsi besar: deret yang dipaskaninya bersifat stationary (stasioner) — rata-rata dan sebarannya tidak berubah sepanjang waktu. Deret penjualan Toko Kopi Kita yang bertren naik jelas melanggar asumsi itu, dan bila kita paksakan, hasilnya bisa menyesatkan. Pada chapter ini kita definisikan stasioneritas dengan tepat, memeriksanya lewat uji sederhana perbandingan statistik awal vs akhir, lalu menstasionerkannya dengan differencing — teknik menghitung selisih antar titik waktu yang akan menjadi huruf “I” pada ARIMA.

Apa itu Stasioneritas #

Deret disebut stasioner bila sifat statistiknya tetap dari waktu ke waktu: rata-ratanya konstan (tidak bertren), variansnya konstan (sebarannya tidak melebar-mengempis), dan polanya berulang secara teratur. Intuisinya sederhana — model yang dilatih pada “dunia” paruh pertama data harus tetap berlaku pada paruh kedua. Bila dunianya bergeser (rata-rata naik karena tren), model lama otomatis kedaluwarsa.

SifatDeret stasionerDeret tidak stasioner
Rata-rataKonstan di semua rentang waktuBergeser (mis. naik karena tren)
VariansKonstanMelebar atau menyempit
Perilaku modelSatu model cukup untuk semua periodeModel perlu pembaruan terus-menerus
ContohNoise di sekitar 50 gelasPenjualan bertren naik 40 → 70 gelas

Mengapa asumsi ini penting? Banyak model klasikal — AR, MA, ARIMA — pada dasarnya adalah regresi yang memakai nilai lampau untuk menjelaskan nilai kini. Hubungan seperti itu hanya stabil bila “titik diam” deret tidak berpindah; tren yang merambat membuat koefisien-koefisien model menangkap pergeseran level, bukan mekanisme sesungguhnya. Praktikumnya dua langkah: periksa dulu, lalu stabilkan bila perlu.

Uji Sederhana: Bandingkan Paruh Awal dengan Paruh Akhir #

Cara pemeriksaan paling jujur dan mudah dijelaskan adalah membelah deret jadi dua paruh, lalu membandingkan rata-rata dan simpangan bakunya. Pada deret stasioner, kedua paruh akan menampilkan statistik yang mirip. Kita bandingkan dua deret sekaligus: deret A yang murni noise di sekitar angka 50, dan deret B yang bertren naik seperti penjualan kopi kita.

python
import numpy as np
import pandas as pd

rng = np.random.default_rng(42)
n = 42
tanggal = pd.date_range("2025-01-06", periods=n, freq="D")

deret_a = pd.Series(50 + rng.normal(0, 4.0, n), index=tanggal, name="stasioner")

bobot_hari = np.array([0, 1, 2, 3, 8, 14, 11], dtype=float)
gelas = 40 + 0.6 * np.arange(n) + bobot_hari[tanggal.dayofweek] + rng.normal(0, 4.0, n)
deret_b = pd.Series(gelas.round().astype(int), index=tanggal, name="bertren")

def bandingkan(deret):
    setengah = len(deret) // 2
    awal = deret.iloc[:setengah]
    akhir = deret.iloc[setengah:]
    return round(awal.mean(), 1), round(akhir.mean(), 1), round(awal.std(), 1), round(akhir.std(), 1)

for deret in (deret_a, deret_b):
    m_awal, m_akhir, s_awal, s_akhir = bandingkan(deret)
    print(f"{deret.name:10s} | rata-rata {m_awal:5.1f} -> {m_akhir:5.1f} | simpangan {s_awal:4.1f} -> {s_akhir:4.1f}")

Output yang Dihasilkan:

text
stasioner  | rata-rata  49.8 ->  50.7 | simpangan  3.4 ->  3.2
bertren    | rata-rata  51.4 ->  64.1 | simpangan  7.3 ->  7.6

Mari kita baca hasilnya:

  1. deret_a adalah noise murni: rata-rata paruh awal 49,8 berhadapan dengan 50,7 di paruh akhir — selisih 0,9 gelas, wajar untuk noise setara simpangan 3-4 gelas. Deret ini stasioner.
  2. deret_b (penjualan kopi kita) memperlihatkan rata-rata yang bergeser dari 51,4 ke 64,1 — selisih hampir 13 gelas. Rata-rata yang berpindah itulah tanda tidak stasioner yang paling sering dijumpai.
  3. Simpangan baku kedua deret relatif stabil (7,3 vs 7,6), jadi masalah deret B terkonsentrasi pada rata-rata, bukan sebaran — kabar baik, karena tren justru komponen yang paling gampang diatasi.
  4. Fungsi bandingkan() mengembalikan empat angka per deret dengan iloc sebagai pemotong paruh; // memastikan potongan berupa bilangan bulat.

Pemeriksaan dua-paruh seperti ini memang kasar; uji formal yang lazim dipakai praktisi adalah Augmented Dickey-Fuller (fungsi adfuller pada statsmodels) yang menguji hipotesis “deret tidak stasioner” lewat regresi. Namun untuk data sekecil 42 titik, memahami angka mentahnya lebih penting daripada menyalakan kotak hitam — dan logika bakunya tetap sama: statistik paruh awal harus mewakili paruh akhir.

Differencing: Menstasionerkan dengan Selisih #

Bila ketidakstasioneran bersumber dari tren, obatnya adalah differencing satu langkah: kurangkan tiap nilai dengan nilai sebelumnya (diff()). Untuk tren linear seperti milik kita, selisih harian berkisar di sekitar 0,6 gelas — konstan — sehingga deret selisihnya stasioner dalam rata-rata.

python
import numpy as np
import pandas as pd

rng = np.random.default_rng(42)
n = 42
tanggal = pd.date_range("2025-01-06", periods=n, freq="D")
bobot_hari = np.array([0, 1, 2, 3, 8, 14, 11], dtype=float)
gelas = 40 + 0.6 * np.arange(n) + bobot_hari[tanggal.dayofweek] + rng.normal(0, 4.0, n)
deret = pd.Series(gelas.round().astype(int), index=tanggal, name="gelas")

selisih = deret.diff().dropna()
print("Lima nilai selisih pertama:", selisih.head(5).tolist())

setengah = len(selisih) // 2
m_awal = selisih.iloc[:setengah].mean()
m_akhir = selisih.iloc[setengah:].mean()
print(f"Rata-rata selisih paruh awal : {m_awal:.2f}")
print(f"Rata-rata selisih paruh akhir: {m_akhir:.2f}")
print(f"Korelasi lag-1 selisih       : {selisih.corr(selisih.shift(1)):.3f}")

Output yang Dihasilkan:

text
Lima nilai selisih pertama: [-4.0, 9.0, 3.0, -6.0, 9.0]
Rata-rata selisih paruh awal : 1.05
Rata-rata selisih paruh akhir: 0.76
Korelasi lag-1 selisih       : -0.113

Mari kita telaah baris-baris kode di atas:

  1. deret.diff() menghitung y_t - y_{t-1} untuk semua titik; titik pertama tidak punya pendahulu sehingga menjadi NaN dan dibuang dropna(). Lima selisih pertama (-4, 9, 3, …) memperlihatkan angka yang berayun di sekitar nol — persis perilaku deret stasioner.
  2. Rata-rata paruh awal 1,05 vs akhir 0,76 kini hampir setara — pergeseran 13 gelas tadi berubah menjadi selisih kurang dari 0,3. Tren berhasil diluruhkan; keduanya mendekati 0,6 gelas/hari yang kita tanam, dengan sisa deviasi tipikal dari noise.
  3. Korelasi lag-1 yang mendekati nol (-0,113) menandakan selisih harian sudah nyaris tidak berhubungan dengan selisih sebelumnya — tidak ada struktur tren yang tersisa untuk dimanfaatkan model.

Rangkuman #

  • Stasioner berarti rata-rata dan varians konstan sepanjang waktu; model klasikal deret waktu mengasumsikannya.
  • Uji dua-paruh (bandingkan rata-rata dan simpangan awal vs akhir) adalah pemeriksaan cepat yang mudah ditafsirkan; uji formalnya adalah Augmented Dickey-Fuller.
  • Differencing diff() mengubah deret bertren menjadi deret selisih yang stasioner; diff(7) menangani musiman mingguan.
  • Setelah menstasionerkan, jangan lupa: kita menganalisis selisih, bukan nilai aslinya — model ARIMA nanti akan membalik proses ini untuk mengembalikan hasil ke satuan gelas.

Stasioneritas memberi kita deret yang “tenang” untuk dimodelkan. Tetapi sebelum melompat ke model, ada satu teknik pemisahan pola yang lebih jernih lagi: memecah deret menjadi komponen tren, musiman, dan sisa secara serentak — materi chapter Dekomposisi Deret Waktu .

Referensi #

  1. statsmodels — Time Series Analysis (tsa)
  2. NumPy — The absolute basics for beginners