Setiap orang di organisasi membandingkan: desain baru lawan desain lama, cabang Bandung lawan Surabaya, batch kopi minggu ini lawan minggu lalu. Masalahnya, dua kelompok hampir selalu menunjukkan rata-rata yang berbeda — bahkan bila keduanya diambil dari populasi yang sama persis — karena sampel membawa fluktuasi. Analisis komparatif adalah disiplin membedakan perbedaan yang nyata dari perbedaan yang sekadar ulir acak. Pada chapter ini kita mulai dari eksperimen A/B yang sederhana, naik ke uji-t dua sampel dengan scipy.stats.ttest_ind, lalu memperluas ke tiga kelompok sekaligus dengan ANOVA satu arah.

Membandingkan Dua Kelompok: Eksperimen A/B #

Kasus kita: aplikasi pemesanan Toko Kopi Kita mendapat usulan tampilan baru pada halaman checkout. Sebelum mengganti sepenuhnya, tim menguji kedua tampilan secara paralel — pelanggan yang datang dialihkan secara acak ke tampilan lama atau tampilan baru, lalu nilai transaksi tiap pelanggan dicatat. Inilah bentuk paling murni eksperimen A/B: satu-satunya hal yang membedakan kedua kelompok adalah perlakuannya, karena pembagian kelompok dilakukan secara acak.

Metrik yang dibandingkan adalah nilai transaksi dalam ribuan rupiah. Sebelum uji statistik apa pun, kita lihat dulu ringkasan deskriptifnya:

python
import pandas as pd

lama = [38, 46, 33, 47, 40, 34, 45, 37, 30, 50]
baru = [45, 51, 40, 54, 44, 48, 53, 42, 37, 55, 47, 41, 49, 43, 46]

uji_ab = pd.DataFrame({
    "tampilan": ["lama"] * len(lama) + ["baru"] * len(baru),
    "nilai": lama + baru,
})

print(uji_ab.groupby("tampilan")["nilai"].agg(["count", "mean", "std"]).round(2))
print()
rata_lama = uji_ab.loc[uji_ab["tampilan"] == "lama", "nilai"].mean()
rata_baru = uji_ab.loc[uji_ab["tampilan"] == "baru", "nilai"].mean()
print("Selisih rata-rata (baru - lama): %.2f ribu rupiah" % (rata_baru - rata_lama))

Output yang Dihasilkan:

text
          count   mean   std
tampilan                    
baru         15  46.33  5.37
lama         10  40.00  6.73

Selisih rata-rata (baru - lama): 6.33 ribu rupiah

Cara membaca hasil tersebut:

  1. groupby("tampilan") + agg merangkum tiap kelompok terpisah: banyaknya transaksi (count), rata-rata (mean), dan simpangan baku (std).
  2. Selisih 6,33 ribu rupiah tampak menggiurkan — tampilan baru membawa transaksi sekitar 6 ribu rupiah lebih besar. Tetapi perhatikan std sekitar 5 sampai 7: nilai transaksi di dalam tiap kelompok bergelombang. Bila kita mengulang eksperimen yang sama tanpa perubahan apa pun, selisih beberapa ribu rupiah bisa muncul begitu saja.
  3. Kelompok yang tidak seimbang (10 lawan 15 transaksi) wajar terjadi pada A/B di dunia nyata; kita tinggal memastikan alat uji berikutnya menangani hal itu.

Pertanyaan analisis komparatif selalu berbunyi: selisih sebesar 6,33 ribu rupiah dengan sebaran seperti ini — besar atau kecil? Untuk menjawabnya kita butuh ukuran yang memperhitungkan sebaran, dan itu pekerjaan uji-t.

Uji-t Dua Sampel: Selisih Nyata atau Kebetulan #

Uji-t dua sampel menguji hipotesis nol bahwa kedua kelompok berasal dari populasi dengan rata-rata sama. Idé dasarnya sederhana: selisih rata-rata dibandingkan terhadap galat bakunya — seberapa besar selisih biasanya bergoyang bila hipotesis nol benar.

