Analisis konfirmasi pada chapter sebelumnya mengunci rencana uji agar keputusan tidak dibentuk ulang setelah hasil terlihat. Namun rencana paling ketat sekalipun berdiri di atas pilihan-pilihan analis: hari pencilan dimasukkan atau dikeluarkan, metrik dihitung dari nilai bruto atau neto, periode data dipotong per bulan atau digabung penuh. Masing-masing pilihan itu sah, dan masing-masing bisa menggeser angka akhir. Analisis sensitivitas adalah uji keandalan yang menghadapi hal itu secara terbuka: jalankan analisis yang sama di atas beberapa variasi pilihan, lalu lihat apakah kesimpulan bertahan. Pada chapter ini kita mempraktikkannya pada tren penjualan harian Toko Kopi Kita dengan satu loop skenario sederhana.
Satu Kesimpulan, Banyak Pilihan Analis #
Sebelum menyentuh kode, mari kita daftar pilihan-pilihan yang paling sering menggerakkan angka analisis. Tiga di antaranya muncul hampir di setiap proyek data:
| Dimensi pilihan | Opsi yang tersedia | Contoh pada kasus kita |
|---|---|---|
| Perlakuan pencilan | dimasukkan, dikeluarkan, dibatasi (winsorize) | satu hari pesanan borongan kantor yang jauh di atas hari biasa |
| Definisi metrik | bruto, neto setelah diskon, median, rata-rata | penjualan dihitung dari kolom bruto atau bruto - diskon |
| Periode data | penuh, per bulan, per pekan, tanpa hari libur | 30 hari gabungan, atau Desember dan Januari terpisah |
Tabel ini bukan daftar hal yang boleh dicoba-coba sampai angkanya enak dilihat. Analisis sensitivitas memakai daftar ini untuk menjawab satu pertanyaan: bila pilihan yang wajar-wajar saja sudah mengubah kesimpulan, berarti kesimpulan itu belum layak dipakai untuk keputusan besar. Sebaliknya, bila kesimpulan bertahan di hampir semua variasi, kita melaporkannya dengan keyakinan yang jauh lebih kuat.
Kasus: Tren Penjualan Harian Toko Kopi Kita #
Bahan kita adalah catatan penjualan 30 hari, dari 17 Desember 2025 sampai 15 Januari 2026. Kolom bruto dan diskon dalam ribu rupiah. Pengelola toko hendak menyimpulkan satu hal: apakah penjualan harian sedang menanjak?
tanggal,bruto,diskon
2025-12-17,812,30
2025-12-18,795,0
2025-12-19,838,45
2025-12-20,866,0
2025-12-21,803,25
2025-12-22,851,0
2025-12-23,829,40
2025-12-24,872,0
2025-12-25,844,35
2025-12-26,819,0
2025-12-27,861,50
2025-12-28,835,0
2025-12-29,888,30
2025-12-30,856,0
2025-12-31,841,20
2026-01-01,825,0
2026-01-02,869,35
2026-01-03,842,0
2026-01-04,884,45
2026-01-05,858,0
2026-01-06,896,30
2026-01-07,1602,240
2026-01-08,847,0
2026-01-09,891,40
2026-01-10,863,0
2026-01-11,918,25
2026-01-12,889,0
2026-01-13,932,35
2026-01-14,901,0
2026-01-15,924,50Ada satu hari yang menonjol sejak pandangan pertama: 7 Januari, dengan bruto 1.602 ribu — hampir dua kali hari biasa — dan diskon 240 ribu. Kasirnya mencatat hari itu sebagai pesanan borongan kantor. Sebelum memodelkan apa pun, kita ukur dulu seberapa besar satu hari itu menggeser statistik paling sederhana, rata-rata:
import pandas as pd
penjualan = pd.read_csv("penjualan_harian.csv", parse_dates=["tanggal"])
print("Lima hari dengan bruto tertinggi:")
print(penjualan.nlargest(5, "bruto").to_string(index=False))
print()
semua = penjualan["bruto"].mean()
normal = penjualan.loc[penjualan["bruto"] < 1000, "bruto"].mean()
print("Rata-rata bruto 30 hari : %.1f ribu rupiah" % semua)
print("Rata-rata tanpa hari borongan : %.1f ribu rupiah" % normal)
print("Selisih : %.1f ribu rupiah" % (semua - normal))Output yang Dihasilkan:
Lima hari dengan bruto tertinggi:
tanggal bruto diskon
2026-01-07 1602 240
2026-01-13 932 35
2026-01-15 924 50
2026-01-11 918 25
2026-01-14 901 0
Rata-rata bruto 30 hari : 885.0 ribu rupiah
Rata-rata tanpa hari borongan : 860.3 ribu rupiah
Selisih : 24.7 ribu rupiahMari kita telaah baris-baris kode di atas:
nlargest(5, "bruto")mengurutkan lima hari teratas menurut kolombruto. Jaraknya jelas: hari borongan 1.602, sementara peringkat kedua sampai kelima berkumpul rapat di 901–932 — tidak ada hari lain yang mendekati, sehingga ambang pemisah 1.000 pada baris berikutnya aman dipakai.penjualan.loc[penjualan["bruto"] < 1000, "bruto"].mean()menghitung rata-rata hanya dari hari-hari normal; kondisi< 1000adalah definisi “hari normal” yang kita pegang sepanjang chapter.- Selisih 24,7 ribu rupiah itulah pengaruh satu hari terhadap rata-rata 30 hari: sekitar 2,9% naik atau turun hanya karena satu baris data. Kini pertanyaannya — apakah kesimpulan yang lebih rumit pun terguncang sebesar itu?
Loop Skenario: Enam Versi dari Analisis yang Sama #
Kesimpulan yang diuji adalah “penjualan harian menanjak”, dan pengukurnya adalah kemiringan garis regresi dari Regresi Linear
: np.polyfit(hari_ke, penjualan, 1) — perubahan penjualan per hari, dikalikan 30 agar terbaca sebagai per bulan. Kita jalankan pengukuran yang sama di atas enam variasi pilihan: dengan dan tanpa hari borongan, metrik bruto dan neto, serta periode Desember saja, Januari saja, dan gabungan:
import numpy as np
import pandas as pd
penjualan = pd.read_csv("penjualan_harian.csv", parse_dates=["tanggal"])
penjualan["hari_ke"] = (penjualan["tanggal"] - penjualan["tanggal"].min()).dt.days + 1
penjualan["neto"] = penjualan["bruto"] - penjualan["diskon"]
normal = penjualan[penjualan["bruto"] < 1000]
desember = penjualan[penjualan["tanggal"].dt.month == 12]
januari = penjualan[penjualan["tanggal"].dt.month == 1]
skenario = [
("Bruto, semua data", penjualan, "bruto"),
("Bruto, tanpa borongan", normal, "bruto"),
("Neto, semua data", penjualan, "neto"),
("Neto, tanpa borongan", normal, "neto"),
("Hanya Desember", desember, "bruto"),
("Hanya Januari", januari, "bruto"),
]
print("%-24s %4s %11s %11s %s" % ("Skenario", "Hari", "Kemiringan", "Per bulan", "Arah"))
for nama, data, kolom in skenario:
b, a = np.polyfit(data["hari_ke"], data[kolom], 1)
arah = "naik" if b > 0 else "turun"
print("%-24s %4d %11.2f %11.1f %s" % (nama, len(data), b, b * 30, arah))Output yang Dihasilkan:
Skenario Hari Kemiringan Per bulan Arah
Bruto, semua data 30 5.14 154.3 naik
Bruto, tanpa borongan 29 3.06 91.7 naik
Neto, semua data 30 4.45 133.5 naik
Neto, tanpa borongan 29 3.00 90.1 naik
Hanya Desember 15 2.93 87.9 naik
Hanya Januari 15 2.71 81.2 naikStruktur kodenya sengaja berbentuk daftar skenario dan satu loop:
penjualan["hari_ke"]mengubah tanggal menjadi nomor hari 1–30 sekali di awal. Karena penomoran ini tidak dihitung ulang per skenario, kemiringan tiap skenario tetap bermakna sama: perubahan penjualan per hari.penjualan["neto"]menyiapkan definisi metrik alternatif — penjualan setelah diskon — sebagai kolom baru, sehingga skenario neto tinggal memilih kolom.skenarioadalah daftar pasangan(nama, data, kolom): potongan data mana dan kolom metrik mana yang dipakai. Loop kemudian menjalankannp.polyfityang sama untuk semuanya — analisisnya identik, bahan bakunya yang divariasikan.
Membaca Tabel Skenario: Kapan Kesimpulan Kokoh #
Tabel hasil dibaca dalam dua lapis. Lapis pertama adalah arah: keenam skenario menghasilkan kemiringan positif — “penjualan menanjak” tidak berubah di pilihan analisis mana pun. Lapis kedua adalah besaran: kenaikannya berkisar dari 81,2 sampai 154,3 ribu rupiah per bulan, hampir dua kali lipat dari ujung ke ujung. Kesimpulan arahnya kokoh; kesimpulan besarannya belum.
Dari mana rentang selarut itu datang? Dua skenario teratas — yang memuat hari borongan — mencatat 154,3 dan 133,5 ribu per bulan, sementara empat skenario lainnya berkumpul rapat di 81–92 ribu. Satu hari borongan di akhir Januari menarik garis agar terlihat lebih menanjak; begitu hari itu dikeluarkan, angka turun dan berhimpit dengan perkiraan dari periode Desember maupun Januari sendirian. Ringkasnya per dimensi pilihan:
| Dimensi pilihan | Dampak ke hasil | Pembacaannya |
|---|---|---|
| Perlakuan hari borongan | besar: 154,3 vs 91,7 ribu per bulan | pilihan yang paling menggerakkan kesimpulan |
| Definisi metrik bruto vs neto | kecil: 91,7 vs 90,1 (tanpa borongan) | kesimpulan tidak bergantung definisi |
| Periode Desember vs Januari vs gabungan | kecil: 87,9, 81,2, 90,1 | tananjaknya berlangsung merata, bukan tipuan satu bulan |
Bentuk laporan yang jujur mengikuti langsung dari tabel ini: penjualan harian menanjak — arah ini stabil di semua skenario — dengan laju kenaikan sekitar 81–92 ribu rupiah per bulan pada hari-hari normal, dan setidaknya 133 ribu bila hari borongan diperhitungkan. Bandingkan dengan laporan tanpa sensitivitas yang menyebut satu angka 154,3 ribu: angka itu bukan salah, tetapi menyembunyikan bahwa nilainya bergantung pada perlakuan satu baris data.
Kesimpulan yang sensitif pun belum tentu dibuang. Bila satu skenario membuat arah berbalik, langkah berikutnya adalah memahami penyebabnya — pencilan yang perlu penjelasan bisnis, definisi metrik yang perlu disepakati pemangku kepentingan, atau periode yang memang berbeda perilakunya — lalu memutuskan pilihan utama beserta alasannya, dan melaporkan kerentanannya secara terbuka.
Rangkuman #
- Setiap kesimpulan berdiri di atas pilihan analis: perlakuan pencilan, definisi metrik, dan periode data adalah tiga yang paling sering muncul.
- Satu hari borongan menggeser rata-rata penjualan 30 hari sebesar 24,7 ribu rupiah — contoh konkret betapa pekanya statistik terhadap satu baris.
- Analisis sensitivitas menjalankan analisis yang sama di atas beberapa variasi pilihan lewat satu loop skenario; hasilnya adalah tabel perbandingan, bukan satu angka.
- Kesimpulan arah “penjualan menanjak” kokoh di keenam skenario; besaran kenaikannya rentang 81–154 ribu per bulan, dan sumber rentangnya teridentifikasi: perlakuan hari borongan.
- Seluruh skenario didefinisikan lebih dulu dan dilaporkan seluruhnya; memilih yang menguntungkan saja adalah data dredging dengan nama lain.
Tabel skenario memberi kita gambaran keandalan, tetapi angka yang stabil pun belum selesai diperlakukan. Berapa pun angkanya, ia harus diterjemahkan menjadi makna: seberapa besar itu di dunia nyata, seberapa pasti, dan kalimat apa yang pantas diucapkan di depan pengambil keputusan. Penerjemahan itulah babak akhir Section ini. Lanjut ke chapter Interpretasi Hasil Analisis .