Kesan pertama membaca line chart beras adalah “naik terus”, dan kesan pertama membaca tabel es krim kafe adalah “panas laku, hujan sepi”. Keduanya adalah pola, dan pola baru berguna bagi analisis setelah berubah menjadi angka: seberapa cepat tren naik, dan seberapa besar lonjakan musimannya. Chapter ini memasang regresi linear pada sumbu waktu untuk mengukur tren dua belas bulan harga beras, lalu memakai rata-rata per posisi kuartal dan seasonal index untuk mengukur pola musiman dua tahun penjualan es krim. Di ujung chapter kita memisahkan musiman dari siklus dan menyinggung efek kalender yang kerap menggerakkan data Indonesia menjelang hari besar.
Tren: Pergerakan Jangka Panjang #
Tren adalah arah pergerakan jangka panjang sebuah deret — kemiringan yang tersisa setelah gejolak bulanan diabaikan. Deteksi paling sederhana memakai mata: line chart beras pada chapter sebelumnya menampilkan deret yang menanjak dari 12500 ke 14400, dengan penurunan tipis yang selalu berbalik naik pada bulan berikutnya. Tetapi “menanjak” belum menjawab kebutuhan pengelola pasar: bila pola ini berlanjut, berapa tambahan harga yang wajar diantisipasi tiap bulan? Jawaban kuantitatifnya datang dari alat yang sudah kita kuasai — regresi linear, sebagaimana dibahas pada OpenIntro Statistics .
Memasang Garis Tren pada Harga Beras #
Chapter Simple Linear Regression di Section Korelasi dan Regresi memasang garis ŷ = b0 + b1x pada pasangan variabel (x, y). Untuk tren, variabel bebasnya adalah waktu: kita pakai t = 1, 2, …, 12, dan ŷt = b0 + b1 × t menjadi nilai tren pada bulan t. Rumus slope dan intercept sama persis dengan regresi biasa — hanya makna x yang berganti menjadi waktu:
b1 = (n × Σ(t × Yt) − Σt × ΣYt) / (n × Σt² − (Σt)²)
b0 = (ΣYt − b1 × Σt) / nSeluruh penjumlahan yang dibutuhkan untuk dua belas bulan beras:
n = 12 Σt = 78 Σt² = 650
ΣYt = 162200 Σ(t × Yt) = 1080300
b1 = (12 × 1080300 − 78 × 162200) / (12 × 650 − 78²)
= 312000 / 1716
= 2000 / 11
≈ 181.82 (dibulatkan ke dua desimal)
b0 = (162200 − (2000/11) × 78) / 12
= 148018.18 / 12
≈ 12334.85 (dibulatkan ke dua desimal)Slope b1 ≈ 181.82 berarti harga beras naik rata-rata sekitar 182 Rp/kg untuk setiap bulan selama periode data — angka yang jauh lebih informatif daripada kesan “naik terus”. Intercept b0 adalah level dasar garis pada t = 0, dan nilai tren pada Desember adalah b0 + b1 × 12 ≈ 14516.67, hanya 116.67 di atas harga aktual 14400 — selisih kecil yang menandakan garis lurus cukup mewakili pergerakan setahun ini. Model yang sama memperkirakan Januari tahun depan (t = 13) pada kisaran 14698, dengan satu peringatan penting: ekstrapolasi jauh ke depan menempatkan kita di luar jangkauan data, dan tidak ada jaminan tren linear bertahan selamanya.
Perhitungan di atas bisa kita minta langsung dari Python:
beras = [12500, 12800, 12700, 13100, 13400, 13300,
13600, 13900, 13800, 14200, 14500, 14400]
t = list(range(1, 13))
n = len(beras)
st = sum(t)
st2 = sum(x * x for x in t)
sy = sum(beras)
sty = sum(x * y for x, y in zip(t, beras))
b1 = (n * sty - st * sy) / (n * st2 - st * st)
b0 = (sy - b1 * st) / n
print(f"b1 (slope) : {b1:.2f} Rp/kg per bulan")
print(f"b0 (intercept) : {b0:.2f} Rp/kg")
print(f"prediksi t=12 : {b0 + b1 * 12:.2f} Rp/kg")
print(f"prediksi t=13 : {b0 + b1 * 13:.2f} Rp/kg")Output yang Dihasilkan:
b1 (slope) : 181.82 Rp/kg per bulan
b0 (intercept) : 12334.85 Rp/kg
prediksi t=12 : 14516.67 Rp/kg
prediksi t=13 : 14698.48 Rp/kgMari kita bedah kode di atas:
- Baris 7-10 (
st,st2,sy,sty): empat penjumlahan rumus slope — Σt, Σt², ΣYt, dan Σ(t × Yt) — dihitung dengansum()danzip(). - Baris 12-13 (
b1danb0): substitusi menghasilkan b1 = 2000/11 ≈ 181.82 Rp/kg per bulan, nilai yang sama dengan hitungan manual di atas. - Baris 18 (
prediksi t=13): ekstrapolasi satu bulan di luar data menghasilkan 14698.48 — prediksi, bukan pengamatan, sehingga derajat kepercayaannya dibahas pada chapter Evaluasi Forecast.
Musiman: Pola Berulang Periode Tetap #
Musiman adalah pola yang berulang dengan periode tetap dan dapat diketahui sebelumnya — kuartal dalam tahun, bulan dalam tahun, atau hari dalam minggu. Berbeda dari tren yang bergerak searah, musiman naik dan turun mengikuti kalender. Dataset kedua kita adalah penjualan es krim sebuah kafe per kuartal selama dua tahun:
| Kuartal | Tahun 1 (porsi) | Tahun 2 (porsi) | Rata-rata (porsi) |
|---|---|---|---|
| Q1 (Jan-Mar) | 180 | 190 | 185 |
| Q2 (Apr-Jun) | 320 | 335 | 327.5 |
| Q3 (Jul-Sep) | 260 | 275 | 267.5 |
| Q4 (Okt-Des) | 120 | 130 | 125 |
Pola terbaca konsisten pada kedua tahun: penjualan melonjak pada Q2 — awal kemarau saat udara terpanas — lalu melandai pada Q3 dan jatuh ke titik terendah pada Q4 saat musim hujan tiba. Pengukurannya sederhana: rata-rata setiap posisi kuartal. Menjumlahkan dua tahun meniadakan fluktuasi tahunan dan menyisakan bentuk musiman murni, persis seperti rumus mean dari chapter Mean yang kali ini diterapkan per kelompok:
rata-rata Q1 = (180 + 190) / 2 = 185
rata-rata Q2 = (320 + 335) / 2 = 327.5
rata-rata Q3 = (260 + 275) / 2 = 267.5
rata-rata Q4 = (120 + 130) / 2 = 125rata-rata penjualan es krim per kuartal (porsi)
Q1 185.0 ███████
Q2 327.5 █████████████
Q3 267.5 ███████████
Q4 125.0 █████
1 blok = 25 porsi (dibulatkan)Seasonal Index #
Rata-rata per kuartal menjadi lebih bermakna bila dibandingkan dengan rata-rata keseluruhan deret:
indeks musiman Qk = rata-rata kuartal k / rata-rata seluruh dataRata-rata seluruh data es krim adalah 1810 / 8 = 226.25 porsi. Membagi setiap rata-rata kuartal dengan angka tersebut menghasilkan:
| Kuartal | Rata-rata | Indeks musiman | Tafsiran |
|---|---|---|---|
| Q1 | 185 | 0.82 | 18 persen di bawah rata-rata |
| Q2 | 327.5 | 1.45 | 45 persen di atas rata-rata |
| Q3 | 267.5 | 1.18 | 18 persen di atas rata-rata |
| Q4 | 125 | 0.55 | 45 persen di bawah rata-rata |
Indeks 1.45 pada Q2 menyatakan kuartal tersebut menjual 45 persen lebih banyak daripada deret pada level rata-ratanya; indeks 0.55 pada Q4 menyatakan 45 persen lebih sedikit. Perhatikan pula bahwa keempat indeks berjumlah 0.82 + 1.45 + 1.18 + 0.55 = 4.0 — musiman idealnya menaikkan dan menurunkan penjualan secara seimbang sepanjang satu periode penuh, sehingga indeks-indeksnya berkisar di sekitar angka 1. Nilai yang menjauh dari 1 adalah cara tercepat mendeteksi musiman: bila rata-rata setiap kelompok nyaris sama dengan rata-rata keseluruhan, deret boleh dinyatakan tanpa pola musiman yang berarti.
Musiman vs Siklus dan Efek Kalender #
Siklus sering tertukar dengan musiman karena keduanya berbentuk gelombang. Pembedanya ada pada periode: musiman punya periode tetap yang diketahui (4 kuartal, 12 bulan), sedangkan siklus naik-turun dengan panjang yang tidak tetap dan posisi yang tidak bisa diramalkan. Naik-turun perekonomian yang membentang beberapa tahun adalah contoh klasik siklus — jarak puncak ke puncaknya berubah dari satu episode ke episode berikutnya, sehingga tidak ada “kuartal siklus” yang bisa dirata-ratakan seperti Q1 sampai Q4. Panduan membedakan keduanya tersedia dalam NIST/SEMATECH e-Handbook .
| Aspek | Musiman | Siklus |
|---|---|---|
| Panjang periode | tetap dan diketahui | tidak tetap |
| Pemicu | kalender dan cuaca | dinamika ekonomi |
| Contoh | es krim memuncak tiap Q2 | naik-turun ekonomi beberapa tahunan |
| Posisi puncak berikutnya | bisa ditentukan | tidak bisa dipastikan |
Masih satu keluarga dengan musiman adalah efek kalender — lonjakan yang lahir dari penanggalan, bukan cuaca. Konsumsi beras dan tiket transportasi menanjak menjelang lebaran, harga sebagian komoditas turun saat panen raya tiba, dan pengunjung pusat perbelanjaan memuncak di akhir pekan. Rilis lembaga seperti BPS kerap melakukan penyesuaian musiman dan kalender agar lonjakan hari besar tidak dibaca sebagai perubahan tren, dan kita perlu membandingkan bulan atau kuartal yang sama ketika menilai data lintas tahun.
Menghitung Pola Musiman dengan Python #
Cuplikan berikut menghitung rata-rata per posisi kuartal beserta seasonal index-nya:
es_krim = [180, 320, 260, 120, 190, 335, 275, 130]
tahun_1 = es_krim[:4]
tahun_2 = es_krim[4:]
rata_total = sum(es_krim) / len(es_krim)
print(f"rata-rata keseluruhan: {rata_total:.2f} porsi")
for k in range(4):
rata_k = (tahun_1[k] + tahun_2[k]) / 2
indeks = rata_k / rata_total
print(f"Q{k + 1}: rata-rata {rata_k:6.1f} porsi, indeks musiman {indeks:.2f}")Output yang Dihasilkan:
rata-rata keseluruhan: 226.25 porsi
Q1: rata-rata 185.0 porsi, indeks musiman 0.82
Q2: rata-rata 327.5 porsi, indeks musiman 1.45
Q3: rata-rata 267.5 porsi, indeks musiman 1.18
Q4: rata-rata 125.0 porsi, indeks musiman 0.55Mari kita bedah kode di atas:
- Baris 2-3 (
tahun_1dantahun_2): irisan memisahkan delapan kuartal menjadi dua tahun, sehingga kuartal posisi k dari tahun kedua berada ditahun_2[k]. - Baris 9 (
rata_k): rata-rata pasangan kuartal yang sama, misalnya Q2 = (320 + 335) / 2 = 327.5 porsi. - Baris 10 (
indeks): pembagian ke rata-rata keseluruhan 226.25 menghasilkan indeks 1.45 untuk Q2 — angka yang identik dengan tabel manual di atas.
Tren 182 Rp per bulan dan indeks musiman Q2 sebesar 1.45 kini terukur, tetapi keduanya dibaca dari data yang telah dirata-ratakan terlebih dahulu. Deret mentah masih bergerak naik-turun dari bulan ke bulan, dan alat pertama untuk meredam gejolak tersebut — moving average — adalah topik chapter berikutnya, sekaligus janji yang kita tanggung sejak chapter Line Chart.