Pada chapter sebelumnya kita melihat bahwa sampel acak menghasilkan statistik yang berkerumun di sekitar parameter. Kata kuncinya adalah “acak” — tetapi acak bukan satu teknik tunggal. Memilih 8 siswa dengan undian berbeda konsekuensinya dengan memilih 8 siswa yang kebetulan berada di kantin. Pada chapter ini kita mencoba empat teknik pengambilan sampel pada data yang sama — 30 siswa dari tiga kelas dengan tingkat nilai berbeda — lalu membuktikan lewat hitungan betapa mahalnya sampel yang dipilih dengan cara yang tidak tepat.

Data Latihan: Tiga Kelas yang Tidak Setara #

Kita pakai berkas siswa.csv berisi 30 siswa dari tiga kelas. Ketiga kelas tersebut tidak setara: rata-rata kelas A sekitar 87, kelas B sekitar 78, dan kelas C sekitar 67. Ketimpangan inilah yang akan membuat pilihan teknik sampling terasa dampaknya.

csv
id,kelas,nilai
S01,A,88
S02,A,92
S03,A,85
S04,A,90
S05,A,79
S06,A,94
S07,A,86
S08,A,81
S09,A,89
S10,A,84
S11,A,91
S12,A,87
S13,B,76
S14,B,82
S15,B,71
S16,B,78
S17,B,85
S18,B,73
S19,B,80
S20,B,75
S21,B,83
S22,B,77
S23,C,68
S24,C,74
S25,C,62
S26,C,70
S27,C,66
S28,C,72
S29,C,60
S30,C,64

Sebelum masuk ke kode, kita petakan dulu teknik-teknik yang akan dibahas:

TeknikCara kerjaKelebihanRisiko
Simple randomSetiap anggota berpeluang sama terpilihDasar matematis paling kuatButuh daftar seluruh anggota
SystematicPilih titik awal acak, lalu ambil tiap k-anggotaPraktis untuk daftar berurutanBerbahaya bila data berpola periodik
StratifiedBagi populasi per kelompok, sampel tiap kelompokMenjamin semua kelompok terwakiliPerlu tahu komposisi kelompok
ClusterPilih acak beberapa kelompok utuh, sensus di dalamnyaMurah bila anggota tersebarKeragaman antarkelompok memperbesar galat
ConvenienceAmbil yang paling mudah dijangkauTermurah dan tercepatHampir pasti bias

Simple Random Sampling #

Teknik paling murni: setiap siswa berpeluang sama untuk terpilih, seperti undian. NumPy menyediakannya lewat rng.choice():

python
import numpy as np
import pandas as pd

siswa = pd.read_csv("siswa.csv")

rng = np.random.default_rng(42)
terpilih = rng.choice(len(siswa), size=8, replace=False)
terpilih.sort()

print("Simple random sampling, 8 dari 30 siswa:")
for i in terpilih:
    baris = siswa.iloc[i]
    print(f"  {baris['id']}  kelas {baris['kelas']}  nilai {baris['nilai']}")

Output yang Dihasilkan:

text
Simple random sampling, 8 dari 30 siswa:
  S03  kelas A  nilai 85
  S12  kelas A  nilai 87
  S17  kelas B  nilai 85
  S19  kelas B  nilai 80
  S21  kelas B  nilai 83
  S25  kelas C  nilai 62
  S27  kelas C  nilai 66
  S29  kelas C  nilai 60

Bedah baris-per-baris kodenya:

  1. Baris 4 (pd.read_csv): membaca daftar siswa; posisi baris 0 sampai 29 menjadi identitas anggota populasi.
  2. Baris 6 (default_rng(42)): generator acak berseed 42 agar sampel yang sama bisa dihasilkan ulang.
  3. Baris 7 (rng.choice(len(siswa), size=8, replace=False)): menarik 8 nomor baris tanpa pengulangan — replace=False menjaga satu siswa tidak terpilih dua kali.
  4. Baris 8-11: nomor terpilih diurutkan agar mudah dibaca, lalu tiap nomor dipetakan kembali ke baris siswanya.