text
t = (rata-rata kelompok 1 - rata-rata kelompok 2) / galat baku selisih

Nilai t yang jauh dari nol berarti selisih terlalu besar untuk dijelaskan fluktuasi semata, dan p-value-nya mengecil. scipy.stats.ttest_ind menghitung semuanya; kita jalankan dua ragamnya sekaligus:

python
from scipy.stats import ttest_ind

lama = [38, 46, 33, 47, 40, 34, 45, 37, 30, 50]
baru = [45, 51, 40, 54, 44, 48, 53, 42, 37, 55, 47, 41, 49, 43, 46]

t_student, p_student = ttest_ind(baru, lama, equal_var=True)
t_welch, p_welch = ttest_ind(baru, lama, equal_var=False)

print("Student (equal_var=True) : t = %.3f, p = %.4f" % (t_student, p_student))
print("Welch   (equal_var=False): t = %.3f, p = %.4f" % (t_welch, p_welch))

Output yang Dihasilkan:

text
Student (equal_var=True) : t = 2.612, p = 0.0156
Welch   (equal_var=False): t = 2.493, p = 0.0237

Bedah kode dan hasilnya:

  1. ttest_ind(baru, lama) menerima dua daftar nilai dan mengembalikan pasangan statistik t serta p-value. Urutan argumen hanya menentukan tanda t, bukan kesimpulannya.
  2. equal_var=True memilih uji-t Student yang mengasumsikan varians kedua populasi sama; equal_var=False memilih ragam Welch yang tidak memakai asumsi itu. Pada data kita simpangan baku 5,37 lawan 6,73 — sebaran yang tidak persis setara — sehingga kedua ragam menghasilkan angka berbeda: t 2,612 lawan 2,493, p 0,0156 lawan 0,0237.
  3. Kesimpulan di kasus ini sama: kedua p-value berada di bawah ambang 0,05, jadi kita menolak hipotesis nol — tampilan baru membawa rata-rata transaksi yang lebih tinggi. Tetapi bayangkan p-value berada di sekitar 0,04 lawan 0,06; pilihan ragam uji akan menentukan kesimpulan. Karena itulah ragam Welch layak dijadikan pilihan bawaan.

Satu catatan penutup untuk uji-t: hasil yang signifikan hanya menjawab “ada perbedahan”, bukan “perbedaan itu penting”. Selisih 6,33 ribu rupiah per transaksi pada puluhan ribu transaksi per bulan adalah kabar besar; pada sepuluh transaksi per bulan, kabar itu nyaris tak terasa. Ukuran praktis seperti ini kita bahas tuntas pada chapter penutup Section ini, dan ukuran efek formalnya sudah kita kenal di Section Statistika.

Lebih dari Dua Kelompok: ANOVA Satu Arah #

Kini pemilik toko bertanya hal yang lebih luas: apakah nilai transaksi pelanggan berbeda antar tiga cabang — Bandung, Surabaya, dan Yogyakarta? Kita bisa menguji tiap pasangan cabang dengan uji-t, tetapi tiga uji-t berarti tiga peluang tersesat masing-masing 5%; dijumlahkan, peluang menemukan “perbedaan” palsu membengkak. ANOVA satu arah (one-way ANOVA) menguji ketiga kelompok sekaligus dengan satu pertanyaan: apakah rata-rata semua cabang sama?

Cara kerjanya adalah membandingkan dua sumber variasi:

text
F = varians antar kelompok / varians dalam kelompok

Bila rata-rata antar cabang memang sama, variasi antar kelompok hanya pantulan variasi dalam kelompok dan F berdekatan dengan 1. Bila satu cabang benar-benar berbeda, pembilang membesar dan F menjauh dari 1. Kita hitung dengan scipy.stats.f_oneway:

python
from scipy.stats import f_oneway

bandung    = [44, 49, 41, 52, 46, 38, 50, 45, 47, 43]
surabaya   = [36, 41, 33, 45, 38, 42, 35, 40, 37, 31]
yogyakarta = [43, 39, 46, 42, 48, 40, 45, 44, 41, 47]

