MA1420 · DATA SAINS · SESI 15

Studi Kasus Komprehensif
& Proyek Akhir

Sesi terakhir sebelum UAS. Kita mengintegrasikan seluruh materi — dari pembersihan data hingga machine learning — dalam dua studi kasus nyata, lalu merancang proyek akhir semester yang menunjukkan pemahaman menyeluruh tentang alur kerja data sains.

Studi Kasus 1: Prediksi Nilai Akhir Mahasiswa

STUDI KASUS · 01
Apa yang Menentukan Keberhasilan Mahasiswa?

Universitas X ingin membangun sistem early warning untuk mengidentifikasi mahasiswa yang berisiko tidak lulus sebelum UAS, agar intervensi bimbingan dapat dilakukan tepat waktu.

Regresi + Klasifikasi 500 mahasiswa 12 fitur Data ISTN 3 semester

Data yang Tersedia

FiturTipeContoh NilaiRelevansi
jam_belajar_mingguNumerik2–20 jamLangsung berpengaruh
kehadiran_pctNumerik40–100%Proksi ketekunan
ipk_semester_laluNumerik1.5–4.0Baseline kemampuan
jumlah_sksNumerik15–24 SKSBeban akademik
aktif_forumNumerik0–50 postKeterlibatan belajar
jam_main_hpNumerik1–12 jamPotensi gangguan
kerja_paruh_waktuBiner0 / 1Faktor eksternal
jarak_rumah_kmNumerik1–80 kmFaktor logistik
program_studiKategorikalIF / SI / MathKonteks akademik

Alur Pipeline Lengkap

01
EDA & Audit
Cek distribusi setiap fitur. Temukan: kehadiran_pct memiliki 23 missing value (MCAR), jam_main_hp ada 5 outlier ekstrem (>20 jam). Program studi perlu encoding. df.info() | df.describe() | df.isnull().sum()
02
Cleaning
Imputasi kehadiran_pct dengan median per program_studi. Hapus 3 baris dengan data tidak valid. Cap outlier jam_main_hp di persentil ke-99. SimpleImputer | groupby().transform('median')
03
Feature Eng.
Buat rasio_belajar_hp = jam_belajar / jam_main_hp. Buat beban_relatif = jumlah_sks / 24. One-hot encode program_studi (3 kolom baru). pd.get_dummies() | feature engineering manual
04
Analisis Korelasi
Heatmap korelasi: ipk_semester_lalu (r=0.71) dan kehadiran_pct (r=0.64) korelasi tertinggi dengan nilai_akhir. jam_main_hp (r=−0.58) negatif. Cek VIF — rasio_belajar_hp VIF=8.2 (sedang). df.corr() | variance_inflation_factor()
05
Modeling
Target A: prediksi nilai_akhir (regresi) dengan Linear Regression & Random Forest. Target B: prediksi lulus/tidak (klasifikasi) dengan Logistic Regression & Random Forest. Split 80/20, 5-fold CV. train_test_split | cross_val_score | GridSearchCV
06
Evaluasi & Insight
Evaluasi di test set. Analisis feature importance. Buat rekomendasi kebijakan berdasarkan temuan model. Visualisasi hasil untuk stakeholder non-teknis. classification_report | feature_importances_

Hasil dan Temuan Utama

0.887 R² REGRESI
4.23 MAE (poin)
93.4% AKURASI KLAS.
0.91 F1-SCORE
#1
IPK Semester Lalu (importance: 31%)
Prediktor tunggal terkuat. Mahasiswa dengan IPK <2.5 semester lalu memiliki risiko tidak lulus 3.2× lebih tinggi. Saran: program pendampingan khusus sejak awal semester.
#2
Kehadiran (importance: 24%)
Threshold kritis: mahasiswa dengan kehadiran <60% memiliki probabilitas gagal 78%. Rekomendasi: sistem peringatan otomatis saat kehadiran turun di bawah 65%.
#3
Rasio Belajar/HP (importance: 18%)
Fitur rekayasa yang paling informatif. Rasio <0.5 (lebih banyak HP dari belajar) sangat berkorelasi dengan nilai rendah. Lebih prediktif dari jam belajar saja.
#4
Kerja Paruh Waktu (importance: 8%)
Pengaruh lebih kecil dari dugaan. Mahasiswa yang bekerja tapi punya IPK tinggi sebelumnya tetap bisa berprestasi. Kontekstualisasi penting — jangan diskriminasi.
PYTHON · STUDI KASUS 1 — PIPELINE LENGKAP
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor
from sklearn.linear_model import LinearRegression, LogisticRegression
from sklearn.metrics import r2_score, mean_absolute_error, classification_report
from sklearn.impute import SimpleImputer

