Prediksi jauh lebih peka terhadap kualitas data daripada analisis deskriptif. Pada analisis, satu baris ganda hanya menggeser rata-rata sedikit; pada prediksi, baris ganda bisa membuat model melihat pola yang sebenarnya tidak pernah terjadi, dan satu sel kosong bisa menghentikan seluruh pipeline. Karena itu, sebelum model mana pun disentuh, kita periksa deret mentah 38 baris ini dengan daftar periksa yang sistematis — bukan dengan pandangan sekilas yang mudah terkecoh oleh tampilan yang rapi.

Empat Pertanyaan Validasi #

Validasi deret waktu kita rangkum menjadi empat pertanyaan berurutan. Pertama, apakah urutan waktunya utuh — minggu W1 sampai W36 tanpa lompatan, dengan selang tetap tujuh hari? Kedua, apakah ada minggu yang tercatat lebih dari sekali? Ketiga, apakah semua sel harga benar-benar angka? Keempat, apakah rentang harganya wajar untuk cabai merah? Blok berikut menjawab ketiga pertanyaan pertama:

python
import pandas as pd

df = pd.read_csv("../data/harga_mingguan.csv")

# 1. Urutan minggu: harapan W1..W36 tanpa lompatan dan tanpa kosong.
nomor = df["minggu"].str.extract(r"(\d+)")[0].astype(int)
print("Nomor minggu utuh  :", sorted(nomor.unique()) == list(range(1, 37)))
print("Rentang tanggal     :", df["tanggal_mulai"].min(), "s.d.", df["tanggal_mulai"].max())
tanggal = pd.to_datetime(df["tanggal_mulai"]).drop_duplicates()
print("Selang tetap 7 hari :", bool((tanggal.diff().dropna() == pd.Timedelta(days=7)).all()))

# 2. Duplikat: satu minggu seharusnya hanya muncul satu baris.
hitung = df["minggu"].value_counts()
print("Minggu tercatat >1  :", hitung[hitung > 1].to_dict())

# 3. Sel yang bukan angka pada kolom harga.
bukan_angka = df.loc[df["harga_ribu"] == "-", ["minggu", "harga_ribu"]]
print("Sel bukan angka    :", bukan_angka.values.tolist())

Output yang Dihasilkan:

text
Nomor minggu utuh  : True
Rentang tanggal     : 2025-06-02 s.d. 2026-02-02
Selang tetap 7 hari : True
Minggu tercatat >1  : {'W10': 3}
Sel bukan angka    : [['W27', '-']]

Mari kita baca hasil pemeriksaan baris demi baris:

  1. Nomor minggu utuh: True: str.extract(r"(\d+)") menarik angka dari label W1–W36, lalu membandingkan himpunan uniknya dengan 1 sampai 36. Tidak ada minggu yang hilang — kabar baik pertama.
  2. Selang tetap 7 hari: True: tanggal.diff() menghitung jarak antar tanggal berurutan; seluruhnya tepat Timedelta(days=7). Deret ini benar-benar mingguan, syarat penting agar fitur lag pada Bagian 6 bermakna “satu minggu sebelumnya”.
  3. {'W10': 3}: minggu W10 muncul tiga kali — dua baris kembar hasil entri ulang, kejanggalan yang sudah tercium di Bagian 2.
  4. [['W27', '-']]: satu sel harga berisi tanda -, bukan angka — catatan yang tidak sempat diisi.

Kewajaran Rentang Harga #

Pertanyaan keempat menuntut dua hal sekaligus: mengonversi kolom harga ke angka, lalu membaca statistiknya. Konversi memakai pd.to_numeric(..., errors="coerce") — sel yang gagal dikonversi (termasuk -) berubah menjadi NaN, penanda “tidak ada data” milik pandas:

python
import pandas as pd

df = pd.read_csv("../data/harga_mingguan.csv")
angka = pd.to_numeric(df["harga_ribu"], errors="coerce")

print("Tipe kolom harga_ribu :", df["harga_ribu"].dtype)
print("Sel gagal jadi angka  :", int(angka.isna().sum()))
print(f"Rentang harga         : {angka.min():.1f} s.d. {angka.max():.1f} ribu")
print(f"Rata-rata             : {angka.mean():.2f} ribu")
print()

masalah = pd.DataFrame(
    {
        "masalah": ["W10 tercatat 3 kali", "harga W27 tertulis '-'", "kolom harga terbaca teks"],
        "jenis": ["duplikat", "sel kosong", "tipe data"],
        "dampak": ["bobot ganda untuk W10", "W27 tak bisa dihitung", "statistik harga gagal"],
        "perlakuan": ["buang baris kembar", "interpolasi linear", "konversi ke numerik"],
    }
)
print(masalah.to_string(index=False))

Output yang Dihasilkan:

text
Tipe kolom harga_ribu : object
Sel gagal jadi angka  : 1
Rentang harga         : 35.9 s.d. 53.1 ribu
Rata-rata             : 40.59 ribu

                 masalah      jenis                dampak           perlakuan
     W10 tercatat 3 kali   duplikat bobot ganda untuk W10  buang baris kembar
  harga W27 tertulis '-' sel kosong W27 tak bisa dihitung  interpolasi linear
kolom harga terbaca teks  tipe data statistik harga gagal konversi ke numerik

Empat baris pertama menjawab pertanyaan kewajaran. Rentang 35,9 sampai 53,1 ribu rupiah per kilogram masuk akal untuk cabai merah — tidak ada nilai mustahil seperti 0 atau 900. Rata-rata sementara 40,59 masih memuat bobot ganda W10; setelah dibersihkan nilainya akan bergeser tipis ke 40,56. Tiga baris terakhir tabel merangkum seluruh temuan: dua masalah isi (duplikat dan sel kosong) yang menciptakan satu masalah turunan (kolom harga terbaca object, alias teks, karena satu sel - cukup untuk membuat pandas menyerah menafsirkan seluruh kolom sebagai angka).

Praktik memeriksa data sebelum dipercaya dibahas tuntas pada chapter Memeriksa Data , dan berbagai jenis masalah kualitas beserta perawatannya ada pada section Data Cleaning .

Ringkasan Bagian 3 #

Empat pertanyaan validasi terjawab tuntas: urutan minggu utuh W1–W36 dengan selang tetap 7 hari; W10 tercatat tiga kali; satu sel harga W27 tertulis -; dan rentang harga 35,9–53,1 ribu tergolong wajar. Seluruh temuan terkumpul dalam satu tabel masalah berikut perlakuan yang direncanakan.

Rencana itu kita eksekusi pada Bagian 4: Membersihkan Data — dengan alasan untuk setiap keputusan, dan verifikasi ulang sampai data benar-benar layak dipakai melatih model.