Perhatikan komposisi hasilnya: 2 siswa dari kelas A, 3 dari kelas B, dan 3 dari kelas C. Karena undian tidak melihat kelas, proporsi sampel mengikuti kebetulan — kadang kelas kecil bisa sama sekali tidak terwakili.

Systematic Sampling #

Pada systematic sampling kita berjalan berinterval: tentukan jarak k = N / n, pilih satu titik awal acak dari 0 sampai k−1, lalu ambil setiap anggota ke-k darinya:

python
import numpy as np
import pandas as pd

siswa = pd.read_csv("siswa.csv")

N = len(siswa)   # 30
n = 6            # ukuran sampel
k = N // n       # interval sistematis = 5

rng = np.random.default_rng(42)
awal = int(rng.integers(0, k))   # titik awal acak dari 0 sampai k-1
indeks = list(range(awal, N, k))

print(f"Systematic sampling: k = {N}/{n} = {k}, titik awal = {awal}")
for i in indeks:
    baris = siswa.iloc[i]
    print(f"  urutan ke-{i + 1:2d}: {baris['id']}  kelas {baris['kelas']}  nilai {baris['nilai']}")

Output yang Dihasilkan:

text
Systematic sampling: k = 30/6 = 5, titik awal = 0
  urutan ke- 1: S01  kelas A  nilai 88
  urutan ke- 6: S06  kelas A  nilai 94
  urutan ke-11: S11  kelas A  nilai 91
  urutan ke-16: S16  kelas B  nilai 78
  urutan ke-21: S21  kelas B  nilai 83
  urutan ke-26: S26  kelas C  nilai 70

Dengan seed 42 titik awalnya 0, sehingga terpilih siswa nomor urut 1, 6, 11, 16, 21, dan 26 — sampel merentang dari kelas A hingga kelas C hanya lewat satu angka acak. Teknik ini praktis untuk daftar berurutan seperti nomor kupon atau urutan kedatangan pelanggan. Kelemahannya: bila daftar memiliki pola berulang tepat sepanjang k (misalnya setiap siswa ke-5 berasal dari kelas yang sama), sampel sistematis menjadi tidak mewakili populasi.

Stratified Sampling #

Stratified sampling menjawab kekhawatiran pada simple random: kelompok kecil bisa saja tidak terwakili. Solusinya, populasi dibagi per stratum (di sini: kelas), lalu tiap stratum menyumbang sampel sebanding ukurannya:

python
import numpy as np
import pandas as pd

siswa = pd.read_csv("siswa.csv")

n_total = 10
rng = np.random.default_rng(42)
terpilih = []

for kelas in ("A", "B", "C"):
    indeks_kelas = siswa.index[siswa["kelas"] == kelas].tolist()
    kuota = round(len(indeks_kelas) / len(siswa) * n_total)
    ambil = rng.choice(indeks_kelas, size=kuota, replace=False)
    terpilih.extend(ambil.tolist())
    print(f"Kelas {kelas}: populasi {len(indeks_kelas):2d} siswa, diambil {kuota}")

terpilih.sort()
print()
print("Susunan sampel stratified:")
for i in terpilih:
    baris = siswa.iloc[i]
    print(f"  {baris['id']}  kelas {baris['kelas']}  nilai {baris['nilai']}")

Output yang Dihasilkan:

text
Kelas A: populasi 12 siswa, diambil 4
Kelas B: populasi 10 siswa, diambil 3
Kelas C: populasi  8 siswa, diambil 3

Susunan sampel stratified:
  S01  kelas A  nilai 88
  S06  kelas A  nilai 94
  S08  kelas A  nilai 81
  S11  kelas A  nilai 91
  S13  kelas B  nilai 76
  S14  kelas B  nilai 82
  S18  kelas B  nilai 73
  S27  kelas C  nilai 66
  S28  kelas C  nilai 72
  S30  kelas C  nilai 64

