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
Universitas X ingin membangun sistem early warning untuk mengidentifikasi mahasiswa yang berisiko tidak lulus sebelum UAS, agar intervensi bimbingan dapat dilakukan tepat waktu.
Data yang Tersedia
| Fitur | Tipe | Contoh Nilai | Relevansi |
|---|---|---|---|
| jam_belajar_minggu | Numerik | 2–20 jam | Langsung berpengaruh |
| kehadiran_pct | Numerik | 40–100% | Proksi ketekunan |
| ipk_semester_lalu | Numerik | 1.5–4.0 | Baseline kemampuan |
| jumlah_sks | Numerik | 15–24 SKS | Beban akademik |
| aktif_forum | Numerik | 0–50 post | Keterlibatan belajar |
| jam_main_hp | Numerik | 1–12 jam | Potensi gangguan |
| kerja_paruh_waktu | Biner | 0 / 1 | Faktor eksternal |
| jarak_rumah_km | Numerik | 1–80 km | Faktor logistik |
| program_studi | Kategorikal | IF / SI / Math | Konteks akademik |
Alur Pipeline Lengkap
Hasil dan Temuan Utama
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
Bank regional ingin memahami profil nasabah deposito untuk merancang produk yang lebih relevan. Tanpa label yang sudah ada — ini murni eksplorasi dengan unsupervised learning.
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
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.
Rubrik Penilaian Proyek Akhir
| Komponen | Bobot | A (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
Tips Sukses Proyek
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.