Data bersih hasil Bagian 5 sudah siap dihitung, tetapi melompat langsung ke uji statistik membuat kita membaca angka tanpa mengenal watak datanya lebih dulu. Pada bagian ini kita berkeliling dulu tanpa target jawaban: melihat sebaran tiap kolom, membandingkan kedua kelas, lalu mencermati peringkat atas dan bawah untuk menangkap pola awal. Eksplorasi semacam ini sering menemukan hal yang tak terduga sebelum pertanyaan P1-P4 dijawab secara formal pada Bagian 8. Setiap pola yang muncul di sini kita perlakukan sebagai dugaan kerja — bukan kesimpulan — karena statusnya baru akan diperiksa pada analisis formal.
Statistik Deskriptif Sekilas #
Titik berangkat eksplorasi adalah describe() pada ketiga kolom angka — alat baku yang pernah kita pakai di proyek-proyek sebelumnya. Ingat bahwa tiap blok kode pada proyek ini berdiri sendiri, jadi fungsi muat_bersih dari Bagian 5 selalu ikut dituliskan lengkap:
import pandas as pd
def muat_bersih(path):
"""Muat data mentah dan terapkan seluruh langkah pembersihan."""
df = pd.read_csv(path).drop_duplicates().reset_index(drop=True)
df["kelas"] = df["kelas"].str.upper()
df["kehadiran_persen"] = pd.to_numeric(df["kehadiran_persen"].replace("-", pd.NA))
df = df.dropna(subset=["kehadiran_persen"]).reset_index(drop=True)
df["kehadiran_persen"] = df["kehadiran_persen"].astype(int)
return df
bersih = muat_bersih("../data/nilai_siswa.csv")
print("Statistik deskriptif tiga kolom numerik (30 siswa):")
print(bersih[["jam_belajar_mingguan", "kehadiran_persen", "nilai_ujian"]]
.describe().round(2).to_string())Output yang Dihasilkan:
Statistik deskriptif tiga kolom numerik (30 siswa):
jam_belajar_mingguan kehadiran_persen nilai_ujian
count 30.00 30.00 30.00
mean 9.27 81.80 68.73
std 4.19 11.92 12.85
min 2.00 58.00 44.00
25% 6.00 75.00 59.00
50% 9.50 85.00 71.50
75% 12.75 92.00 77.75
max 16.00 96.00 91.00Mari kita baca statistik tersebut satu per satu:
count30 pada ketiga kolom — seluruh baris terisi penuh; pembersihan Bagian 5 memang menyisakan data yang utuh, dan angka ini menjadi bukti sekali lagi di awal analisis.- Rata-rata jam belajar 9,27 per minggu — sekitar satu jam dua puluh menit per hari; kehadiran rata-rata 81,8 persen; nilai rata-rata 68,73, persis angka verifikasi Bagian 5. Konsistensi seperti ini penting: data yang dimuat ulang lewat jalur sama seharusnya menghasilkan angka sama.
- Nilai ujian tersebar lebar —
std12,85 dengan rentang 44 sampai 91. Seperempat siswa terbawah bernilai paling banyak 59, seperempat teratas paling sedikit 78, dan mediannya 71,5. Kelompok seseragam ini biasanya menyimpan hubungan yang menarik untuk diuji. - Jam belajar terentang 2 sampai 16 — jarak delapan kali lipat antara siswa paling ringan (Zaki, 2 jam) dan terberat (Nia dan Farhan, 16 jam). Rentang prediktor yang lebar seperti ini kelak menguntungkan regresi pada P4.
Membandingkan Kedua Kelas #
Pertanyaan P3 menyangkut perbandingan kelas, jadi kita pisahkan statistiknya per kelas sejak sekarang. Tiga keluaran berikut sengaja diringkas agar perbandingannya terbaca langsung:
import pandas as pd
def muat_bersih(path):
"""Muat data mentah dan terapkan seluruh langkah pembersihan."""
df = pd.read_csv(path).drop_duplicates().reset_index(drop=True)
df["kelas"] = df["kelas"].str.upper()
df["kehadiran_persen"] = pd.to_numeric(df["kehadiran_persen"].replace("-", pd.NA))
df = df.dropna(subset=["kehadiran_persen"]).reset_index(drop=True)
df["kehadiran_persen"] = df["kehadiran_persen"].astype(int)
return df
bersih = muat_bersih("../data/nilai_siswa.csv")
print("Rata-rata tiga kolom per kelas:")
print(bersih.groupby("kelas")[
["jam_belajar_mingguan", "kehadiran_persen", "nilai_ujian"]
].mean().round(2).transpose().to_string())
print("\nSebaran nilai ujian per kelas:")
print(bersih.groupby("kelas")["nilai_ujian"].describe().round(2).transpose().to_string())
print("\nRentang jam belajar dan kehadiran per kelas:")
for kolom in ("jam_belajar_mingguan", "kehadiran_persen"):
rentang = bersih.groupby("kelas")[kolom].agg(["min", "max"])
print(f" {kolom}:")
for kelas, baris in rentang.iterrows():
print(f" kelas {kelas}: {baris['min']} sampai {baris['max']}")Output yang Dihasilkan:
Rata-rata tiga kolom per kelas:
kelas A B
jam_belajar_mingguan 9.53 9.00
kehadiran_persen 83.60 80.00
nilai_ujian 70.60 66.87
Sebaran nilai ujian per kelas:
kelas A B
count 15.00 15.00
mean 70.60 66.87
std 13.02 12.85
min 51.00 44.00
25% 60.00 59.00
50% 72.00 71.00
75% 78.50 74.50
max 91.00 87.00
Rentang jam belajar dan kehadiran per kelas:
jam_belajar_mingguan:
kelas A: 3 sampai 16
kelas B: 2 sampai 16
kehadiran_persen:
kelas A: 62 sampai 96
kelas B: 58 sampai 95Perbandingannya memberi tiga kesan awal:
- Rata-rata kedua kelas berdekatan — jam belajar 9,53 lawan 9,00, kehadiran 83,6 lawan 80,0, nilai 70,60 lawan 66,87. Kelas A unggul tipis di ketiganya, tetapi selisihnya kecil dibanding lebar sebaran masing-masing.
- Rentang nilainya saling menumpuk — nilai kelas A membentang 51 sampai 91, kelas B 44 sampai 87. Siswa terbaik kedua kelas nyaris berimpit (87 lawan 91), dan tidak ada celah kosong yang memisahkan kelompoknya. Bila kedua kelas benar-benar berbeda mencolok, rentangnya biasanya berjauhan.
- Median yang hampir sama — 72 lawan 71, dengan kuartil bawah 60 lawan 59. Titik tengah kedua kelompok nyaris bertumpuk, cukup berbeda dari kesan yang timbul bila hanya rata-rata yang dilihat.
Pola Awal dari Peringkat Atas dan Bawah #
Cara paling jujur merasakan pola adalah melihat manusianya. Kita urutkan data menurut nilai ujian, lalu bandingkan lima siswa teratas dengan lima terbawah, dan satukan sepuluh teratas lawan sepuluh terbawah dalam satu hitungan:
import pandas as pd
def muat_bersih(path):
"""Muat data mentah dan terapkan seluruh langkah pembersihan."""
df = pd.read_csv(path).drop_duplicates().reset_index(drop=True)
df["kelas"] = df["kelas"].str.upper()
df["kehadiran_persen"] = pd.to_numeric(df["kehadiran_persen"].replace("-", pd.NA))
df = df.dropna(subset=["kehadiran_persen"]).reset_index(drop=True)
df["kehadiran_persen"] = df["kehadiran_persen"].astype(int)
return df
bersih = muat_bersih("../data/nilai_siswa.csv")
urut = bersih.sort_values("nilai_ujian", ascending=False).reset_index(drop=True)
print("Lima siswa dengan nilai tertinggi:")
print(urut.head(5)[["siswa", "kelas", "jam_belajar_mingguan",
"kehadiran_persen", "nilai_ujian"]].to_string(index=False))
print("\nLima siswa dengan nilai terendah:")
print(urut.tail(5)[["siswa", "kelas", "jam_belajar_mingguan",
"kehadiran_persen", "nilai_ujian"]].to_string(index=False))
atas = urut.head(10)
bawah = urut.tail(10)
print("\nRata-rata 10 nilai tertinggi vs 10 nilai terendah:")
print(f" jam belajar : {atas['jam_belajar_mingguan'].mean():.1f} vs "
f"{bawah['jam_belajar_mingguan'].mean():.1f} jam")
print(f" kehadiran : {atas['kehadiran_persen'].mean():.1f} vs "
f"{bawah['kehadiran_persen'].mean():.1f} persen")Output yang Dihasilkan:
Lima siswa dengan nilai tertinggi:
siswa kelas jam_belajar_mingguan kehadiran_persen nilai_ujian
Nia A 16 96 91
Budi A 15 95 87
Farhan B 16 95 87
Bima B 15 94 83
Fajar A 14 90 82
Lima siswa dengan nilai terendah:
siswa kelas jam_belajar_mingguan kehadiran_persen nilai_ujian
Luki A 4 65 51
Hadi A 3 62 51
Wulan B 4 60 50
Zaki B 2 58 48
Elsa B 3 64 44
Rata-rata 10 nilai tertinggi vs 10 nilai terendah:
jam belajar : 13.3 vs 4.7 jam
kehadiran : 90.7 vs 68.5 persenTiga pola awal menonjol dari tabel tersebut:
- Peringkat atas dan bawah terpisah jelas pada kebiasaan belajar — lima teratas seluruhnya belajar 14 jam atau lebih dengan kehadiran di atas 90 persen; lima terbawah seluruhnya belajar 4 jam atau kurang dengan kehadiran di bawah 66 persen. Dalam bentuk ringkasnya, sepuluh teratas rata-rata belajar 13,3 jam sedangkan sepuluh terbawah hanya 4,7 jam.
- Kedua kelas hadir di kedua ujung peringkat — tiga siswa kelas A dan dua kelas B mengisi lima teratas; dua kelas A dan tiga kelas B mengisi lima terbawah. Sekali lagi tidak tampak pemisahan menurut kelas, memperkuat dugaan awal kita tentang P3.
- Kehadiran tinggi tidak menjamin nilai tinggi — Tono hadir 92 persen tetapi bernilai 64, dan Maya hadir 95 persen tetapi bernilai 72; keduanya di tengah tabel. Sebaliknya, seluruh siswa dengan kehadiran di bawah 70 persen bernilai paling banyak 54. Pola ini mengisyaratkan jam belajar lebih membedakan nasib nilai dibanding kehadiran — dugaan yang akan diuji berimbang pada P1 dan P2.
Peta awal sudah terbentang: kebiasaan belajar berjalan seiring dengan nilai, sementara kelas hampir tidak membawa beda. Dugaan-dugaan ini tidak boleh dibiarkan sebagai kesan — pertanyaan berikutnya adalah teknik analisis mana yang layak mengujinya secara formal, dan itulah pekerjaan Bagian 7: Memilih Teknik Analisis .