Bedah kode di atas:

  1. Baris 10 (siswa.index[siswa["kelas"] == kelas]): menyaring nomor baris milik satu stratum — kelas A menyumbang 12 baris, B 10, C 8.
  2. Baris 11 (kuota = round(...)): alokasi proporsional. Dari target 10 siswa, kelas A mendapat 12/30 × 10 = 4 kursi, B dan C masing-masing 3 setelah pembulatan.
  3. Baris 12 (rng.choice(indeks_kelas, ...)): undian tetap diadakan, tetapi hanya di dalam stratum — struktur sampel dikunci, isi tiap bagian tetap acak.

Hasilnya: sampel 10 siswa dengan komposisi 4-3-3 yang menyalin komposisi populasi. Saat kelompok berbeda sifat secara nyata, stratified biasanya memberi taksiran yang lebih presisi daripada simple random dengan ukuran sampel sama.

Convenience Sampling dan Harganya yang Mahal #

Convenience sampling mengambil anggota yang paling mudah dijangkau: teman sekelas, pengikut media sosial toko, atau pelanggan yang kebetulan lewat. Tidak ada undian dan tidak ada kendali struktur. Di sekolah kita, cara paling “mudah” adalah mengambil seluruh kelas A — dekat, ramai, dan kooperatif:

python
import statistics
import pandas as pd

siswa = pd.read_csv("siswa.csv")

semua_nilai = siswa["nilai"].tolist()
nilai_kelas_a = siswa.loc[siswa["kelas"] == "A", "nilai"].tolist()

rata_populasi = statistics.mean(semua_nilai)
rata_kelas_a = statistics.mean(nilai_kelas_a)

print(f"Rata-rata populasi (30 siswa) : {rata_populasi:.2f}")
print(f"Rata-rata hanya kelas A       : {rata_kelas_a:.2f}")
print(f"Bias kenyamanan               : {rata_kelas_a - rata_populasi:+.2f} poin")

Output yang Dihasilkan:

text
Rata-rata populasi (30 siswa) : 78.73
Rata-rata hanya kelas A       : 87.17
Bias kenyamanan               : +8.43 poin

Angka +8,43 poin tersebut adalah bias — kesalahan yang arahnya konsisten, bukan keragaman acak yang saling meniadakan. Sampel 12 siswa dari kelas A bahkan lebih besar daripada sampel acak 8 siswa, tetapi justru makin yakin meleset karena ukuran sampel tidak menyembuhkan pemilihan yang condong. Survei yang hanya menyebar di grup pelanggan setia pun menghasilkan pola serupa: respondennya banyak, kenyataannya hanya satu sisi.

Rangkuman #

  • Simple random sampling memberi peluang sama pada setiap anggota; rng.choice(..., replace=False) adalah wujud undiannya di NumPy.
  • Systematic sampling berjalan berinterval k = N / n dari satu titik awal acak — praktis, tetapi rawan bila daftar berpola periodik.
  • Stratified sampling mengunci komposisi sampel mengikuti komposisi populasi sehingga kelompok kecil tetap terwakili; cluster sampling memilih kelompok utuh secara acak untuk menekan biaya.
  • Convenience sampling murah tetapi menghasilkan bias yang membesar, bukan mengecil, ketika responden ditambah.

Sampel yang baik memberi kita data yang layak diringkas. Pertanyaan berikutnya adalah cara meringkasnya: satu angka apa yang paling mewakili sekumpulan nilai? Kita mulai dari ukuran yang paling sering dipakai sekaligus paling sering disalahpahami pada chapter Ukuran Tendensi Sentral .

Referensi #

  1. NumPy — Absolute Beginner’s Guide
  2. pandas — API Reference: read_csv