Model prediksi hanya sebaik pemahaman kita atas data yang diprediksi. Sebelum menyentuh LSTM, bagian ini membangkitkan dan membedah dataset deret waktu yang akan dipakai seluruh proyek: 400 titik penjualan mingguan fiktif yang tersusun dari tiga komponen — tren linear naik, pola musiman dua harmonik, dan derau acak. Memahami ketiganya penting karena masing-mamen menuntut perlakuan berbeda: tren dan musiman bisa dipelajari model, sedangkan derau menjadi batas bawah kesalahan yang tidak mungkin ditembus.

Tiga Komponen Deret #

Rumus pembangkitnya sederhana dan transparan:

KomponenRumusPeran
Tren120 + 0.06 * tnaik 0,06 per minggu; 400 minggu berarti +24 satuan
Musiman12 sin(2πt/20) + 5 sin(4πt/20)siklus 20 minggu + harmonik keduanya
DerauGaussian mean 0, deviasi 2bagian tak terduga yang tidak bisa dipelajari

Diagram di atas merangkum alur pembangkitan: tiga komponen dijumlahkan menjadi satu nilai per titik waktu, lalu disimpan sebagai CSV dua kolom. Harmonik kedua (5 sin(4πt/20)) sengaja ditambahkan agar puncak musiman tidak rapi sempurna — deret hasilnya menyerupai data musiman nyata yang bentuk siklusnya sedikit tak beraturan.

Generator Dataset #

python Generator deret (data/generate_data.py)
"""Generator deret waktu sintetis: tren + musiman + derau.

Membangkitkan 400 titik data penjualan mingguan fiktif dengan tiga
komponen: tren linear naik, pola musiman dua harmonik (siklus 20
minggu), dan derau Gaussian. Seed tetap memastikan data/deret.csv
identik pada setiap eksekusi.

Pemakaian:
    python3 generate_data.py
"""

import csv
from pathlib import Path

import numpy as np

SEED = 42
JUMLAH_TITIK = 400
PERIODE_MUSIM = 20
BERKAS_OUTPUT = Path(__file__).resolve().parent / "deret.csv"


def bangkitkan_deret():
    """Kembalikan array nilai deret hasil tren + musiman + derau."""
    t = np.arange(JUMLAH_TITIK, dtype="float64")
    tren = 120.0 + 0.06 * t
    musiman = 12.0 * np.sin(2 * np.pi * t / PERIODE_MUSIM) \
        + 5.0 * np.sin(4 * np.pi * t / PERIODE_MUSIM)
    rng = np.random.default_rng(SEED)
    derau = rng.normal(0.0, 2.0, size=t.size)
    return tren + musiman + derau


def main():
    deret = bangkitkan_deret()

    with BERKAS_OUTPUT.open("w", newline="", encoding="utf-8") as f:
        penulis = csv.writer(f)
        penulis.writerow(["waktu", "nilai"])
        for waktu, nilai in enumerate(deret):
            penulis.writerow([waktu, f"{nilai:.4f}"])

    print(f"berkas output : {BERKAS_OUTPUT.name}")
    print(f"jumlah titik  : {len(deret)}")
    print(f"nilai pertama: {deret[0]:.2f} | nilai terakhir: {deret[-1]:.2f}")
    print(f"rentang       : min {deret.min():.2f} | maks {deret.max():.2f}")
    print(f"rata-rata     : {deret.mean():.2f} | deviasi baku: {deret.std():.2f}")
    print("5 nilai pertama:", [round(float(v), 2) for v in deret[:5]])
    print("5 nilai terakhir:", [round(float(v), 2) for v in deret[-5:]])


if __name__ == "__main__":
    main()

Output yang Dihasilkan:

text
berkas output : deret.csv
jumlah titik  : 400
nilai pertama: 120.61 | nilai terakhir: 135.88
rentang       : min 104.64 | maks 158.22
rata-rata     : 131.96 | deviasi baku: 11.46
5 nilai pertama: [120.61, 124.63, 133.43, 136.52, 130.69]
5 nilai terakhir: [131.98, 130.93, 129.81, 133.13, 135.88]

Mari kita telaah kode di atas baris per baris:

  1. Baris 23-31 (bangkitkan_deret): np.arange(400) menjadi sumbu waktu t; tren, dua harmonik musiman, dan derau dijumlahkan menjadi satu array. np.random.default_rng(SEED) membuat derau yang sama setiap eksekusi — mengganti SEED menghasilkan deret berbeda namun berkarakter sama.
  2. Baris 34-43 (main, penulisan CSV): setiap titik ditulis dengan empat angka desimal (f"{nilai:.4f}") sehingga berkas berukuran sekitar 5 KB dan bebas artefak presisi panjang.
  3. Baris 44-50 (ringkasan): statistik dasar dicetak sebagai pemeriksaan kewarasan — nilai pertama dekat 120 (tren di titik nol), nilai terakhir dekat 135 (tren + rata-rata musiman), dan deviasi baku sekitar 11 mencerminkan gabungan amplitudo musiman dan derau.

Membaca Statistik Deret #

Keluaran generator memberi kita tiga fakta yang dipakai sepanjang proyek. Pertama, nilai berkembang dari 120,61 ke 135,88 — tren naik terkonfirmasi. Kedua, rentang 104,64 sampai 158,22 lebih lebar daripada pergerakan tren murni (+24); selisihnya berasal dari amplitudo musiman total 17 (12 + 5). Ketiga, deviasi baku 11,46 adalah skala wajar untuk normalisasi di Bagian 3 — LSTM, seperti jaringan lain, belajar paling stabil ketika masukan berada di kisaran nol-rata-rata.

Data kini ada dan karakternya terukur. Bagian berikutnya mengubah deret mentah ini menjadi dataset supervised berbentuk (N, W, 1) lalu merakit LSTM yang membacanya.