stat, p = f_oneway(bandung, surabaya, yogyakarta)

print("Statistik F : %.3f" % stat)
print("p-value     : %.4f" % p)

Output yang Dihasilkan:

text
Statistik F : 10.497
p-value     : 0.0004

Pembacaan hasilnya perlu ketelitian:

  1. f_oneway(bandung, surabaya, yogyakarta) menerima tiap kelompok sebagai argumen terpisah dan mengembalikan statistik F serta p-value. “Satu arah” berarti hanya satu faktor yang dibandingkan — cabang — bukan kombinasi faktor.
  2. F = 10,497 dengan p = 0,0004 jauh di bawah ambang 0,05: variasi antar cabang terlalu besar untuk dijelaskan variasi dalam cabang. Kita menolak hipotesis nol bahwa rata-rata ketiga cabang sama.
  3. ANOVA tidak menyebut cabang mana yang berbeda. Melihat rata-rata mentah — Bandung 45,5; Yogyakarta 43,5; Surabaya 37,8 — kita bisa menduga Surabaya yang tertinggal, tetapi dugaan itu belum teruji. Menindaklanjuti dengan uji per pasangan memang lazim, tetapi tiap uji tambahan membuka peluang temuan palsu — masalah pembandingan ganda yang kita bahas serius di chapter Analisis Konfirmasi .

Memilih Metode Perbandingan yang Tepat #

Alat yang kita kumpulkan di Section ini kini saling melengkapi. Pemilihannya ditentukan oleh jenis data dan jumlah kelompok:

PertanyaanJenis dataMetodeFungsi
Dua kelompok, varians sebandingNumerikUji-t Studentttest_ind(..., equal_var=True)
Dua kelompok, varians berbeda/ragam amanNumerikUji-t Welchttest_ind(..., equal_var=False)
Tiga kelompok atau lebihNumerikANOVA satu arahf_oneway(...)
Hubungan dua kolom kategorikalKategorikalChi-squarechi2_contingency(...)
Kebersamaan dua kolom numerikNumerikKorelasiDataFrame.corr()

Baris terakhir menghubungkan kita kembali ke chapter Analisis Korelasi dan Analisis Data Kategorikal : teknik tidak berdiri sendiri, melainkan dipilih menurut bentuk datanya. Satu pengecualian penting: semua uji pada tabel di atas mensyaratkan pengamatan yang saling bebas — data berulang dari pelanggan yang sama, misalnya, menuntut pendekatan lain yang membahas struktur dependensi.

Rangkuman #

  • Perbedaan rata-rata antar kelompok hampir selalu muncul; tugas analisis komparatif adalah memilah perbedaan nyata dari fluktuasi sampel.
  • Eksperimen A/B yang sehat mengacak pembagian kelompok dan mengubah satu hal saja, sehingga selisih metrik bisa diatribusikan ke perlakuan.
  • ttest_ind menguji dua kelompok; ragam Welch (equal_var=False) tidak mengandaikan varians sama dan layak menjadi pilihan bawaan.
  • f_oneway membandingkan tiga kelompok atau lebih sekaligus lewat rasio varians antar kelompok terhadap dalam kelompok; hasil signifikan berarti minimal satu kelompok berbeda — kelompok yang mana, tidak dikatakannya.
  • Metode dipilih menurut jenis data dan jumlah kelompok; uji per pasangan tanpa rencana membuka pintu temuan palsu.

Sepanjang chapter ini kelompok yang dibandingkan sudah tersedia: tampilan lama lawan baru, cabang lawan cabang. Sering kali kelompok justru belum ada dan tugas kita menciptakannya — membagi pelanggan menjadi segmen yang polanya mirip agar promosi bisa menyasar. Di chapter berikutnya kita menyusun segmen itu dari perilaku belanja pelanggan dengan kerangka RFM. Lanjut ke chapter Analisis Segmentasi .

Referensi #

  1. SciPy — scipy.stats
  2. pandas — API Reference: DataFrame.groupby