np.random.seed(42)
n = 500

# ── Simulasi dataset mahasiswa ────────────────────
ipk_lalu   = np.random.normal(2.9, 0.55, n).clip(1.5, 4.0)
kehadiran  = (50 + 10*ipk_lalu + np.random.normal(0,8,n)).clip(40,100)
jam_belajar= (2  + 2.5*ipk_lalu + np.random.normal(0,2,n)).clip(1,20)
jam_hp     = (8  - jam_belajar + np.random.normal(0,1.5,n)).clip(1,12)
kerja      = np.random.binomial(1, 0.3, n)
prodi      = np.random.choice(['IF','SI','Math'], n)
nilai_akhir= (20 + 12*ipk_lalu + 0.5*kehadiran + 1.5*jam_belajar
              - 1.2*jam_hp - 3*kerja + np.random.normal(0,4,n)).clip(0,100)

df = pd.DataFrame({
    'ipk_lalu': ipk_lalu, 'kehadiran': kehadiran,
    'jam_belajar': jam_belajar, 'jam_hp': jam_hp,
    'kerja': kerja, 'prodi': prodi, 'nilai_akhir': nilai_akhir
})
# Tambahkan missing values buatan
df.loc[np.random.choice(df.index, 23, replace=False), 'kehadiran'] = np.nan

# ── Preprocessing ───────────────────────────────
df['kehadiran'] = df.groupby('prodi')['kehadiran'].transform(
    lambda x: x.fillna(x.median()))
df['rasio_belajar_hp'] = df.'jam_belajar'] / df['jam_hp']
prodi_dummies = pd.get_dummies(df['prodi'], prefix='prodi', drop_first=True)
df = pd.concat([df, prodi_dummies], axis=1)

features = ['ipk_lalu','kehadiran','jam_belajar','jam_hp',
            'kerja','rasio_belajar_hp','prodi_Math','prodi_SI']
X = df[features]
y_reg = df['nilai_akhir']
y_cls = (df['nilai_akhir'] >= 60).astype(int)

X_tr,X_te,yr_tr,yr_te = train_test_split(X, y_reg, test_size=0.2, random_state=42)
sc = StandardScaler()
X_trs = sc.fit_transform(X_tr); X_tes = sc.transform(X_te)

# ── Regresi ─────────────────────────────────────
rf_reg = RandomForestRegressor(200, random_state=42).fit(X_tr, yr_tr)
y_pred = rf_reg.predict(X_te)
print(f"Regresi — R²: {r2_score(yr_te,y_pred):.3f} | MAE: {mean_absolute_error(yr_te,y_pred):.2f}")

# Feature importance
imp = pd.Series(rf_reg.feature_importances_, index=features).sort_values(ascending=False)
print("\nFeature Importance:")
print(imp.round(3))

# ── Klasifikasi ──────────────────────────────────
_,X_te2,yc_tr,yc_te = train_test_split(X, y_cls, test_size=0.2, random_state=42)
rf_cls = RandomForestClassifier(200, random_state=42)
X_all_tr = X.iloc[X_tr.index]
rf_cls.fit(X_tr, y_cls.iloc[X_tr.index])
print("\nKlasifikasi:")
print(classification_report(yc_te, rf_cls.predict(X_te),
      target_names=['Tidak Lulus','Lulus']))

Studi Kasus 2: Segmentasi Nasabah Bank

STUDI KASUS · 02
Siapa Nasabah Kita Sebenarnya?

Bank regional ingin memahami profil nasabah deposito untuk merancang produk yang lebih relevan. Tanpa label yang sudah ada — ini murni eksplorasi dengan unsupervised learning.

K-Means + PCA 2.300 nasabah 8 fitur RFM+

Fitur yang digunakan: saldo_rata_rata, frekuensi_transaksi, recency_hari, usia, lama_menjadi_nasabah_tahun, jumlah_produk, pernah_kredit, nilai_kredit_juta.

Proses: EDA → Scaling → Elbow → K-Means → Profil Cluster → PCA Visualisasi

Cluster A — Sejahtera Aktif (28%)
Saldo tinggi, transaksi sering, multi-produk
Rata-rata saldo Rp 85jt, 42 transaksi/bulan, 3.2 produk. Nasabah premium jangka panjang. Strategi: tawarkan wealth management dan produk investasi eksklusif.
Cluster B — Muda Potensial (35%)
Usia muda, saldo sedang, mulai aktif
Usia rata-rata 28 tahun, saldo Rp 12jt, nasabah baru <2 tahun. Potensi pertumbuhan besar. Strategi: produk tabungan digital, edukasi investasi, cicilan pertama.
Cluster C — Pasif Setia (37%)
Saldo rendah, transaksi jarang, nasabah lama
Lama nasabah 8+ tahun, saldo Rp 3.5jt, transaksi <5/bulan. Mungkin hanya untuk kebutuhan minimum. Strategi: reaktivasi dengan kemudahan mobile banking dan cashback.
PYTHON · STUDI KASUS 2 — SEGMENTASI NASABAH
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
from sklearn.metrics import silhouette_score
from sklearn.preprocessing import StandardScaler
import pandas as pd; import numpy as np

