Bulan 12: Capstone Project
Saatnya Abbas menyatukan semua yang dipelajari selama 11 bulan ke dalam satu proyek analisis data yang utuh, bermakna, dan siap dipresentasikan ke dunia.
Apa yang Abbas Capai di Bulan Ini
Bulan 12 adalah puncak dari perjalanan satu tahun Abbas. Tidak ada topik baru yang diperkenalkan dari nol. Sebaliknya, semua keterampilan dari Python, statistik, SQL, visualisasi, machine learning, hingga dashboard akan digabungkan dalam satu proyek capstone yang sepenuhnya dipilih dan dikerjakan oleh Abbas sendiri.
Di akhir bulan ini, Abbas akan memiliki satu proyek yang bisa ditunjukkan kepada siapa saja, baik guru, orang tua, maupun calon pemberi kerja atau kampus impian.
Kompetensi yang Dibuktikan di Bulan 12
- Merumuskan pertanyaan riset atau bisnis yang spesifik, terukur, dan relevan dari konteks kehidupan nyata
- Mencari, mengevaluasi, dan mengakuisisi dataset dari sumber terbuka seperti Kaggle, BPS, atau data primer sendiri
- Melakukan eksplorasi data (EDA) secara sistematis: distribusi, outlier, missing values, dan korelasi antar variabel
- Membersihkan dan mentransformasi data menggunakan Pandas hingga siap dianalisis tanpa kebocoran informasi
- Menerapkan minimal satu metode statistik inferensial atau model machine learning yang sesuai dengan pertanyaan riset
- Membangun visualisasi dan dashboard yang ringkas namun informatif, dapat dipahami oleh audiens non-teknis
- Menyusun narasi analitis yang menghubungkan temuan data dengan konteks nyata dan rekomendasi yang actionable
- Mempresentasikan proyek secara lisan dengan percaya diri, menjawab pertanyaan, dan menjelaskan keterbatasan analisis
Minggu 1: Perencanaan Capstone
Minggu pertama sepenuhnya didedikasikan untuk perencanaan yang matang. Abbas akan memilih topik, merumuskan problem statement, mencari data, dan menyusun rencana kerja empat minggu.
Abbas memulai dengan menulis daftar pertanyaan yang selama ini membuatnya penasaran. Pertanyaan itu bisa berasal dari kehidupan sekolah, lingkungan sekitar, olahraga, musik, atau isu sosial yang Abbas pedulikan.
- Tulis minimal 10 pertanyaan riset kandidat dalam format: "Apakah X berhubungan dengan Y di konteks Z?"
- Kelompokkan pertanyaan berdasarkan domain: pendidikan, lingkungan, ekonomi, olahraga, budaya
- Evaluasi setiap kandidat: apakah datanya bisa ditemukan? Apakah pertanyaannya bisa dijawab dengan analisis data?
- Pilih 2-3 kandidat terkuat untuk dievaluasi lebih lanjut besok
# Template evaluasi kandidat topik capstone
# Jalankan di Jupyter Notebook untuk mendokumentasikan pilihan
kandidat_topik = [
{
"topik": "Hubungan suhu udara dengan penjualan minuman di kantin sekolah",
"domain": "ekonomi + lingkungan",
"pertanyaan_utama": "Apakah hari yang lebih panas meningkatkan penjualan minuman dingin?",
"data_tersedia": "Ya - data kantin SMM + data BMKG",
"kompleksitas": "Sedang",
"relevansi_pribadi": "Tinggi - Abbas tahu pola ini dari pengamatan langsung",
"feasibility_score": 8 # skala 1-10
},
{
"topik": "Tren nilai ujian nasional berdasarkan wilayah Indonesia",
"domain": "pendidikan",
"pertanyaan_utama": "Apakah ada kesenjangan nilai antara sekolah di kota dan daerah?",
"data_tersedia": "Ya - data BPS dan Kemdikbud",
"kompleksitas": "Tinggi",
"relevansi_pribadi": "Sedang",
"feasibility_score": 6
}
]
for k in kandidat_topik:
print(f"Topik: {k['topik']}")
print(f" Pertanyaan: {k['pertanyaan_utama']}")
print(f" Feasibility: {k['feasibility_score']}/10")
print()
Setelah memilih topik, Abbas akan mengasah pertanyaan riset menjadi problem statement yang spesifik, terukur, dan dapat dijawab dengan data. Problem statement yang kabur adalah penyebab utama proyek capstone yang melebar tanpa arah.
- Pelajari perbedaan antara pertanyaan deskriptif, diagnostik, prediktif, dan preskriptif
- Tulis problem statement menggunakan kerangka: Siapa, Apa masalahnya, Mengapa penting, Apa yang ingin diketahui
- Identifikasi variabel dependen dan independen utama dalam analisis Abbas
- Buat daftar hipotesis awal sebelum melihat data, minimal 3 hipotesis
# Kerangka problem statement capstone
# Simpan sebagai README.md di folder proyek Abbas
problem_statement = """
CAPSTONE PROJECT - DATA ANALYST ABBAS
JUDUL: [Judul singkat dan deskriptif]
LATAR BELAKANG:
[2-3 kalimat konteks mengapa topik ini penting dan relevan]
PERTANYAAN RISET UTAMA:
[1 pertanyaan spesifik yang ingin dijawab]
PERTANYAAN PENDUKUNG:
1. [Sub-pertanyaan 1]
2. [Sub-pertanyaan 2]
3. [Sub-pertanyaan 3]
HIPOTESIS AWAL:
H1: [Prediksi pertama sebelum melihat data]
H2: [Prediksi kedua]
H3: [Prediksi ketiga]
VARIABEL:
- Dependen (Y): [Apa yang ingin diprediksi atau dijelaskan]
- Independen (X): [Faktor-faktor yang mungkin memengaruhi Y]
TARGET AUDIENS PRESENTASI:
[Siapa yang akan mendengar hasil ini: guru, orang tua, teman, dll]
DEFINISI SUKSES:
[Bagaimana Abbas tahu proyek ini berhasil?]
"""
print(problem_statement)
# Salin ke file README.md di folder capstone
Hari ini Abbas akan berburu data. Ini adalah salah satu keterampilan paling berharga seorang data analyst: tahu di mana data berada dan bagaimana mengevaluasi kualitasnya sebelum membuang waktu menganalisis data yang buruk.
- Eksplorasi sumber data terbuka: Kaggle, BPS Indonesia, data.go.id, WHO, World Bank, Google Dataset Search
- Untuk setiap dataset kandidat: cek jumlah baris, kolom, tahun, lisensi, dan apakah pertanyaan Abbas bisa dijawab
- Unduh minimal 2 dataset kandidat dan lakukan inspeksi awal dengan Pandas
- Dokumentasikan sumber, URL, tanggal unduh, dan lisensi penggunaan setiap dataset
import pandas as pd
import os
# Inspeksi awal dataset kandidat
def inspeksi_dataset(filepath, nama_dataset):
"""
Fungsi untuk evaluasi cepat kualitas dataset
"""
df = pd.read_csv(filepath)
print(f"=== {nama_dataset} ===")
print(f"Ukuran: {df.shape[0]:,} baris x {df.shape[1]} kolom")
print(f"\nKolom dan tipe data:")
print(df.dtypes)
print(f"\nMissing values per kolom:")
missing = df.isnull().sum()
missing_pct = (missing / len(df) * 100).round(1)
print(pd.DataFrame({'missing': missing, 'persen': missing_pct})[missing > 0])
print(f"\nContoh 3 baris pertama:")
print(df.head(3))
print(f"\nStatistik dasar kolom numerik:")
print(df.describe().round(2))
print("\n" + "="*50 + "\n")
return df
# Contoh penggunaan
# df1 = inspeksi_dataset("data/dataset_kandidat_1.csv", "Dataset A")
# df2 = inspeksi_dataset("data/dataset_kandidat_2.csv", "Dataset B")
Proyek yang baik dimulai dari struktur yang rapi. Abbas akan menyiapkan folder proyek, membuat rencana kerja empat minggu, dan melakukan commit pertama ke GitHub.
- Buat struktur folder proyek capstone yang standar dan konsisten
- Susun timeline kerja: apa yang harus selesai di setiap minggu
- Inisialisasi repository GitHub untuk proyek capstone dan lakukan commit pertama
- Tulis README.md dengan problem statement, struktur folder, dan rencana kerja
# Struktur folder capstone yang direkomendasikan
# Jalankan perintah ini di terminal untuk membuat struktur
"""
capstone-abbas/
โโโ README.md # Problem statement dan dokumentasi proyek
โโโ data/
โ โโโ raw/ # Data asli, jangan pernah diubah
โ โโโ processed/ # Data setelah cleaning
โ โโโ external/ # Data tambahan dari sumber lain
โโโ notebooks/
โ โโโ 01_eksplorasi.ipynb # EDA awal
โ โโโ 02_cleaning.ipynb # Data cleaning
โ โโโ 03_analisis.ipynb # Analisis utama
โ โโโ 04_model.ipynb # Model (jika ada)
โโโ output/
โ โโโ figures/ # Grafik dan visualisasi
โ โโโ tables/ # Tabel ringkasan
โโโ dashboard/ # File dashboard (jika ada)
โโโ presentasi/ # Slide atau dokumen presentasi
"""
# Buat folder dengan Python
import os
folders = [
"capstone-abbas/data/raw",
"capstone-abbas/data/processed",
"capstone-abbas/data/external",
"capstone-abbas/notebooks",
"capstone-abbas/output/figures",
"capstone-abbas/output/tables",
"capstone-abbas/dashboard",
"capstone-abbas/presentasi"
]
for folder in folders:
os.makedirs(folder, exist_ok=True)
print(f"Dibuat: {folder}")
print("\nStruktur proyek siap!")
Hari terakhir minggu pertama adalah untuk refleksi dan finalisasi. Abbas mengunci keputusan topik, dataset, dan rencana kerja sebelum mulai eksekusi di minggu depan.
- Baca ulang problem statement dan pastikan masih bisa dijawab dengan data yang sudah ditemukan
- Identifikasi risiko terbesar: apa yang bisa menghambat proyek dan bagaimana antisipasinya
- Tulis checklist minggu 2-4: apa saja output yang harus ada setiap minggu
- Minta feedback dari satu orang, bisa orang tua, teman, atau guru, tentang topik dan rencana kerja Abbas
# Checklist kesiapan sebelum mulai eksekusi
# Simpan sebagai planning_checklist.md
checklist_minggu1 = {
"topik_terpilih": False,
"problem_statement_ditulis": False,
"hipotesis_awal_ada": False,
"dataset_utama_diunduh": False,
"inspeksi_awal_dataset_selesai": False,
"struktur_folder_dibuat": False,
"github_repo_dibuat": False,
"readme_ditulis": False,
"rencana_4_minggu_ada": False,
"risiko_diidentifikasi": False
}
selesai = sum(1 for v in checklist_minggu1.values() if v)
total = len(checklist_minggu1)
persen = selesai / total * 100
print(f"Kesiapan Minggu 1: {selesai}/{total} ({persen:.0f}%)")
print()
for item, status in checklist_minggu1.items():
ikon = "v" if status else "o"
label = item.replace("_", " ").capitalize()
print(f" [{ikon}] {label}")
if persen < 80:
print("\nPerhatian: Selesaikan checklist sebelum lanjut ke minggu 2.")
else:
print("\nBagus! Abbas siap mulai eksekusi di minggu 2.")
Minggu 2: Data Acquisition dan Eksplorasi Data
Dengan perencanaan yang matang di tangan, Abbas sekarang terjun ke dalam data. Minggu ini fokus pada akuisisi data yang lengkap, pembersihan awal, dan eksplorasi yang sistematis untuk memahami apa yang sebenarnya ada di dalam dataset sebelum menganalisis.
Abbas mengumpulkan semua data yang dibutuhkan, baik dataset utama maupun data pendukung, lalu mendokumentasikan setiap sumber dengan teliti. Data tanpa dokumentasi sumber tidak bisa dipercaya.
- Unduh atau kumpulkan semua dataset yang direncanakan, termasuk data primer jika ada survei atau observasi
- Buat file
data/sources.mdberisi nama dataset, URL, tanggal akses, lisensi, dan deskripsi singkat - Salin semua file mentah ke folder
data/raw/dan jangan pernah mengubah file di folder ini - Lakukan loading awal semua dataset dan catat ukuran serta format masing-masing
import pandas as pd
# Dokumentasi sumber data secara programatik
sumber_data = [
{
"nama": "Dataset Utama",
"file": "data/raw/dataset_utama.csv",
"url": "https://www.kaggle.com/datasets/...", # ganti dengan URL asli
"tanggal_akses": "2025-12-01",
"lisensi": "CC0: Public Domain",
"deskripsi": "Berisi data [X] dari tahun [Y] hingga [Z]",
"jumlah_baris": None,
"jumlah_kolom": None
},
{
"nama": "Data Pendukung",
"file": "data/raw/data_pendukung.csv",
"url": "https://bps.go.id/...",
"tanggal_akses": "2025-12-01",
"lisensi": "Open Government Data",
"deskripsi": "Data kontekstual dari BPS untuk [variabel Z]",
"jumlah_baris": None,
"jumlah_kolom": None
}
]
# Load dan catat ukuran setiap dataset
for s in sumber_data:
try:
df = pd.read_csv(s["file"])
s["jumlah_baris"] = df.shape[0]
s["jumlah_kolom"] = df.shape[1]
print(f"[OK] {s['nama']}: {df.shape[0]:,} baris x {df.shape[1]} kolom")
except FileNotFoundError:
print(f"[TIDAK DITEMUKAN] {s['file']}")
print("\nSemua dataset tercatat. Simpan dokumentasi ini ke data/sources.md")
raw/. Semua transformasi dilakukan di notebook dan disimpan ke data/processed/. Ini memastikan Abbas bisa selalu kembali ke titik awal jika ada kesalahan.
Hari ini Abbas menyelami isi dataset secara menyeluruh. Tujuannya bukan untuk membersihkan data dulu, tapi untuk memahami karakter data sebelum memutuskan tindakan apa yang perlu diambil.
- Periksa distribusi setiap kolom numerik: apakah normal, skewed kanan, skewed kiri, atau bimodal?
- Hitung persentase missing values per kolom dan putuskan strategi penanganannya
- Deteksi outlier menggunakan IQR method dan visualisasikan dengan boxplot
- Cek apakah ada duplikat baris dan identifikasi kolom yang mungkin menjadi ID unik
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
df = pd.read_csv("data/raw/dataset_utama.csv")
# 1. Ringkasan komprehensif
print("=== RINGKASAN DATASET ===")
print(f"Dimensi: {df.shape}")
print(f"Duplikat: {df.duplicated().sum()} baris")
print()
# 2. Missing values dengan persentase
missing = pd.DataFrame({
"jumlah_missing": df.isnull().sum(),
"persen_missing": (df.isnull().sum() / len(df) * 100).round(1)
}).sort_values("persen_missing", ascending=False)
print("=== MISSING VALUES ===")
print(missing[missing["jumlah_missing"] > 0])
print()
# 3. Deteksi outlier dengan IQR
def deteksi_outlier_iqr(series):
Q1 = series.quantile(0.25)
Q3 = series.quantile(0.75)
IQR = Q3 - Q1
batas_bawah = Q1 - 1.5 * IQR
batas_atas = Q3 + 1.5 * IQR
outlier = series[(series < batas_bawah) | (series > batas_atas)]
return len(outlier), batas_bawah, batas_atas
print("=== OUTLIER PER KOLOM NUMERIK ===")
kolom_numerik = df.select_dtypes(include="number").columns
for col in kolom_numerik:
n_out, b_bawah, b_atas = deteksi_outlier_iqr(df[col].dropna())
print(f" {col}: {n_out} outlier (batas: {b_bawah:.2f} - {b_atas:.2f})")
# 4. Visualisasi distribusi
fig, axes = plt.subplots(1, min(3, len(kolom_numerik)), figsize=(15, 4))
for i, col in enumerate(kolom_numerik[:3]):
df[col].hist(ax=axes[i], bins=30, edgecolor="white")
axes[i].set_title(col)
plt.suptitle("Distribusi Kolom Numerik")
plt.tight_layout()
plt.savefig("output/figures/distribusi_awal.png", dpi=150)
plt.show()
Setelah memahami setiap variabel secara terpisah, Abbas mulai melihat hubungan antar variabel. Ini adalah tahap di mana hipotesis awal mulai diuji secara visual sebelum analisis statistik formal.
- Buat heatmap korelasi untuk semua variabel numerik dan interpretasikan hasilnya
- Buat scatter plot antara variabel dependen dan setiap variabel independen utama
- Jika ada variabel kategorikal, buat boxplot atau barplot untuk melihat perbedaan antar grup
- Tulis catatan untuk setiap hubungan yang ditemukan: apakah sesuai hipotesis, berlawanan, atau tidak ada pola?
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
df = pd.read_csv("data/raw/dataset_utama.csv")
kolom_numerik = df.select_dtypes(include="number").columns.tolist()
# 1. Heatmap korelasi
fig, ax = plt.subplots(figsize=(10, 8))
matriks_korelasi = df[kolom_numerik].corr()
mask = np.triu(np.ones_like(matriks_korelasi, dtype=bool))
sns.heatmap(
matriks_korelasi,
mask=mask,
annot=True,
fmt=".2f",
cmap="coolwarm",
center=0,
ax=ax,
square=True
)
ax.set_title("Matriks Korelasi Antar Variabel Numerik")
plt.tight_layout()
plt.savefig("output/figures/heatmap_korelasi.png", dpi=150)
plt.show()
# 2. Temukan pasangan korelasi tertinggi
korelasi_pairs = []
for i in range(len(matriks_korelasi.columns)):
for j in range(i+1, len(matriks_korelasi.columns)):
col1 = matriks_korelasi.columns[i]
col2 = matriks_korelasi.columns[j]
r = matriks_korelasi.loc[col1, col2]
korelasi_pairs.append({"var1": col1, "var2": col2, "korelasi": r})
df_korelasi = pd.DataFrame(korelasi_pairs)
df_korelasi["abs_korelasi"] = df_korelasi["korelasi"].abs()
print("10 Pasangan Variabel dengan Korelasi Tertinggi:")
print(df_korelasi.nlargest(10, "abs_korelasi")[["var1", "var2", "korelasi"]])
Dengan pemahaman mendalam tentang karakter data, Abbas sekarang melakukan pembersihan yang tepat sasaran. Setiap keputusan cleaning harus didokumentasikan dengan alasan yang jelas.
- Tangani missing values dengan strategi yang sesuai: imputasi median untuk numerik, modus untuk kategorikal, atau hapus baris jika missing terlalu banyak
- Tangani outlier: keputusan apakah di-clip, dihapus, atau dibiarkan harus didokumentasikan
- Standardisasi format teks: hapus spasi ekstra, seragamkan kapitalisasi, perbaiki typo pada kolom kategorikal
- Simpan dataset bersih ke
data/processed/dataset_bersih.csvdan bandingkan ukurannya dengan data mentah
import pandas as pd
import numpy as np
df_raw = pd.read_csv("data/raw/dataset_utama.csv")
df = df_raw.copy() # selalu bekerja dengan salinan
print(f"Ukuran awal: {df.shape}")
# Log setiap perubahan
log_cleaning = []
# 1. Hapus duplikat
n_duplikat = df.duplicated().sum()
df = df.drop_duplicates()
log_cleaning.append(f"Hapus {n_duplikat} baris duplikat")
# 2. Imputasi missing values numerik dengan median
kolom_numerik = df.select_dtypes(include="number").columns
for col in kolom_numerik:
n_missing = df[col].isnull().sum()
if n_missing > 0:
median_val = df[col].median()
df[col] = df[col].fillna(median_val)
log_cleaning.append(
f"Imputasi {n_missing} missing di '{col}' dengan median ({median_val:.2f})"
)
# 3. Standardisasi kolom teks (ganti dengan nama kolom aktual)
# kolom_teks = ["kategori", "wilayah"]
# for col in kolom_teks:
# if col in df.columns:
# df[col] = df[col].str.strip().str.title()
# log_cleaning.append(f"Standardisasi format teks kolom '{col}'")
# 4. Simpan hasil
df.to_csv("data/processed/dataset_bersih.csv", index=False)
print(f"Ukuran akhir: {df.shape}")
print()
print("=== LOG CLEANING ===")
for i, log in enumerate(log_cleaning, 1):
print(f" {i}. {log}")
Hari terakhir minggu kedua adalah untuk merangkum semua temuan EDA menjadi narasi yang kohesif dan mendorong semua progres ke GitHub. Abbas juga memperbarui rencana analisis berdasarkan apa yang ditemukan dari data.
- Tulis ringkasan EDA dalam format Markdown: minimal 5 temuan utama dengan visualisasi pendukung
- Perbarui hipotesis: mana yang masih relevan, mana yang perlu direvisi berdasarkan temuan EDA
- Commit semua notebook, data processed, dan visualisasi ke GitHub dengan pesan commit yang deskriptif
- Rencanakan analisis untuk minggu 3: metode statistik atau model apa yang akan digunakan
# Template ringkasan EDA untuk notebook
# Salin ke sel Markdown di akhir notebook 01_eksplorasi.ipynb
ringkasan_eda = """
# Ringkasan Temuan EDA
## Dataset
- Sumber: [nama sumber]
- Ukuran awal: [X] baris x [Y] kolom
- Ukuran setelah cleaning: [X] baris x [Y] kolom
## Temuan Utama
**1. [Judul Temuan 1]**
[Deskripsi 2-3 kalimat. Sertakan angka spesifik.]
Implikasi: [Apa artinya untuk analisis Abbas?]
**2. [Judul Temuan 2]**
[Deskripsi]
Implikasi: [...]
**3. [Judul Temuan 3]**
[Deskripsi]
Implikasi: [...]
**4. [Judul Temuan 4]**
[Deskripsi]
Implikasi: [...]
**5. [Judul Temuan 5]**
[Deskripsi]
Implikasi: [...]
## Revisi Hipotesis Setelah EDA
| Hipotesis | Status | Alasan |
|-----------|--------|--------|
| H1: [teks] | Masih relevan / Perlu revisi / Ditolak | [alasan] |
| H2: [teks] | ... | ... |
| H3: [teks] | ... | ... |
## Rencana Analisis Minggu 3
- Metode utama: [nama metode]
- Variabel yang akan dianalisis: [daftar]
- Pertanyaan yang masih belum terjawab: [daftar]
"""
print(ringkasan_eda)
Minggu 3 - Analisis dan Modeling
Capstone: analisis dan modeling untuk menjawab semua research questions
Abbas menentukan metode analisis yang paling sesuai untuk setiap research question yang sudah dirumuskan. Tidak semua pertanyaan butuh model kompleks; kadang statistik deskriptif dan visualisasi sudah cukup untuk memberikan insight yang kuat.
- Review 3 research questions capstone dan tentukan jenis analisis untuk masing-masing
- Buat decision matrix: RQ vs metode (deskriptif, inferensial, prediktif, atau clustering)
- Identifikasi variabel dependen dan independen untuk setiap RQ
- Cek asumsi statistik: distribusi data, outlier, missing values yang masih perlu ditangani
- Dokumentasikan justifikasi pemilihan metode di notebook
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats
# Load data hasil EDA minggu lalu
df = pd.read_csv("data/clean_capstone.csv")
# Fungsi bantu: cek asumsi normalitas untuk variabel numerik
def cek_normalitas(series, nama_kolom):
stat, p_value = stats.shapiro(series.dropna().sample(min(50, len(series)), random_state=42))
print(f"{nama_kolom}: W={stat:.4f}, p={p_value:.4f} --> {'Normal' if p_value > 0.05 else 'Tidak Normal'}")
cols_numerik = df.select_dtypes(include=[np.number]).columns
for col in cols_numerik:
cek_normalitas(df[col], col)
# Matriks korelasi untuk RQ yang melibatkan hubungan antar variabel
plt.figure(figsize=(10, 8))
corr_matrix = df[cols_numerik].corr()
sns.heatmap(corr_matrix, annot=True, fmt=".2f", cmap="coolwarm", center=0,
linewidths=0.5, square=True)
plt.title("Matriks Korelasi - Variabel Numerik Capstone")
plt.tight_layout()
plt.savefig("output/heatmap_korelasi.png", dpi=150)
plt.show()
print("Korelasi tertinggi:")
print(corr_matrix.unstack().sort_values(ascending=False).drop_duplicates().head(10))
Abbas menjalankan analisis statistik untuk dua research question pertama. Fokus hari ini adalah mendapatkan angka yang dapat diinterpretasikan, bukan sekadar menjalankan fungsi. Setiap hasil harus diikuti penjelasan maknanya dalam konteks dataset.
- Jalankan analisis untuk RQ1: gunakan groupby, agregasi, atau uji hipotesis sesuai jenis pertanyaan
- Visualisasikan hasil RQ1 dengan grafik yang paling komunikatif (bar, box, scatter, dll)
- Jalankan analisis untuk RQ2 dengan metode yang sudah dipilih kemarin
- Tulis interpretasi naratif di markdown cell: "Temuan ini menunjukkan bahwa..."
- Simpan semua grafik ke folder output dengan nama file yang deskriptif
# Contoh: RQ1 - apakah ada perbedaan signifikan antar kelompok?
# Ganti 'kategori' dan 'nilai' sesuai kolom dataset Abbas
# Analisis deskriptif per kelompok
ringkasan_rq1 = df.groupby("kategori")["nilai"].agg(
jumlah="count",
rata_rata="mean",
median="median",
std_deviasi="std",
min="min",
max="max"
).round(2)
print("=== Ringkasan RQ1 ===")
print(ringkasan_rq1)
# Uji Kruskal-Wallis jika data tidak normal dan > 2 kelompok
kelompok = [group["nilai"].dropna().values for _, group in df.groupby("kategori")]
h_stat, p_val = stats.kruskal(*kelompok)
print(f"
Uji Kruskal-Wallis: H={h_stat:.4f}, p={p_val:.4f}")
if p_val < 0.05:
print("Ada perbedaan signifikan antar kelompok (p < 0.05)")
else:
print("Tidak ada perbedaan signifikan antar kelompok (p >= 0.05)")
# Visualisasi RQ1
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
df.groupby("kategori")["nilai"].mean().plot(kind="bar", ax=axes[0], color="steelblue", edgecolor="white")
axes[0].set_title("Rata-rata Nilai per Kategori (RQ1)")
axes[0].set_xlabel("Kategori")
axes[0].set_ylabel("Rata-rata")
axes[0].tick_params(axis="x", rotation=45)
df.boxplot(column="nilai", by="kategori", ax=axes[1])
axes[1].set_title("Distribusi Nilai per Kategori (RQ1)")
axes[1].set_xlabel("Kategori")
axes[1].set_ylabel("Nilai")
plt.tight_layout()
plt.savefig("output/rq1_analisis.png", dpi=150)
plt.show()
Hari ini Abbas masuk ke modeling: membangun model prediktif atau clustering untuk menjawab research question ketiga. Model tidak harus sempurna di iterasi pertama; yang penting adalah siklus build, evaluate, dan improve yang terdokumentasi dengan baik.
- Tentukan target variabel (supervised) atau tujuan pengelompokan (unsupervised)
- Split data: train/test 80:20 jika supervised, atau tentukan jumlah cluster yang masuk akal
- Bangun baseline model dengan parameter default
- Evaluasi dengan metrik yang relevan: R2/RMSE untuk regresi, accuracy/F1 untuk klasifikasi, silhouette score untuk clustering
- Catat hasil di tabel perbandingan model di notebook
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, LogisticRegression
from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor
from sklearn.metrics import mean_squared_error, r2_score, classification_report, confusion_matrix
import warnings
warnings.filterwarnings("ignore")
# Persiapan fitur
features = ["fitur_1", "fitur_2", "fitur_3"] # sesuaikan dengan dataset Abbas
target = "target_kolom"
X = df[features].dropna()
y = df.loc[X.index, target]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Scaling
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# Baseline model (pilih sesuai jenis target)
model_baseline = RandomForestRegressor(n_estimators=100, random_state=42)
model_baseline.fit(X_train_scaled, y_train)
y_pred = model_baseline.predict(X_test_scaled)
rmse = np.sqrt(mean_squared_error(y_test, y_pred))
r2 = r2_score(y_test, y_pred)
cv_scores = cross_val_score(model_baseline, X_train_scaled, y_train, cv=5, scoring="r2")
print("=== Evaluasi Model Baseline (Random Forest) ===")
print(f"RMSE : {rmse:.4f}")
print(f"R2 : {r2:.4f}")
print(f"CV R2 : {cv_scores.mean():.4f} (+/- {cv_scores.std():.4f})")
# Feature importance
feat_imp = pd.Series(model_baseline.feature_importances_, index=features).sort_values(ascending=False)
plt.figure(figsize=(8, 4))
feat_imp.plot(kind="bar", color="teal")
plt.title("Feature Importance - Model RQ3")
plt.ylabel("Importance Score")
plt.tight_layout()
plt.savefig("output/rq3_feature_importance.png", dpi=150)
plt.show()
Abbas memperbaiki model dari hari sebelumnya melalui hyperparameter tuning dan memvalidasi bahwa semua temuan dari ketiga RQ konsisten satu sama lain. Inkonsistensi adalah sinyal bahwa ada asumsi yang perlu dikaji ulang.
- Jalankan GridSearchCV atau RandomizedSearchCV untuk model RQ3
- Bandingkan performa baseline vs tuned model secara visual
- Cross-check: apakah temuan RQ1, RQ2, dan RQ3 saling mendukung atau ada kontradiksi?
- Jika ada kontradiksi, dokumentasikan hipotesis mengapa hal itu bisa terjadi
- Simpan model terbaik dengan joblib untuk digunakan di demo day
from sklearn.model_selection import RandomizedSearchCV
import joblib
# Definisi parameter grid untuk tuning
param_dist = {
"n_estimators": [50, 100, 200, 300],
"max_depth": [None, 5, 10, 20],
"min_samples_split": [2, 5, 10],
"min_samples_leaf": [1, 2, 4],
"max_features": ["sqrt", "log2", None]
}
# RandomizedSearchCV lebih cepat dari GridSearch untuk banyak parameter
search = RandomizedSearchCV(
RandomForestRegressor(random_state=42),
param_distributions=param_dist,
n_iter=20,
cv=5,
scoring="r2",
random_state=42,
n_jobs=-1,
verbose=0
)
search.fit(X_train_scaled, y_train)
best_model = search.best_estimator_
y_pred_tuned = best_model.predict(X_test_scaled)
rmse_tuned = np.sqrt(mean_squared_error(y_test, y_pred_tuned))
r2_tuned = r2_score(y_test, y_pred_tuned)
print("=== Perbandingan Baseline vs Tuned ===")
print(f"{'Metrik':<12} {'Baseline':>12} {'Tuned':>12} {'Delta':>12}")
print("-" * 50)
print(f"{'RMSE':<12} {rmse:>12.4f} {rmse_tuned:>12.4f} {(rmse-rmse_tuned):>+12.4f}")
print(f"{'R2':<12} {r2:>12.4f} {r2_tuned:>12.4f} {(r2_tuned-r2):>+12.4f}")
print(f"
Parameter terbaik: {search.best_params_}")
# Simpan model
joblib.dump(best_model, "models/model_rq3_final.pkl")
joblib.dump(scaler, "models/scaler_rq3.pkl")
print("
Model disimpan ke models/")
Abbas menyatukan semua temuan dari minggu ini menjadi satu narasi analitis yang kohesif. Ini adalah skill paling berharga bagi seorang data analyst: kemampuan menyulam angka-angka menjadi cerita yang dapat dipahami oleh orang yang tidak tahu data science sama sekali.
- Buat notebook khusus: "03_synthesis.ipynb" yang merangkum semua temuan utama
- Susun urutan: konteks - temuan RQ1 - temuan RQ2 - temuan RQ3 - kesimpulan terpadu
- Pilih maksimal 5 visualisasi terbaik yang paling komunikatif dari seluruh analisis
- Tulis rekomendasi aksi berdasarkan temuan (minimal 3 rekomendasi konkret)
- Commit semua notebook dan output ke GitHub dengan pesan commit yang deskriptif
# Template struktur notebook sintesis
# Gunakan markdown cells di Jupyter untuk narasi
# Cell 1: Judul dan konteks
"""
# Sintesis Analisis Capstone
**Dataset:** [nama dataset]
**Periode Data:** [periode]
**Tujuan Utama:** [satu kalimat tujuan]
**Tanggal Analisis:** 2026-06
## Executive Summary
[2-3 kalimat ringkasan seluruh proyek]
"""
# Cell 2: Ringkasan temuan per RQ
temuan = {
"RQ1": {
"pertanyaan": "[teks RQ1]",
"metode": "[metode yang digunakan]",
"temuan_utama": "[temuan dalam satu kalimat]",
"signifikansi": "[apakah hasil signifikan secara statistik]"
},
"RQ2": {
"pertanyaan": "[teks RQ2]",
"metode": "[metode yang digunakan]",
"temuan_utama": "[temuan dalam satu kalimat]",
"signifikansi": "[apakah hasil signifikan secara statistik]"
},
"RQ3": {
"pertanyaan": "[teks RQ3]",
"metode": "[nama model terbaik]",
"temuan_utama": f"Model R2={r2_tuned:.4f}, RMSE={rmse_tuned:.4f}",
"signifikansi": "Model disimpan untuk prediksi"
}
}
for rq, detail in temuan.items():
print(f"
{'='*50}")
print(f" {rq}: {detail['pertanyaan']}")
print(f" Metode : {detail['metode']}")
print(f" Temuan : {detail['temuan_utama']}")
print(f" Status : {detail['signifikansi']}")
# Rekomendasi aksi
rekomendasi = [
"1. [Rekomendasi berdasarkan temuan RQ1] - prioritas: [Tinggi/Sedang/Rendah]",
"2. [Rekomendasi berdasarkan temuan RQ2] - prioritas: [Tinggi/Sedang/Rendah]",
"3. [Rekomendasi berdasarkan temuan RQ3] - prioritas: [Tinggi/Sedang/Rendah]"
]
print("
=== Rekomendasi Aksi ===")
for r in rekomendasi:
print(r)
Minggu 4 - Polish dan Demo Day
Memoles presentasi, merapikan repository, dan mendemonstrasikan seluruh capstone project
Abbas melakukan audit menyeluruh terhadap seluruh repository capstone. Kode yang bersih dan terstruktur sama pentingnya dengan kualitas analisis; rekruter dan reviewer akan menilai keduanya sekaligus.
- Cek struktur folder: data/, notebooks/, output/, models/, harus rapi dan konsisten
- Hapus cell output yang terlalu panjang dari notebook; ganti dengan versi ringkas
- Pastikan semua notebook bisa dijalankan dari awal ke akhir tanpa error (Kernel - Restart and Run All)
- Tambahkan docstring pada setiap fungsi yang dibuat, minimal satu baris penjelasan
- Update .gitignore agar file data mentah dan model besar tidak ikut ter-commit
# Skrip audit otomatis: cek apakah semua file penting ada
import os
struktur_wajib = {
"data/": ["raw/", "clean/"],
"notebooks/": ["01_data_cleaning.ipynb", "02_eda.ipynb",
"03_synthesis.ipynb"],
"output/": [],
"models/": [],
".": ["README.md", "FINDINGS.md", "requirements.txt", ".gitignore"]
}
print("=== Audit Struktur Repository ===
")
semua_ok = True
for folder, isi in struktur_wajib.items():
folder_ada = os.path.exists(folder)
status_folder = "OK" if folder_ada else "HILANG"
print(f"[{status_folder}] {folder}")
if not folder_ada:
semua_ok = False
for item in isi:
path = os.path.join(folder, item)
ada = os.path.exists(path)
print(f" [{'OK' if ada else 'HILANG'}] {path}")
if not ada:
semua_ok = False
print(f"
{'Repository siap untuk demo!' if semua_ok else 'Ada file/folder yang perlu dibuat.'}")
# Cek requirements.txt
print("
=== Isi requirements.txt ===")
try:
with open("requirements.txt") as f:
print(f.read())
except FileNotFoundError:
print("requirements.txt tidak ditemukan - buat dengan: pip freeze > requirements.txt")
Abbas membangun slide presentasi yang ringkas dan berdampak. Presentasi data yang baik mengikuti prinsip: satu pesan utama per slide, visual mendukung narasi, dan tidak ada bullet point yang bisa diringkas lebih lanjut.
- Buat outline slide: Problem - Data - Metodologi - Temuan RQ1 - Temuan RQ2 - Temuan RQ3 - Rekomendasi - Penutup
- Maksimal 10 slide, setiap slide punya satu pesan utama yang bisa dibaca dalam 3 detik
- Ekspor visualisasi terbaik ke PNG resolusi tinggi untuk disisipkan ke slide
- Gunakan Google Slides, Canva, atau PowerPoint sesuai preferensi Abbas
- Latihan mempresentasikan setiap slide dalam 90 detik atau kurang
# Ekspor semua visualisasi terbaik untuk slide
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
# Fungsi untuk membuat grafik ringkasan eksekutif
def buat_infographic_temuan(temuan_dict, output_path="output/slide_executive_summary.png"):
fig, ax = plt.subplots(figsize=(14, 6))
ax.set_xlim(0, 3)
ax.set_ylim(0, 1)
ax.axis("off")
warna = ["#2563EB", "#16A34A", "#DC2626"]
for i, (rq, detail) in enumerate(temuan_dict.items()):
x = i + 0.5
# Kotak latar
rect = plt.Rectangle((i + 0.05, 0.05), 0.9, 0.9,
facecolor=warna[i], alpha=0.1,
edgecolor=warna[i], linewidth=2)
ax.add_patch(rect)
# Label RQ
ax.text(x, 0.82, rq, ha="center", va="center",
fontsize=14, fontweight="bold", color=warna[i])
# Pertanyaan (dipotong)
q_text = detail["pertanyaan"][:40] + "..." if len(detail["pertanyaan"]) > 40 else detail["pertanyaan"]
ax.text(x, 0.65, q_text, ha="center", va="center",
fontsize=9, color="#374151", wrap=True)
# Temuan utama
ax.text(x, 0.40, detail["temuan_utama"], ha="center", va="center",
fontsize=10, color="#111827", fontweight="semibold")
# Metode
ax.text(x, 0.20, f"Metode: {detail['metode']}", ha="center", va="center",
fontsize=8, color="#6B7280", style="italic")
ax.set_title("Ringkasan Temuan Capstone", fontsize=16, fontweight="bold", pad=20)
plt.tight_layout()
plt.savefig(output_path, dpi=200, bbox_inches="tight")
plt.show()
print(f"Infographic disimpan ke {output_path}")
# Panggil dengan temuan yang sudah dibuat di minggu 3
# buat_infographic_temuan(temuan)
print("Jalankan buat_infographic_temuan(temuan) setelah mengisi dict temuan dengan data aktual Abbas")
Abbas mempraktikkan data storytelling: menyajikan analisis sebagai narasi yang mengalir, bukan daftar angka. Kemampuan ini yang membedakan data analyst dari sekadar operator spreadsheet.
- Tulis skrip presentasi lengkap (bukan hanya poin-poin) dan bacakan dengan keras
- Identifikasi momen "tapi tunggu" dalam cerita: tempat di mana temuan mengejutkan atau melawan intuisi
- Siapkan jawaban untuk 5 pertanyaan yang mungkin ditanya: mengapa metode ini, bagaimana kualitas data, apa limitasi, apa next step, bagaimana dampaknya
- Latihan presentasi penuh minimal 2 kali, hitung waktunya
- Minta satu orang (teman, keluarga, siapapun) mendengarkan dan memberikan satu feedback
# Template skrip opening presentasi capstone
# Salin dan adaptasi untuk dataset Abbas
skrip_opening = """
SLIDE 1 - OPENING (90 detik)
"Selamat pagi/siang. Hari ini saya akan berbagi hasil analisis selama 12 bulan belajar data analytics
yang saya rangkum dalam satu proyek capstone.
Proyek ini menjawab pertanyaan sederhana tapi penting: [isi dengan RQ utama Abbas].
Saya menganalisis [jumlah baris] data dari [sumber dataset], yang mencakup [periode waktu].
Dan yang saya temukan cukup mengejutkan: [isi dengan temuan paling menarik].
Dalam 10 menit ke depan, saya akan menunjukkan bagaimana saya sampai pada kesimpulan ini,
dan apa yang bisa dilakukan berdasarkan temuan ini."
"""
daftar_pertanyaan_q_and_a = [
{
"pertanyaan": "Mengapa memilih dataset ini?",
"jawaban": "[Alasan spesifik Abbas: relevansi, ketersediaan, ukuran, dll]"
},
{
"pertanyaan": "Apa limitasi terbesar analisis ini?",
"jawaban": "[Jujur tentang: ukuran sampel, bias selection, periode data, dll]"
},
{
"pertanyaan": "Bagaimana kualitas data yang digunakan?",
"jawaban": "[Jelaskan: berapa % missing values, bagaimana dibersihkan, dll]"
},
{
"pertanyaan": "Apa yang akan dilakukan jika ada lebih banyak waktu?",
"jawaban": "[Deep learning, data tambahan, analisis segmentasi lebih dalam, dll]"
},
{
"pertanyaan": "Bagaimana model ini bisa diterapkan di dunia nyata?",
"jawaban": "[Jelaskan skenario penggunaan konkret dari model RQ3]"
}
]
print(skrip_opening)
print("
=== Persiapan Q&A ===")
for i, qa in enumerate(daftar_pertanyaan_q_and_a, 1):
print(f"
Q{i}: {qa['pertanyaan']}")
print(f"A : {qa['jawaban']}")
Hari Demo Day. Abbas mempresentasikan seluruh capstone project kepada audiens nyata: teman, kolega, mentor, atau komunitas data analytics online. Presentasi adalah puncak dari 12 bulan perjalanan belajar.
- Siapkan environment: laptop terisi penuh, koneksi internet stabil, Jupyter dan browser siap
- Buka GitHub repository capstone dan pastikan bisa diakses publik
- Presentasikan slide dan demo notebook langsung (jika memungkinkan)
- Jawab pertanyaan dengan jujur; "saya belum coba itu" adalah jawaban yang valid
- Minta feedback tertulis dari setidaknya satu pendengar setelah presentasi
# Checklist akhir sebelum Demo Day
checklist_demo = {
"Repository": [
"README.md lengkap dengan deskripsi, cara menjalankan, dan temuan utama",
"FINDINGS.md berisi executive summary",
"requirements.txt ada dan up-to-date",
".gitignore sudah dikonfigurasi",
"Semua notebook bisa dijalankan tanpa error",
"Output folder berisi semua grafik yang digunakan di slide"
],
"Presentasi": [
"Slide maksimal 10 halaman",
"Setiap slide punya satu pesan utama",
"Durasi presentasi 8-12 menit",
"Q&A siap untuk 5 pertanyaan umum",
"Demo notebook bisa dijalankan live jika diminta"
],
"Teknis": [
"Semua model tersimpan di folder models/",
"Data clean tersimpan di data/clean/",
"Tidak ada hardcoded path yang bermasalah",
"Versi library tercatat di requirements.txt"
]
}
print("=== CHECKLIST DEMO DAY ===
")
total = 0
for kategori, items in checklist_demo.items():
print(f"
[{kategori}]")
for item in items:
print(f" [ ] {item}")
total += 1
print(f"
Total: {total} item harus selesai sebelum presentasi")
print("
Selamat! Abbas sudah menyelesaikan 12 bulan perjalanan data analytics.")
print("Demo Day bukan akhir - ini adalah awal dari karir sebagai data analyst.")
Hari terakhir dari perjalanan 12 bulan. Abbas melakukan retrospektif jujur: apa yang berhasil, apa yang bisa lebih baik, dan ke mana arah belajar selanjutnya. Setiap analis handal adalah pelajar yang tidak pernah berhenti.
- Tulis retrospektif pribadi: 3 hal terbaik, 3 hal yang ingin diperbaiki, 3 pelajaran terpenting
- Update LinkedIn dengan project capstone: judul, deskripsi singkat, dan link repository
- Identifikasi satu area teknis yang ingin diperdalam: ML lanjutan, SQL advanced, Tableau, atau domain spesifik
- Buat daftar 3 project berikutnya yang ingin dikerjakan menggunakan skill yang sudah dibangun
- Commit file "RETROSPECTIVE.md" ke repository sebagai penutup resmi capstone
# Template RETROSPECTIVE.md - Penutup Resmi Capstone
retrospektif = """
# Retrospektif - Capstone Project & 12 Bulan Belajar Data Analytics
**Nama:** [Nama Abbas]
**Periode Belajar:** [bulan mulai] - Juni 2026
**Dataset Capstone:** [nama dataset]
---
## 3 Hal Terbaik
1. **[Hal terbaik pertama]**
[Penjelasan singkat mengapa ini jadi pencapaian yang berarti]
2. **[Hal terbaik kedua]**
[Penjelasan singkat]
3. **[Hal terbaik ketiga]**
[Penjelasan singkat]
---
## 3 Hal yang Ingin Diperbaiki
1. **[Area yang kurang]**
[Apa yang akan dilakukan berbeda jika mengulang dari awal]
2. **[Area yang kurang]**
[Rencana perbaikan]
3. **[Area yang kurang]**
[Rencana perbaikan]
---
## 3 Pelajaran Terpenting
1. [Pelajaran teknis atau non-teknis yang paling berdampak]
2. [Pelajaran tentang proses atau metodologi]
3. [Pelajaran tentang cara belajar itu sendiri]
---
## Rencana Selanjutnya
- **Bulan 1-2:** [topik/project pertama yang ingin dikerjakan]
- **Bulan 3-4:** [topik/project kedua]
- **Bulan 5-6:** [topik/project ketiga]
- **Target karir:** [posisi atau project impian yang ingin dicapai]
---
*Capstone ini adalah bukti bahwa konsistensi selama 12 bulan menghasilkan skill nyata
yang bisa didemonstrasikan, bukan sekadar sertifikat.*
"""
# Simpan ke file
with open("RETROSPECTIVE.md", "w") as f:
f.write(retrospektif)
print("RETROSPECTIVE.md berhasil dibuat.")
print("
Selamat menyelesaikan 12 bulan perjalanan belajar Data Analytics!")
print("Repository capstone Abbas adalah portofolio nyata - jaga dan terus kembangkan.")
Buku Pendukung Bulan 12
Referensi untuk mendalami capstone project, storytelling data, dan transisi ke karir analyst
Storytelling with Data
Buku paling langsung relevan untuk Demo Day. Knaflic mengajarkan cara memilih jenis grafik yang tepat, menghilangkan visual yang tidak perlu, dan membangun narasi di sekitar data. Cocok dibaca sebelum membuat slide presentasi capstone karena setiap bab memiliki latihan langsung yang bisa diterapkan ke visualisasi yang sudah Abbas buat.
Visualisasi PresentasiThe Model Thinker
Melengkapi kemampuan modeling Abbas dengan perspektif yang lebih luas: tidak ada satu model yang sempurna untuk semua masalah. Page menjelaskan puluhan model berpikir dari ekonomi, biologi, dan ilmu sosial yang bisa memperkaya cara Abbas menginterpretasikan temuan capstone dan memilih pendekatan untuk project berikutnya.
Mental Model AnalisisBuild a Career in Data Science
Panduan praktis transisi karir yang ditulis oleh dua data scientist yang sudah melewati proses ini. Relevan untuk fase setelah capstone: cara menulis CV berbasis proyek, mempersiapkan portofolio GitHub, melewati technical interview, dan menavigasi perbedaan antara peran data analyst, data scientist, dan data engineer di industri nyata.
Karir PortofolioNaked Statistics
Buku statistik yang paling mudah dibaca tanpa mengorbankan kedalaman. Sangat berguna untuk memperkuat fondasi interpretasi statistik yang Abbas gunakan di capstone: regresi, probabilitas, inferensi, dan bias. Ditulis dengan humor dan penuh contoh nyata yang membuat statistik terasa relevan, bukan abstrak.
Statistik FondasiTools yang Digunakan
Stack lengkap untuk capstone project, polish, dan presentasi
Jupyter Notebook
Lingkungan utama seluruh analisis capstone. Kombinasi code cell dan markdown cell memungkinkan Abbas mendokumentasikan setiap langkah analisis berdampingan dengan kode yang menjalankannya, menghasilkan notebook yang bisa dibaca sebagai laporan sekaligus dieksekusi sebagai program.
Scikit-learn
Library machine learning utama untuk modeling di capstone. Menyediakan semua tools yang dibutuhkan Abbas dari preprocessing (StandardScaler, OneHotEncoder) hingga model (Random Forest, Logistic Regression) dan evaluasi (cross_val_score, GridSearchCV) dalam satu ekosistem yang konsisten dan terdokumentasi dengan baik.
GitHub
Platform portofolio utama capstone. Repository publik Abbas di GitHub adalah bukti kerja yang bisa dilihat rekruter, kolega, atau siapapun. Commit history yang rapi menunjukkan proses berpikir yang terstruktur, README yang baik adalah pitch pertama, dan FINDINGS.md adalah executive summary untuk pengambil keputusan.
Plotly / Matplotlib
Dua library visualisasi yang melengkapi satu sama lain. Matplotlib untuk grafik statis berkualitas tinggi yang diekspor ke slide, Plotly untuk visualisasi interaktif yang bisa ditampilkan di browser selama demo langsung. Keduanya memungkinkan Abbas membuat visual yang komunikatif dan bukan sekadar output default.
Canva / Google Slides
Tools pembuatan slide presentasi untuk Demo Day. Canva unggul dalam template visual yang menarik tanpa perlu keahlian desain khusus, sementara Google Slides memudahkan kolaborasi dan presentasi langsung dari browser. Abbas mengekspor grafik analisis sebagai PNG dan menyisipkannya ke slide untuk presentasi yang kohesif.
Joblib
Library serialisasi model Python yang digunakan Abbas untuk menyimpan model machine learning terlatih ke file .pkl. Memungkinkan model yang sudah dilatih dan di-tuning selama minggu 3 untuk langsung digunakan di demo tanpa perlu melatih ulang, menghemat waktu dan memastikan konsistensi hasil yang ditampilkan saat presentasi.
Tips Praktis dan Jebakan Pemula
Delapan pelajaran dari capstone project yang sering membuat pemula tersandung, dan cara Abbas menghindarinya
- Analisis Faktor yang Mempengaruhi Nilai Ujian Akhir Siswa SMA: Studi pada Dataset Student Performance
- Prediksi Kualitas Udara Kota Bandung Berdasarkan Suhu, Kelembaban, dan Data PM2.5 Historis
- Pola Pembelian di Kantin Sekolah: Produk Terlaris dan Jam Puncak Transaksi
# ================================================
# PROJECT CHARTER - [NAMA PROYEK ABBAS]
# ================================================
## Identitas Proyek
Nama proyek : [judul yang spesifik dan konkret]
Tanggal mulai : [DD/MM/YYYY]
Target selesai: [DD/MM/YYYY]
## Problem Statement
[Deskripsikan masalah atau pertanyaan dalam 2-3 kalimat.
Contoh: Banyak siswa SMA tidak mengetahui faktor apa yang
paling mempengaruhi nilai ujian mereka. Dengan menganalisis
dataset Student Performance, proyek ini akan mengidentifikasi
variabel yang paling berkorelasi dengan nilai akhir.]
## Research Questions
1. [Pertanyaan utama yang ingin dijawab dengan data]
2. [Pertanyaan pendukung 1]
3. [Pertanyaan pendukung 2]
## Dataset
Sumber utama : [URL atau nama file]
Estimasi baris: [jumlah baris]
Estimasi kolom: [jumlah kolom]
Rentang waktu : [periode data, jika relevan]
Lisensi : [CC0 / Open Government / dll]
## Metode yang Direncanakan
EDA : distribusi, korelasi, outlier detection
Analisis : [regresi / klasifikasi / klasterisasi / statistik inferensial]
Visualisasi : [bar chart / scatter plot / heatmap / boxplot]
## Output Akhir
[ ] Notebook Jupyter yang bersih dan terdokumentasi
[ ] Minimal 5 visualisasi yang komunikatif
[ ] Laporan ringkas 1-2 halaman
[ ] Slide presentasi 5-7 slide
[ ] Repository GitHub dengan README yang jelas
- Shape dan dtype:
df.shape,df.dtypes,df.info() - Missing values:
df.isnull().sum()dan visualisasi heatmap missing - Duplikat:
df.duplicated().sum()dan cek kolom ID unik - Statistik deskriptif:
df.describe()untuk numerik,df.value_counts()untuk kategorik - Distribusi: histogram setiap kolom numerik, perhatikan skewness dan outlier visual
- Outlier: boxplot per kolom numerik, deteksi dengan metode IQR
- Korelasi antar variabel: heatmap korelasi Pearson untuk semua kolom numerik
- Korelasi dengan target: scatter plot setiap variabel independen vs variabel dependen
- Executive Summary (1 paragraf): pertanyaan, metode, temuan utama, rekomendasi
- Latar Belakang: mengapa topik ini relevan dan penting bagi audiens
- Dataset dan Metodologi: sumber data, proses cleaning, metode analisis yang digunakan
- Temuan Utama: 3 hingga 5 insight terpenting, masing-masing disertai satu visualisasi
- Kesimpulan dan Rekomendasi: jawaban langsung atas research questions dan langkah selanjutnya
- Keterbatasan: apa yang tidak bisa dijawab oleh analisis ini dan mengapa
- Slide 1 (30 detik): judul, nama Abbas, satu kalimat tentang temuan utama
- Slide 2 (60 detik): "Masalah yang ingin saya jawab" dan mengapa ini penting
- Slide 3 (60 detik): dataset yang digunakan dan proses cleaning secara singkat
- Slide 4-5 (120 detik): 2 hingga 3 temuan utama, masing-masing dengan satu visualisasi
- Slide 6 (60 detik): kesimpulan, rekomendasi, dan keterbatasan analisis
- Slide 7 (30 detik): "Apa yang ingin saya pelajari selanjutnya" dan terima kasih
Latihan Tambahan
Tiga skenario capstone siap pakai untuk Abbas yang ingin berlatih lebih keras sebelum mengerjakan proyek sesungguhnya
Dataset: Student Performance in Exams oleh Jakki Seshapanpu di Kaggle (1.000 baris, 8 kolom). Kolom utama: gender, race/ethnicity, parental level of education, lunch, test preparation course, math score, reading score, writing score.
Research Question: Faktor demografis dan persiapan belajar apa yang paling berkorelasi dengan nilai ujian matematika siswa?
- Lakukan EDA lengkap: distribusi nilai per gender dan etnis, korelasi antar tiga mata ujian
- Uji hipotesis: apakah siswa yang mengikuti test preparation course memiliki nilai rata-rata yang secara statistik lebih tinggi?
- Bangun model regresi linear untuk memprediksi nilai matematika dari variabel lainnya
- Buat satu visualisasi utama yang merangkum temuan paling menarik untuk non-analis
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from scipy import stats
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import LabelEncoder
# Load dataset
df = pd.read_csv('StudentsPerformance.csv')
print(f"Shape: {df.shape}")
print(df.isnull().sum())
# Distribusi nilai per kelompok test preparation
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
for i, subject in enumerate(['math score', 'reading score', 'writing score']):
df.boxplot(column=subject, by='test preparation course', ax=axes[i])
axes[i].set_title(subject)
plt.suptitle('Nilai per Status Persiapan Ujian')
plt.tight_layout()
plt.savefig('figures/test_prep_comparison.png', dpi=150)
plt.close()
# Uji t-test: apakah perbedaan signifikan?
selesai = df[df['test preparation course'] == 'completed']['math score']
tidak = df[df['test preparation course'] == 'none']['math score']
t_stat, p_value = stats.ttest_ind(selesai, tidak)
print(f"Rata-rata selesai persiapan : {selesai.mean():.1f}")
print(f"Rata-rata tanpa persiapan : {tidak.mean():.1f}")
print(f"t-statistic : {t_stat:.3f}")
print(f"p-value : {p_value:.4f}")
print(f"Signifikan (p < 0.05): {p_value < 0.05}")
# Heatmap korelasi
plt.figure(figsize=(6, 5))
sns.heatmap(df[['math score', 'reading score', 'writing score']].corr(),
annot=True, fmt='.2f', cmap='Blues')
plt.title('Korelasi Antar Mata Ujian')
plt.savefig('figures/korelasi_ujian.png', dpi=150)
print("Visualisasi tersimpan di folder figures/")
Dataset: Air Quality Data in India di Kaggle (bisa digunakan sebagai referensi), atau data BMKG Bandung yang tersedia di situs resmi BMKG. Kolom yang dibutuhkan: tanggal, PM2.5, PM10, suhu, kelembaban, kecepatan_angin.
Research Question: Apakah kondisi cuaca (suhu dan kelembaban) dapat memprediksi kategori kualitas udara pada hari berikutnya?
- Analisis tren PM2.5 bulanan: apakah ada pola musiman yang bisa diidentifikasi?
- Visualisasikan korelasi antara variabel cuaca dan konsentrasi PM2.5
- Bangun model klasifikasi Random Forest untuk memprediksi kategori AQI (Baik, Sedang, Tidak Sehat)
- Evaluasi model dengan classification report dan visualisasikan confusion matrix
import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, ConfusionMatrixDisplay
import seaborn as sns
import matplotlib.pyplot as plt
# Load dan preprocessing
df = pd.read_csv('air_quality_bandung.csv', parse_dates=['tanggal'])
df = df.dropna(subset=['PM2.5', 'suhu', 'kelembaban'])
# Buat kategori AQI dari nilai PM2.5
def kategori_aqi(pm25):
if pm25 <= 12.0: return 'Baik'
elif pm25 <= 35.4: return 'Sedang'
else: return 'Tidak Sehat'
df['kategori'] = df['PM2.5'].apply(kategori_aqi)
print(df['kategori'].value_counts())
# Tren bulanan PM2.5
df['bulan'] = df['tanggal'].dt.to_period('M')
tren = df.groupby('bulan')['PM2.5'].mean()
plt.figure(figsize=(12, 4))
tren.plot(marker='o')
plt.title('Tren PM2.5 Bulanan Kota Bandung')
plt.ylabel('PM2.5 (ug/m3)')
plt.grid(alpha=0.3)
plt.savefig('figures/tren_pm25.png', dpi=150)
plt.close()
# Model Random Forest
fitur = ['suhu', 'kelembaban', 'PM10', 'kecepatan_angin']
X = df[fitur].fillna(df[fitur].median())
y = df['kategori']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)
print(classification_report(y_test, model.predict(X_test)))
# Feature importance
imp = pd.Series(model.feature_importances_, index=fitur).sort_values()
imp.plot(kind='barh', color='steelblue')
plt.title('Faktor yang Paling Mempengaruhi Kualitas Udara')
plt.savefig('figures/feature_importance.png', dpi=150)
print("Model dan visualisasi selesai.")
Dataset: buat dataset simulasi menggunakan kode di bawah ini (cocok digunakan jika data kantin nyata belum tersedia), atau gunakan dataset transaksi ritel dari Kaggle seperti Online Retail II sebagai proxy. Kolom utama: tanggal, jam, produk, kategori, harga, jumlah, total.
Research Question: Produk apa yang paling laris di kantin sekolah, dan jam berapa puncak transaksi terjadi?
- Identifikasi top 10 produk terlaris berdasarkan jumlah unit terjual dan total pendapatan
- Analisis pola transaksi per jam: pukul berapa kantin paling ramai dalam sehari?
- Hitung rata-rata nilai transaksi per hari dan identifikasi hari dengan pendapatan tertinggi
- Buat dashboard ringkas dengan empat visualisasi utama menggunakan Matplotlib
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Generate data simulasi kantin sekolah (ganti dengan data nyata jika tersedia)
np.random.seed(42)
n = 2000
produk_list = ['Nasi Goreng', 'Mie Ayam', 'Es Teh', 'Air Mineral', 'Gorengan',
'Bakso', 'Soto', 'Jus Jeruk', 'Roti Bakar', 'Kopi Susu']
harga_dict = {
'Nasi Goreng': 12000, 'Mie Ayam': 10000, 'Es Teh': 5000,
'Air Mineral': 5000, 'Gorengan': 3000, 'Bakso': 12000,
'Soto': 10000, 'Jus Jeruk': 8000, 'Roti Bakar': 8000,
'Kopi Susu': 8000
}
df = pd.DataFrame({
'tanggal' : pd.date_range('2025-08-01', periods=n, freq='30min'),
'produk' : np.random.choice(produk_list, n, p=[0.15,0.12,0.13,0.10,0.12,
0.08,0.08,0.08,0.07,0.07]),
'jumlah' : np.random.randint(1, 4, n)
})
df['harga'] = df['produk'].map(harga_dict)
df['total'] = df['harga'] * df['jumlah']
df['jam'] = df['tanggal'].dt.hour
df['hari'] = df['tanggal'].dt.day_name()
print(f"Total transaksi: {len(df):,}")
print(f"Total pendapatan: Rp {df['total'].sum():,.0f}")
print(df.groupby('produk')['total'].sum().sort_values(ascending=False).head(5))
# Dashboard 4 panel
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
fig.suptitle('Dashboard Analisis Kantin Sekolah', fontsize=14, fontweight='bold')
top_unit = df.groupby('produk')['jumlah'].sum().sort_values()
top_unit.plot(kind='barh', ax=axes[0,0], color='steelblue')
axes[0,0].set_title('Produk Terlaris (Total Unit)')
axes[0,0].set_xlabel('Jumlah Terjual')
top_rev = df.groupby('produk')['total'].sum().sort_values()
top_rev.plot(kind='barh', ax=axes[0,1], color='darkorange')
axes[0,1].set_title('Pendapatan per Produk (Rp)')
pola_jam = df.groupby('jam')['jumlah'].sum()
pola_jam.plot(kind='bar', ax=axes[1,0], color='seagreen')
axes[1,0].set_title('Transaksi per Jam')
axes[1,0].set_xlabel('Jam')
df['total'].hist(bins=20, ax=axes[1,1], color='mediumpurple', edgecolor='white')
axes[1,1].set_title('Distribusi Nilai Transaksi (Rp)')
axes[1,1].set_xlabel('Total (Rp)')
plt.tight_layout()
plt.savefig('figures/dashboard_kantin.png', dpi=150)
print("Dashboard tersimpan: figures/dashboard_kantin.png")