np.random.seed(42)
n = 2300

# Simulasi 3 segmen nasabah bank
data = pd.DataFrame({
  'saldo_jt'      : np.concatenate([np.random.normal(85,20,644),
                     np.random.normal(12,5,805), np.random.normal(3.5,2,851)]).clip(0.5),
  'freq_trx'      : np.concatenate([np.random.normal(42,8,644),
                     np.random.normal(18,5,805), np.random.normal(4,2,851)]).clip(0),
  'recency_hari'   : np.concatenate([np.random.normal(3,1,644),
                     np.random.normal(12,5,805), np.random.normal(60,20,851)]).clip(1),
  'usia'          : np.concatenate([np.random.normal(48,8,644),
                     np.random.normal(28,4,805), np.random.normal(52,10,851)]).clip(18,75),
  'lama_tahun'    : np.concatenate([np.random.normal(9,3,644),
                     np.random.normal(1.5,0.8,805), np.random.normal(8,3,851)]).clip(0.5),
})

# Scaling wajib sebelum clustering
sc = StandardScaler()
X = sc.fit_transform(data)

# Elbow method + Silhouette untuk pilih K
print("K  | Inertia  | Silhouette")
for k in range(2, 7):
    km = KMeans(k, random_state=42, n_init=10).fit(X)
    sil = silhouette_score(X, km.labels_)
    print(f"{k}  | {km.inertia_:8.1f} | {sil:.3f}")

# Model terbaik K=3
km3 = KMeans(3, random_state=42, n_init=10)
data['cluster'] = km3.fit_predict(X)
print("\n=== PROFIL CLUSTER ===")
print(data.groupby('cluster').agg('mean').round(1))

# PCA 2D untuk visualisasi
pca = PCA(2)
X2d = pca.fit_transform(X)
print(f"\nPCA explained variance: {pca.explained_variance_ratio_.round(3)}")
print(f"Total: {pca.explained_variance_ratio_.sum():.1%} informasi tertangkap di 2D")

Panduan Proyek Akhir Semester

Proyek akhir adalah kesempatan menunjukkan kemampuan menerapkan seluruh alur kerja data sains secara mandiri pada dataset pilihan sendiri. Dikerjakan individu atau kelompok maks. 2 orang.

OPSI PROYEK · A
Analisis dan Prediksi — Dataset Publik
Pilih dataset dari Kaggle, UCI ML Repository, BPS, atau portal data pemerintah Indonesia. Lakukan analisis deskriptif lengkap, preprocessing, dan bangun minimal satu model prediksi (supervised). Interpretasikan hasilnya dalam konteks domain.
Notebook Jupyter/Colab (.ipynb) berisi seluruh kode yang berjalan
Laporan PDF 8–12 halaman: latar belakang, EDA, metodologi, hasil, kesimpulan
Presentasi 10 menit + 5 menit tanya jawab
Minimal 500 baris data, minimal 6 fitur yang relevan
Prediksi harga properti Jakarta Klasifikasi penyakit jantung Prediksi churn pelanggan telco
OPSI PROYEK · B
Eksplorasi Segmentasi — Data Tak Berlabel
Gunakan dataset tanpa target yang sudah terdefinisi. Lakukan clustering (K-Means atau DBSCAN), interpretasikan setiap cluster secara bisnis/domain, dan validasi hasilnya dengan Silhouette Score dan profil deskriptif. Wajib visualisasi dengan PCA atau t-SNE.
Notebook Jupyter/Colab dengan kode bersih dan komentar
Laporan PDF 6–10 halaman + visualisasi heatmap dan scatter plot cluster
Presentasi 10 menit berisi narasi bisnis dari temuan cluster
Minimal 3 cluster bermakna dengan profil berbeda-beda
Segmentasi pelanggan e-commerce Pengelompokan kabupaten berdasarkan IPM Klasterisasi pola konsumsi energi
OPSI PROYEK · C
Mini Dashboard Data Sains (Tantangan Ekstra)
Bangun aplikasi sederhana berbasis Streamlit atau Flask yang memungkinkan pengguna mengupload data CSV, melihat statistik deskriptif otomatis, menjalankan clustering atau model prediksi, dan melihat hasilnya dalam visualisasi interaktif. Proyek ini menggabungkan data sains dengan programming.
Kode aplikasi lengkap (app.py + requirements.txt)
Demo live aplikasi saat presentasi (atau video demo 5 menit)
Laporan teknis singkat 4–6 halaman: arsitektur, fitur, keterbatasan
Nilai bonus +10 poin jika berjalan dengan baik Streamlit / Flask

Rubrik Penilaian Proyek Akhir

KomponenBobotA (85–100)B (70–84)C (55–69)
Pemilihan & Pemahaman Data 15% Dataset relevan, EDA sangat mendalam, temukan pola tersembunyi Dataset sesuai, EDA standar, distribusi terdokumentasi Dataset ada, EDA minimal, sedikit eksplorasi
Preprocessing & Feature Engineering 20% Penanganan missing, outlier, encoding tepat. Ada fitur rekayasa inovatif Preprocessing standar, encoding benar, scaling dilakukan Preprocessing minimal, ada langkah yang terlewat
Analisis Statistik 15% Korelasi, distribusi, uji hipotesis relevan digunakan dan diinterpretasikan Analisis korelasi dilakukan, interpretasi dasar ada Statistik deskriptif dasar saja
Pemodelan 25% Beberapa model dibandingkan, cross-validation, hyperparameter tuning, argumen pemilihan model jelas Minimal dua model, evaluasi di test set, metrik yang tepat Satu model, evaluasi ada tapi mungkin tidak tepat
Interpretasi & Insight 15% Insight bermakna untuk domain, rekomendasi actionable, keterbatasan diakui Hasil diinterpretasikan dengan baik dalam konteks domain Hasil dilaporkan tapi interpretasi dangkal
Presentasi & Komunikasi 10% Narasi jelas untuk audiens non-teknis, visualisasi efektif, menjawab pertanyaan dengan baik Presentasi terstruktur, visualisasi ada, jawab pertanyaan dasar Presentasi ada tapi kurang terstruktur

Timeline Proyek

MINGGU 1–2
Pilih Topik & Data
Konfirmasi dataset, tentukan problem statement, bagi tugas (jika kelompok)
MINGGU 3–4
EDA & Preprocessing
Eksplorasi data, cleaning, feature engineering, visualisasi awal
MINGGU 5–6
Pemodelan
Bangun dan evaluasi model, iterasi, tuning, bandingkan beberapa pendekatan
MINGGU 7
Laporan & Slide
Tulis laporan, buat presentasi, review kode dan komentar
MINGGU 8
Presentasi UAS
Jadwal presentasi per kelompok, pengumpulan akhir notebook + laporan

Tips Sukses Proyek

🎯
Mulai dari Pertanyaan Bisnis
Jangan mulai dari "saya punya dataset ini, mau diapakan." Mulai dari "saya ingin tahu apakah X memengaruhi Y" — lalu cari data yang menjawabnya.
📊
EDA Dulu, Model Kemudian
Luangkan 40% waktu untuk eksplorasi data. Distribusi aneh, korelasi tersembunyi, dan outlier sering menjadi insight paling menarik — sebelum ada model sekalipun.
🏗️
Baseline Sederhana Dulu
Mulai dengan Linear/Logistic Regression. Jika model sederhana sudah bagus, kamu bisa argumentasikan kenapa tidak perlu yang kompleks. Jika belum, ada dasar perbandingan.
📝
Dokumentasikan Setiap Keputusan
Mengapa memilih metode imputasi ini? Mengapa drop fitur itu? Mengapa K=3? Jelaskan dalam komentar kode dan laporan. Keputusan yang terjustifikasi > hasil sempurna tanpa penjelasan.
⚠️
Jujur tentang Keterbatasan
Dataset kecil? Mungkin bias? Tidak bisa generalisasi ke daerah lain? Akui keterbatasan ini. Dosen menghargai kejujuran ilmiah lebih dari klaim berlebihan.
🖼️
Ceritakan dengan Visual
Satu grafik yang bagus lebih kuat dari satu paragraf angka. Investasikan waktu untuk visualisasi yang jelas, beri judul dan label yang informatif, gunakan warna secara konsisten.
📌 PENGINGAT PENTING

Pengumpulan: Notebook (.ipynb) + Laporan PDF diunggah ke SIAKAD sebelum hari presentasi. Link repositori GitHub/Drive jika file besar.

Integritas akademik: Kode boleh menggunakan referensi/tutorial, tapi harus dipahami dan dimodifikasi. Copy-paste tanpa pemahaman akan terdeteksi saat tanya jawab.

Pertanyaan: Konsultasi dengan dosen dapat dilakukan melalui portal SIAKAD atau email institusional. Manfaatkan sesi konsultasi sebelum pengumpulan.