Rencana Pembelajaran Semester
Memuat CPL, CPMK, Sub-CPMK, bahan kajian, strategi pembelajaran, rencana 16 pertemuan, asesmen, rubrik, serta integrasi capstone project.
MAGISTER INOVASI REGIONAL · SEKOLAH PASCASARJANA · UNIVERSITAS PADJADJARAN
Sains Data untuk Inovasi dan Pembangunan Regional
E-Book Pendamping Mata Kuliah Statistics for Data Science
Outcome-Based Education · Case-Based Learning · Project-Based Learning · Responsible Generative AI
Memuat CPL, CPMK, Sub-CPMK, bahan kajian, strategi pembelajaran, rencana 16 pertemuan, asesmen, rubrik, serta integrasi capstone project.
Memuat tata tertib pembelajaran, sistem penilaian, ketentuan tugas dan project, academic integrity, penggunaan Generative AI, serta hak dan kewajiban mahasiswa.
Kata Pengantar
E-book ini disusun untuk mendukung pembelajaran Sains Data/Statistics for Data Science pada Program Magister Inovasi Regional, Sekolah Pascasarjana, Universitas Padjadjaran. Orientasi utamanya bukan menjadikan mahasiswa sebagai pengguna algoritma yang mengejar kompleksitas model, tetapi membentuk kemampuan untuk mengubah persoalan pembangunan wilayah menjadi pertanyaan analitik yang dapat dipertanggungjawabkan, memilih dan memeriksa data yang relevan, menggunakan metode statistik serta machine learning secara proporsional, memvalidasi hasil, dan menerjemahkan temuan menjadi rekomendasi inovasi atau kebijakan regional.
Program Magister Inovasi Regional menempatkan kompetensi berbasis data pada inti profil lulusan: administrator/manajer publik berbasis data, analis kebijakan publik berbasis data, policy entrepreneur yang digital dan inovatif, serta peneliti kebijakan publik berbasis data. CPL program secara eksplisit memuat kemampuan mendesain pengambilan keputusan dengan big data dan machine learning, menyusun kebijakan berbasis bukti dan proyeksi, menangkap peluang inovasi melalui data-driven decision making, menggunakan metode kuantitatif dan sains data untuk evaluasi kebijakan, serta mempublikasikan hasil penelitian berbasis bukti empiris. Karena itu, mata kuliah ini dirancang sebagai jembatan antara metode kuantitatif, komputasi, konteks regional, dan keputusan publik. (Sekolah Pascasarjana Universitas Padjadjaran 2026)
Buku ini memakai prinsip Outcome-Based Education (OBE), case-based learning, dan satu capstone project yang berkembang sepanjang semester. Setiap metode diperkenalkan melalui urutan: konteks masalah → konsep → formulasi matematis → intuisi → simulasi → data nyata → implementasi R → validasi → interpretasi substantif → implikasi regional. Rumus dituliskan secara eksplisit agar mahasiswa memahami asumsi dan mekanisme metode; kode R diberikan sebagai alat untuk melakukan eksperimen dan memastikan reproducibility. (Wickham, Çetinkaya-Rundel, dan Grolemund 2023; James dkk. 2021; Kuhn dan Silge 2022)
Penggunaan Generative AI diperbolehkan secara terarah untuk membantu memahami dokumentasi, merancang kerangka kode, debugging, membuat alternatif visualisasi, atau menyusun dokumentasi teknis. Namun tanggung jawab ilmiah tetap berada pada mahasiswa: sumber data harus diverifikasi, kode harus diuji, hasil harus divalidasi, interpretasi harus dikerjakan secara substantif, dan penggunaan AI harus dideklarasikan. Pendekatan ini mengikuti prinsip penggunaan AI yang manusia-sentris, transparan, aman, dan dapat dipertanggungjawabkan. (Miao dan Holmes 2023; Tabassi 2023; Autio dkk. 2024)
Buku ini sengaja cukup rinci untuk jenjang magister, tetapi tetap memberi jalur belajar bertahap bagi mahasiswa dengan latar statistika dan pemrograman yang beragam. Mahasiswa yang sudah kuat secara teknis dapat memperdalam bagian formulasi dan eksperimen model; mahasiswa yang masih berkembang dalam R dapat mengikuti kode secara bertahap. Yang tidak boleh hilang pada kedua kelompok adalah kemampuan menjawab tiga pertanyaan: (1) apakah analisisnya benar secara metodologis, (2) apakah datanya mendukung klaim yang dibuat, dan (3) apakah hasilnya bermakna bagi wilayah dan keputusan yang sedang dibahas?
Mata kuliah ini mengembangkan lima kelompok kompetensi yang saling terhubung.
| Komponen | Bobot | Implementasi yang disarankan |
|---|---|---|
| Capstone Project | 30% | 7 milestone, kerja kelompok, audit kontribusi individu |
| Partisipasi | 10% | diskusi kasus, kritik grafik/model, peer review, studio project |
| Kuis | 10% | 4 kuis formatif × 2,5% |
| Tugas | 10% | 4 tugas analitik × 2,5% |
| UTS | 20% | individual integrative regional data case |
| UAS | 20% | individual analytical synthesis + oral defense |
| Total | 100% |
Mahasiswa memilih satu persoalan sejak awal semester. Tema berikut adalah contoh, bukan daftar tertutup. Setiap tim wajib mempersempit isu menjadi pertanyaan yang dapat dianalisis dengan data dan memiliki stakeholder yang jelas.
Pertanyaan kebijakan: wilayah mana yang perlu diprioritaskan, dan kombinasi deprivasi apa yang membedakan satu wilayah dengan wilayah lain?
Data yang mungkin digunakan: kemiskinan, pendidikan, akses kesehatan, sanitasi, internet, PDRB per kapita, dan data spasial batas administrasi dari BPS/Open Data Jawa Barat/World Bank. Data kemiskinan kabupaten/kota Jawa Barat tersedia sebagai seri tahunan 2002–2025; karena unitnya ribu jiwa, mahasiswa harus membedakan jumlah absolut dari tingkat kemiskinan. (Badan Pusat Statistik dan Pemerintah Provinsi Jawa Barat 2026a)
Metode: EDA, standardisasi indikator, indeks komposit dengan analisis sensitivitas bobot, PCA, clustering, pemetaan choropleth, Moran’s bila struktur spasial dianalisis.
Produk akhir: policy brief, atlas prioritas, dashboard filter kabupaten/kota, serta daftar rekomendasi yang menjelaskan bahwa prioritas tinggi dapat muncul karena mekanisme yang berbeda.
Pertanyaan kebijakan: apakah wilayah dengan pertumbuhan ekonomi lebih tinggi selalu memiliki TPT lebih rendah, dan kelompok wilayah mana yang membutuhkan strategi ketenagakerjaan berbeda?
Data: TPT kabupaten/kota Jawa Barat 2007–2024 dan laju pertumbuhan PDRB ADHK 2011–2024, ditambah indikator pendidikan atau struktur lapangan usaha bila tersedia. (Badan Pusat Statistik dan Pemerintah Provinsi Jawa Barat 2026d, 2026b)
Metode: tren, korelasi, regresi, model dengan interaksi, clustering, model prediksi, evaluasi out-of-time.
Catatan substantif: hubungan PDRB–TPT tidak boleh langsung ditafsirkan kausal; struktur industri, partisipasi angkatan kerja, urbanisasi, dan shock ekonomi dapat menjadi penjelasan alternatif.
Pertanyaan kebijakan: wilayah mana yang memiliki basis UMKM besar tetapi indikator digital/akses pasarnya masih tertinggal?
Data: proyeksi jumlah UMKM Jawa Barat 2016–2023, akses internet, penduduk, PDRB, atau data infrastruktur. Karena dataset UMKM berstatus proyeksi, status ini harus muncul pada metadata, visualisasi, dan interpretasi. (Dinas Koperasi dan Usaha Kecil Provinsi Jawa Barat 2026)
Metode: indikator per 1.000 penduduk, PCA, clustering, profil cluster, dashboard.
Pertanyaan kebijakan: indikator apa yang berkaitan dengan tingginya prevalensi stunting dan bagaimana mengidentifikasi wilayah untuk pemeriksaan lebih lanjut?
Data: prevalensi balita stunting kabupaten/kota Jawa Barat 2019–2024 atau jumlah balita stunting 2014–2024, ditambah indikator sanitasi, kemiskinan, fasilitas kesehatan, dan pendidikan. (Kementerian Kesehatan Republik Indonesia dan Pemerintah Provinsi Jawa Barat 2026)
Metode: regresi/klasifikasi, calibration, threshold berbasis biaya kebijakan, pemetaan, analisis sensitivitas. Model bukan diagnosis klinis dan tidak menggantikan verifikasi lapangan.
Pertanyaan kebijakan: wilayah mana yang menunjukkan penurunan kapasitas tanam atau ketergantungan yang tinggi, dan apakah pola tersebut membentuk klaster spasial?
Data: luas areal tanam padi sawah kabupaten/kota Jawa Barat 2013–2020, data penduduk, produksi, curah hujan atau penggunaan lahan jika tersedia. (Pemerintah Provinsi Jawa Barat 2026a)
Metode: indikator per kapita/per luas wilayah, tren, clustering, pemetaan, Moran’s , skenario sensitivitas.
Pertanyaan kebijakan: apakah pertumbuhan konektivitas digital diikuti penyempitan kesenjangan akses layanan dan outcome sosial?
Metode: EDA longitudinal, regresi, interaksi urban/rural bila indikator tersedia, segmentasi wilayah, dashboard.
Risiko analitik: ecological fallacy—hubungan pada level kabupaten tidak selalu berlaku pada individu.
Pertanyaan kebijakan: wilayah mana yang memiliki potensi kunjungan tinggi tetapi kapasitas ekonomi lokal atau konektivitasnya belum memadai?
Metode: indeks intensitas kunjungan, pertumbuhan tahunan, clustering, model prediksi sederhana, visualisasi spasial. Data harus dibedakan antara kunjungan, tamu, okupansi, dan jumlah objek wisata.
Pertanyaan kebijakan: bagaimana membangun indeks kapasitas inovasi yang transparan dan sensitif terhadap pilihan indikator/bobot?
Metode: normalisasi, PCA sebagai pembanding indeks berbobot, analisis sensitivitas, ranking stability, clustering, dashboard. Praktik penyusunan indeks komposit harus memisahkan pilihan normatif dari pilihan statistik. (OECD dan Joint Research Centre, European Commission 2008)
Pertanyaan kebijakan: karakteristik wilayah apa yang berasosiasi dengan realisasi investasi dan bagaimana mengidentifikasi wilayah dengan investment gap?
Metode: regresi, regularisasi, model pohon, SHAP/feature importance secara hati-hati, klasifikasi wilayah berpotensi tinggi namun realisasi rendah.
Pertanyaan kebijakan: apakah waktu/jarak akses menuju pusat ekonomi dan layanan berkaitan dengan outcome pembangunan wilayah?
Metode: feature engineering berbasis jarak, visualisasi peta, regresi, clustering, analisis sensitivitas terhadap definisi aksesibilitas.
Blueprint berikut lebih rinci daripada galeri tema. Mahasiswa tidak harus memilih blueprint ini, tetapi dapat menggunakannya untuk memahami level kedalaman yang diharapkan sejak pertemuan pertama.
Stakeholder: Bappeda, dinas sosial, dinas kesehatan, dinas pendidikan.
Decision question: kabupaten/kota mana yang memerlukan review prioritas lintas-sektor pada siklus perencanaan berikut, dan dimensi apa yang paling menjelaskan prioritas tiap wilayah?
Unit analisis: kabupaten/kota–tahun.
Outcome utama: tingkat/jumlah kemiskinan atau indeks deprivasi yang dirancang transparan.
Kandidat data: jumlah penduduk miskin kabupaten/kota Jawa Barat 2002–2025, TPT 2007–2024, indikator pendidikan/kesehatan/internet yang tersedia, serta batas administrasi. (Badan Pusat Statistik dan Pemerintah Provinsi Jawa Barat 2026a, 2026d)
Feature construction:
Workflow minimum: audit metadata → harmonisasi periode → feature rate/growth → EDA disparity → indeks teori → PCA sebagai pembanding → clustering profile → peta → sensitivity bobot → optional predictive model → policy memo.
Validation: ranking stability terhadap bobot; bootstrap/temporal sensitivity; cek apakah top-10 berubah bila satu indikator dikeluarkan; bandingkan indeks berbobot dengan PC1.
Policy interpretation: jangan hanya memberi daftar top-10. Kelompokkan alasan: kemiskinan–pengangguran tinggi, layanan rendah, digital gap, atau kombinasi. Rekomendasi harus berbeda menurut profil.
Dashboard: map + profile card + trend + decomposition indikator.
Risiko: denominator tidak konsisten; angka jumlah vs persen; indikator berbeda tahun; ranking false precision; stigma wilayah.
Deliverable final: reproducible report 20–30 halaman ekuivalen, dashboard beta, policy brief 2 halaman, data dictionary, provenance, AI log.
Stakeholder: Bappeda, dinas tenaga kerja, dinas perindustrian/perdagangan.
Decision question: wilayah mana yang menunjukkan persistensi TPT tinggi meskipun pertumbuhan ekonomi relatif baik, dan apakah pola tersebut mengindikasikan kebutuhan strategi pasar kerja yang berbeda?
Data inti: TPT 2007–2024 dan pertumbuhan PDRB ADHK 2011–2024 dari Open Data Jawa Barat/BPS. (Badan Pusat Statistik dan Pemerintah Provinsi Jawa Barat 2026d, 2026b)
Hipotesis analitik contoh: hubungan pertumbuhan dan TPT dapat non-linear serta berbeda menurut tipe wilayah. Model associational: Untuk prediksi satu tahun ke depan, gunakan lag:
Workflow: time-series profile per wilayah → shock detection → scatter/faceting → baseline OLS → temporal validation → random forest/boosting bila memberi nilai tambah → clustering residual profile → spatial map residual → recommendation.
Pertanyaan interpretasi: wilayah dengan TPT aktual jauh di atas prediksi baseline dapat menjadi “positive/negative residual case” untuk diagnostic review. Residual bukan bukti kegagalan kebijakan; ia menunjukkan outcome tidak dijelaskan penuh oleh fitur model.
Validation: train ≤2021, validation 2022–2023, test 2024 sebagai contoh; jangan random split jika target masa depan. Bandingkan naive baseline dengan regression/ML.
Policy outputs: empat tipologi: high TPT–high growth, high TPT–low growth, low TPT–high growth, low TPT–low growth; kemudian interpretasikan dengan indikator tambahan.
Risiko: pandemi, perubahan survei/metode, pooled ecological inference, target leakage.
Stakeholder: dinas koperasi/UMKM, dinas komunikasi/informatika, pemerintah kabupaten/kota.
Decision question: paket dukungan apa yang berbeda untuk wilayah dengan basis UMKM besar tetapi readiness digital/akses pasar yang berbeda?
Data inti: proyeksi UMKM kabupaten/kota 2016–2023—status proyeksi harus dipertahankan pada seluruh dokumentasi. (Dinas Koperasi dan Usaha Kecil Provinsi Jawa Barat 2026)
Feature contoh:
Metode: EDA → robust scaling → PCA untuk reduksi collinearity → k-means/hierarchical clustering → silhouette/stability → map cluster → profile → policy package. Jika tersedia outcome digital adoption, classification dapat ditambahkan.
Pertanyaan penting: apakah cluster stabil jika variabel count diganti per-capita? Jika tidak, cluster awal mungkin hanya mengelompokkan ukuran populasi.
Policy package contoh: cluster 1 basis usaha besar–digital tinggi → market expansion; cluster 2 basis usaha besar–digital rendah → onboarding/infra; cluster 3 basis kecil–akses rendah → ecosystem building; cluster 4 basis kecil–akses tinggi → entrepreneurship/product development. Ini hanyalah contoh interpretasi dan harus mengikuti hasil aktual.
Validation: silhouette, multiple starts, alternative K, removal of one dominant feature, scaling alternatives.
Dashboard: cluster map; radar/profile plot secukupnya; table indikator; filter tahun.
Risiko: proyeksi dianggap real count; cluster labels normatif; outlier metropolitan mendominasi; data UMKM formal/informal berbeda cakupan.
Stakeholder: dinas kesehatan/Bappeda.
Decision question: wilayah mana yang memiliki probabilitas tinggi terhadap kategori prevalensi stunting tinggi dan membutuhkan review data/intervensi lebih lanjut?
Data: prevalensi stunting 2019–2024 atau jumlah stunting 2014–2024 dari Open Data Jawa Barat, plus indikator kemiskinan, sanitasi, kesehatan, pendidikan. (Kementerian Kesehatan Republik Indonesia dan Pemerintah Provinsi Jawa Barat 2026)
Label contoh—hanya bila ada threshold kebijakan/akademik yang sah: Jangan menciptakan threshold seolah resmi. Jika hanya untuk latihan, tulis “analytical threshold for classroom demonstration”.
Model baseline: logistic regression Bandingkan random forest bila ada cukup observasi dan fitur. Untuk data hanya 27 kabupaten × beberapa tahun, kompleksitas model harus sangat hati-hati; effective sample size dan dependence perlu dibahas.
Metric: sensitivity, precision, calibration, PR/ROC; threshold dipilih dengan cost false negative/kapasitas review.
Spatial: peta prevalensi dan residual/risk; Moran diagnostic jika layak.
Interpretasi: model adalah screening analytic, bukan alat diagnosis anak/rumah tangga dan bukan pengganti survei/verifikasi kesehatan.
Fairness/coverage: cek perform menurut urban/rural atau region group bila sample memungkinkan; hindari klaim subgroup dengan n terlalu kecil.
Policy output: prioritas verifikasi, data gaps, dan opsi penguatan surveillance; bukan automatic funding allocation tanpa review manusia.
| Minggu | Milestone | Deliverable utama | Bobot project |
|---|---|---|---|
| 1 | Tema dan stakeholder | 1 paragraf masalah + calon sumber data | formatif |
| 2 | M1 Problem Framing | one-page problem brief, decision question, unit analisis | 3% |
| 3 | Data inventory | metadata, lisensi, definisi indikator, join key | formatif |
| 4 | M2 Data Dossier | data dictionary, audit kualitas, cleaning log | 4% |
| 5 | EDA draft | 3–5 grafik yang menjawab pertanyaan | formatif |
| 6 | M3 Evidence Story | EDA, deskriptif/inferensial awal, narasi regional | 5% |
| 7 | Baseline model | model sederhana + split/resampling | formatif |
| 8 | UTS + project clinic | revisi problem framing berdasarkan umpan balik | — |
| 9 | Model alternatif | tree/ensemble atau model lain yang relevan | formatif |
| 10 | M4 Predictive/Classification Model | perbandingan model + evaluasi | 5% |
| 11 | Segmentasi | cluster profile atau heterogenitas wilayah | formatif |
| 12 | M5 Regional Heterogeneity | PCA/cluster/segmentasi + interpretasi | 4% |
| 13 | Spatial evidence | peta, neighborhood definition, spatial diagnostic | formatif |
| 14 | Robustness/fairness | sensitivity analysis + uncertainty | formatif |
| 15 | M6 Policy & Dashboard Beta | policy options + dashboard beta | 4% |
| 16 | M7 Final Reproducible Package | report, code, data dictionary, dashboard, AI log | 5% |
| Total Project | 30% |
| Dimensi | Bobot di dalam Project | Kriteria unggul |
|---|---|---|
| Relevansi masalah & pertanyaan | 15% | Masalah nyata, unit analisis dan keputusan jelas, stakeholder terpetakan |
| Data provenance & quality | 15% | Sumber kredibel, metadata lengkap, cleaning terdokumentasi, keterbatasan eksplisit |
| Metode & validasi | 25% | Metode proporsional, baseline tersedia, leakage dicegah, metrik sesuai, uncertainty dibahas |
| Interpretasi regional | 20% | Menghubungkan hasil dengan heterogenitas wilayah dan mekanisme substantif tanpa overclaim |
| Rekomendasi kebijakan/inovasi | 10% | Spesifik, feasible, target dan indikator monitoring jelas, risiko dibahas |
| Visualisasi/dashboard | 5% | Akurat, terbaca, metadata terlihat, dan tidak misleading |
| Reproducibility & AI integrity | 5% | Kode dapat dijalankan, seed/dependency tercatat, AI-use log lengkap |
| Presentasi & respons kritik | 5% | Narasi terstruktur dan mampu mempertahankan metodologi serta keterbatasan |
| Total | 100% dari Project = 30% MK |
Template berikut merupakan bagian dari e-book ini. Mahasiswa tidak perlu menggunakan file template terpisah. Struktur ini digunakan sejak minggu pertama dan diperbarui pada setiap milestone. Tujuannya adalah menjaga evidence chain: masalah → data → metode → validasi → interpretasi → rekomendasi → monitoring.
Tuliskan judul project, nama anggota tim, stakeholder sasaran, wilayah studi, periode data, tanggal pembaruan terakhir, serta tautan repositori/penyimpanan data jika diizinkan. Judul harus menyatakan masalah regional dan tujuan analitik, bukan hanya nama algoritma.
Maksimum 300 kata yang memuat: masalah, keputusan yang didukung, data, metode utama, tiga temuan, dua keterbatasan, dan rekomendasi. Ringkasan ini ditulis terakhir, walaupun ditempatkan di awal laporan.
Gunakan tabel berikut.
| Elemen | Isian wajib |
|---|---|
| Masalah regional | Masalah spesifik, terukur, dan relevan bagi wilayah |
| Stakeholder | Instansi/kelompok yang menggunakan hasil |
| Decision question | Keputusan apa yang akan dibantu oleh analisis |
| Unit analisis | Desa, kecamatan, kabupaten/kota, provinsi, wilayah-tahun, dsb. |
| Outcome/indikator | Definisi operasional, satuan, denominator |
| Horizon | Deskriptif saat ini, prediksi tahun depan, monitoring multi-tahun, dsb. |
| Risiko salah keputusan | Konsekuensi false positive/false negative atau salah ranking |
| Dataset | Produsen | URL/Sumber | Tahun | Unit | Variabel kunci | Status | Keterbatasan |
|---|---|---|---|---|---|---|---|
| Dataset 1 | final/proyeksi/sementara | ||||||
| Dataset 2 |
Setiap dataset wajib memiliki access date, lisensi jika tersedia, perubahan definisi, dan catatan transformasi. Tidak diperkenankan menyalin data dari agregator sekunder jika sumber resmi masih tersedia.
panel_capstone <- readr::read_csv("data/simulasi_panel_regional.csv", show_col_types = FALSE)
tibble::tibble(
n_baris = nrow(panel_capstone),
n_wilayah = dplyr::n_distinct(panel_capstone$wilayah),
tahun_min = min(panel_capstone$tahun),
tahun_maks = max(panel_capstone$tahun),
missing_total = sum(is.na(panel_capstone))
) |>
knitr::kable(caption = "Output awal: audit struktur dataset capstone")| n_baris | n_wilayah | tahun_min | tahun_maks | missing_total |
|---|---|---|---|---|
| 189 | 27 | 2019 | 2025 | 0 |
Laporan minimal memuat duplicate key, missingness, range check, consistency check, join mismatch, perubahan kode wilayah, dan keputusan outlier. Semua transformasi harus dilakukan melalui kode, bukan melalui edit manual spreadsheet yang tidak terdokumentasi.
cap_qc <- panel_capstone |>
dplyr::group_by(tahun) |>
dplyr::summarise(
n = dplyr::n(),
missing_kemiskinan = mean(is.na(kemiskinan_persen)),
min_kemiskinan = min(kemiskinan_persen, na.rm = TRUE),
max_kemiskinan = max(kemiskinan_persen, na.rm = TRUE),
.groups = "drop"
)
knitr::kable(cap_qc, digits = 3, caption = "Output quality audit per tahun")| tahun | n | missing_kemiskinan | min_kemiskinan | max_kemiskinan |
|---|---|---|---|---|
| 2019 | 27 | 0 | 12.056 | 17.664 |
| 2020 | 27 | 0 | 10.589 | 18.048 |
| 2021 | 27 | 0 | 10.734 | 17.976 |
| 2022 | 27 | 0 | 8.477 | 16.303 |
| 2023 | 27 | 0 | 8.570 | 15.518 |
| 2024 | 27 | 0 | 8.636 | 13.924 |
| 2025 | 27 | 0 | 6.006 | 13.055 |
Minimal terdapat empat jenis bukti: distribusi, perbandingan antardaerah, hubungan antarindikator, dan perubahan waktu. Setiap grafik harus memiliki take-away sentence satu atau dua kalimat.
panel_capstone |>
dplyr::filter(tahun == max(tahun)) |>
ggplot2::ggplot(ggplot2::aes(internet_persen, kemiskinan_persen)) +
ggplot2::geom_point(size = 2.4, alpha = .75) +
ggplot2::geom_smooth(method = "lm", se = TRUE) +
ggplot2::labs(
title = "Contoh evidence board: internet dan kemiskinan",
subtitle = "Data simulasi; hubungan tidak otomatis bersifat kausal",
x = "Akses internet (%)", y = "Kemiskinan (%)"
)Model pertama harus sederhana dan dapat dijelaskan. Baseline berfungsi sebagai pembanding terhadap model yang lebih kompleks.
cap_latest <- panel_capstone |> dplyr::filter(tahun == max(tahun))
cap_lm <- lm(kemiskinan_persen ~ internet_persen + pdrb_perkapita_juta + tpt_persen + ipm,
data = cap_latest)
broom::tidy(cap_lm, conf.int = TRUE) |>
knitr::kable(digits = 3, caption = "Output baseline regression")| term | estimate | std.error | statistic | p.value | conf.low | conf.high |
|---|---|---|---|---|---|---|
| (Intercept) | 7.522 | 23.830 | 0.316 | 0.755 | -41.897 | 56.941 |
| internet_persen | -0.012 | 0.068 | -0.180 | 0.859 | -0.152 | 0.128 |
| pdrb_perkapita_juta | -0.102 | 0.060 | -1.697 | 0.104 | -0.226 | 0.023 |
| tpt_persen | -0.233 | 0.282 | -0.826 | 0.417 | -0.818 | 0.352 |
| ipm | 0.145 | 0.343 | 0.423 | 0.677 | -0.567 | 0.857 |
Jika model alternatif digunakan, tunjukkan nilai tambah terhadap baseline. Pilih metrik berdasarkan tujuan keputusan; gunakan data validasi untuk pemilihan model/hyperparameter dan simpan data test untuk evaluasi akhir.
set.seed(260826)
cap_train <- panel_capstone |> dplyr::filter(tahun <= 2023)
cap_test <- panel_capstone |> dplyr::filter(tahun >= 2024)
cap_fit <- lm(kemiskinan_persen ~ internet_persen + pdrb_perkapita_juta + tpt_persen + ipm,
data = cap_train)
cap_eval <- cap_test |>
dplyr::mutate(pred = predict(cap_fit, newdata = cap_test)) |>
dplyr::summarise(
RMSE = sqrt(mean((kemiskinan_persen - pred)^2)),
MAE = mean(abs(kemiskinan_persen - pred))
)
knitr::kable(cap_eval, digits = 3, caption = "Output evaluasi out-of-time")| RMSE | MAE |
|---|---|
| 1.413 | 1.096 |
Uji minimal satu keputusan analitik: bobot indeks, threshold, pilihan fitur, tahun holdout, jumlah cluster, seed, atau definisi matriks bobot spasial. Jelaskan bagian kesimpulan yang stabil dan yang sensitif.
Gunakan format empat lapis:
Setiap rekomendasi harus mempunyai rantai: evidence → target → instrumen → risiko → indikator monitoring. Hindari kalimat generik seperti “pemerintah perlu meningkatkan perhatian”.
Dashboard bersifat opsional jika tidak menambah nilai keputusan. Jika digunakan, minimal memiliki filter wilayah/periode, definisi indikator, sumber data, catatan terakhir diperbarui, dan caveat interpretasi.
| Tanggal | Tool/model | Tujuan | Output AI yang digunakan | Cara verifikasi | Modifikasi manusia |
|---|---|---|---|---|---|
AI tidak boleh menjadi sumber angka faktual tanpa verifikasi sumber primer. Seluruh kode yang dibantu AI tetap menjadi tanggung jawab mahasiswa.
Project dinyatakan siap bila anggota tim lain dapat membuka folder project dan menjalankan ulang analisis hanya dari README dan kode yang tersedia.
#> R version dan package yang digunakan pada saat knit:
#> R version 4.5.1 (2025-06-13)
#> Platform: aarch64-apple-darwin20
#> Running under: macOS Sonoma 14.5
#>
#> Matrix products: default
#> BLAS: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRblas.0.dylib
#> LAPACK: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRlapack.dylib; LAPACK version 3.12.1
#>
#> locale:
#> [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
#>
#> time zone: Asia/Jakarta
#> tzcode source: internal
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] httr2_1.2.3 jsonlite_2.0.0 leaflet_2.2.2 tmap_4.1
#> [5] spdep_1.3-13 spData_2.3.4 sf_1.0-21 factoextra_1.0.7
#> [9] cluster_2.1.8.1 ranger_0.17.0 yardstick_1.3.2 workflowsets_1.1.1
#> [13] workflows_1.3.0 tune_2.0.1 tailor_0.1.0 rsample_1.3.1
#> [17] recipes_1.3.1 parsnip_1.4.1 modeldata_1.5.1 infer_1.1.0
#> [21] dials_1.4.2 scales_1.4.0 tidymodels_1.4.1 broom_1.0.12
#> [25] knitr_1.50 skimr_2.2.2 janitor_2.2.1 lubridate_1.9.5
#> [29] forcats_1.0.1 stringr_1.6.0 dplyr_1.2.1 purrr_1.2.0
#> [33] readr_2.2.0 tidyr_1.3.1 tibble_3.3.1 ggplot2_4.0.1
#> [37] tidyverse_2.0.0
#>
#> loaded via a namespace (and not attached):
#> [1] RColorBrewer_1.1-3 rstudioapi_0.17.1 wk_0.9.4
#> [4] magrittr_2.0.4 farver_2.1.2 rmarkdown_2.30
#> [7] vctrs_0.7.3 base64enc_0.1-3 terra_1.8-54
#> [10] htmltools_0.5.8.1 leafsync_0.1.0 raster_3.6-32
#> [13] s2_1.1.9 sass_0.4.10 parallelly_1.45.0
#> [16] KernSmooth_2.23-26 bslib_0.11.0 htmlwidgets_1.6.4
#> [19] stars_0.6-8 cachem_1.1.0 lifecycle_1.0.5
#> [22] pkgconfig_2.0.3 cols4all_0.9 Matrix_1.7-3
#> [25] R6_2.6.1 fastmap_1.2.0 future_1.58.0
#> [28] snakecase_0.11.1 digest_0.6.38 colorspace_2.1-2
#> [31] furrr_0.3.1 leafem_0.2.4 crosstalk_1.2.1
#> [34] labeling_0.4.3 lwgeom_0.2-14 spacesXYZ_1.6-0
#> [37] timechange_0.4.0 mgcv_1.9-3 abind_1.4-8
#> [40] compiler_4.5.1 microbenchmark_1.5.0 proxy_0.4-27
#> [43] bit64_4.6.0-1 withr_3.0.2 S7_0.2.1
#> [46] backports_1.5.0 DBI_1.2.3 logger_0.4.0
#> [49] maptiles_0.10.0 MASS_7.3-65 lava_1.8.1
#> [52] rappdirs_0.3.3 tmaptools_3.2 classInt_0.4-11
#> [55] tools_4.5.1 units_0.8-7 otel_0.2.0
#> [58] leaflegend_1.2.1 future.apply_1.20.0 nnet_7.3-20
#> [61] glue_1.8.0 nlme_3.1-168 grid_4.5.1
#> [64] generics_0.1.4 leaflet.providers_2.0.0 gtable_0.3.6
#> [67] tzdb_0.5.0 class_7.3-23 data.table_1.18.2.1
#> [70] hms_1.1.4 sp_2.2-0 ggrepel_0.9.6
#> [73] pillar_1.11.1 vroom_1.7.1 splines_4.5.1
#> [76] lhs_1.2.0 lattice_0.22-7 bit_4.6.0
#> [79] survival_3.8-3 deldir_2.0-4 tidyselect_1.2.1
#> [82] bookdown_0.43 xfun_0.54 hardhat_1.4.2
#> [85] timeDate_4051.111 stringi_1.8.7 DiceDesign_1.10
#> [88] yaml_2.3.10 boot_1.3-31 evaluate_1.0.5
#> [91] codetools_0.2-20 cli_3.6.5 rpart_4.1.24
#> [94] repr_1.1.7 jquerylib_0.1.4 dichromat_2.0-0.1
#> [97] Rcpp_1.1.0 globals_0.18.0 png_0.1-8
#> [100] XML_3.99-0.18 parallel_4.5.1 gower_1.0.2
#> [103] GPfit_1.0-9 listenv_0.10.0 viridisLite_0.4.2
#> [106] ipred_0.9-15 prodlim_2025.04.28 e1071_1.7-16
#> [109] crayon_1.5.3 rlang_1.3.0
R/ atau script analisis yang terstruktur.Bagian ini berfungsi sebagai reading map agar mahasiswa tidak membaca e-book secara linear tanpa prioritas. Setiap pertemuan memiliki tiga lapis target: minimum competency (wajib dikuasai seluruh mahasiswa), analytical competency (mampu memilih dan menguji metode), dan master-level competency (mampu menjelaskan asumsi, keterbatasan, serta konsekuensi keputusan). Bacaan utama harus dipakai untuk memahami logika metode; dokumentasi package dipakai untuk implementasi, bukan sebagai pengganti referensi metodologis.
| Minggu | Fokus | Rumus/konsep yang wajib dikuasai | Bacaan inti | Bukti belajar |
|---|---|---|---|---|
| 1 | Problem framing | empirical risk, loss, indeks komposit, utility | Provost dan Fawcett (2013); James dkk. (2021); OECD dan Joint Research Centre, European Commission (2008) | problem canvas + pertanyaan analitik |
| 2 | Ekosistem/open data | rate, proportion, growth, CAGR, missingness | Wickham, Çetinkaya-Rundel, dan Grolemund (2023); Gebru dkk. (2021) | data dossier + metadata |
| 3 | Wrangling & quality | z-score, robust z, IQR, MAD, LQ | Wickham (2014); Little dan Rubin (2019) | reproducible cleaning log |
| 4 | EDA | mean/median, variance, covariance, correlation, Gini, Theil | Tukey (1977); Wickham, Çetinkaya-Rundel, dan Grolemund (2023) | EDA notebook + anomaly log |
| 5 | Visualization | slope, index, uncertainty interval, denominator awareness | Wilkinson (2005); Tufte (2001) | evidence story |
| 6 | Inferensi & regresi | OLS, sampling uncertainty, CI, , VIF, interaction | Harrell (2015); James dkk. (2021) | model card awal |
| 7 | Predictive modeling | RMSE/MAE, CV, regularization, ridge/lasso | Kuhn dan Silge (2022); Hastie, Tibshirani, dan Friedman (2009) | validation memo |
| 8 | UTS | integrasi minggu 1–7 | seluruh bacaan minggu 1–7 | individual case analysis |
| 9 | Tree-based ML | impurity, bagging, random forest, boosting | Breiman (2001); Friedman (2001); Chen dan Guestrin (2016) | baseline-vs-ML comparison |
| 10 | Classification | logit, likelihood, sensitivity/specificity, F1, AUC, calibration | Fawcett (2006); James dkk. (2021) | threshold decision memo |
| 11 | Clustering | distance, within-cluster SS, silhouette, Ward | Kaufman dan Rousseeuw (1990) | segment profile |
| 12 | PCA | covariance/correlation matrix, eigenvalue, PVE, score/loading | Jolliffe dan Cadima (2016) | dimensionality memo |
| 13 | Spatial data | CRS, neighborhood, Moran’s , Local Moran | Pebesma (2018); Moran (1950); Anselin (1995) | spatial diagnostic |
| 14 | Evaluation/robustness | bootstrap, rank stability, fairness, leakage, out-of-time validation | Hardt, Price, dan Srebro (2016); Kuhn dan Silge (2022) | robustness audit |
| 15 | Policy translation | utility, uncertainty, causal caution, DiD overview | Hernán dan Robins (2020); Callaway dan Sant’Anna (2021) | policy brief + dashboard beta |
| 16 | UAS/defense | synthesis, reproducibility, uncertainty, AI disclosure | Gebru dkk. (2021); Mitchell dkk. (2019); Miao dan Holmes (2023) | final package + oral defense |
Setiap persamaan perlu dibaca melalui empat lapisan. Pertama, identifikasi objek matematisnya: apakah skalar, vektor, matriks, probabilitas, atau fungsi. Kedua, jelaskan apa yang dioptimalkan atau diringkas. Ketiga, sebutkan asumsi yang diperlukan agar interpretasi sah. Keempat, terjemahkan kembali hasil ke konteks regional. Sebagai contoh, persamaan regresi
bukan sekadar instruksi menjalankan lm(). Mahasiswa harus mampu menjelaskan bahwa adalah vektor outcome, adalah matriks desain, adalah koefisien populasi yang ingin dipelajari, dan merepresentasikan variasi yang belum dijelaskan model. Jika unit observasi adalah kabupaten-tahun, asumsi independensi sederhana dapat terganggu oleh pengulangan wilayah dan korelasi temporal; jika unit berdekatan secara geografis, residual juga dapat berkorelasi spasial. Karena itu, kemampuan membaca struktur data harus mendahului interpretasi koefisien.
Untuk kuis, tugas, UTS, dan UAS, jawaban matematis yang dinilai penuh harus memuat: (1) rumus, (2) definisi seluruh simbol, (3) substitusi nilai bila tersedia, (4) hasil numerik dengan satuan, dan (5) interpretasi substantif. Contoh jawaban yang hanya menulis “RMSE = 2,7 dan model A lebih baik” belum lengkap. Jika outcome adalah TPT dalam persen, jawaban yang lebih tepat adalah: “RMSE 2,7 berarti besar kesalahan prediksi tipikal dalam skala akar-kuadrat sekitar 2,7 poin persentase TPT; dibanding baseline 3,5, model memberi peningkatan prediksi, tetapi kegunaan kebijakannya tetap perlu dinilai terhadap variasi antardaerah dan biaya salah prioritas.”
Mahasiswa wajib membedakan referensi metode dan referensi data. Referensi metode menjelaskan teori atau algoritma; sitasi dataset menjelaskan asal bukti empiris. Mengutip buku machine learning tidak menggantikan kewajiban mengutip BPS/Open Data Jawa Barat sebagai pemilik atau penyedia data. Untuk dataset dinamis, catat judul dataset, instansi penghasil, portal, URL, cakupan tahun yang benar-benar digunakan, tanggal akses, unit observasi, satuan, serta status angka (misalnya final, sementara, estimasi, atau proyeksi).
Contoh format dokumentasi data yang direkomendasikan:
Dataset: Tingkat Pengangguran Terbuka Berdasarkan Kabupaten/Kota di Jawa Barat. Penghasil: Badan Pusat Statistik; portal: Open Data Jawa Barat; cakupan portal: 2007–2024; unit analisis: kabupaten/kota-tahun; variabel outcome:
tingkat_pengangguran_terbuka; satuan: persen; tanggal akses: dicatat saat pengunduhan. (Badan Pusat Statistik dan Pemerintah Provinsi Jawa Barat 2026d)
Dalam laporan, mahasiswa tidak boleh menyalin definisi portal tanpa memeriksa denominator dan konteks statistiknya. Misalnya, TPT adalah persentase penganggur terhadap angkatan kerja, bukan terhadap seluruh penduduk. Prinsip yang sama berlaku untuk jumlah penduduk miskin: angka absolut dalam ribu jiwa tidak identik dengan persentase kemiskinan. Perbedaan denominator dapat mengubah ranking wilayah dan rekomendasi kebijakan.
Pada level magister, mahasiswa diharapkan bergerak melampaui eksekusi software. Untuk setiap metode utama, mahasiswa harus dapat menjawab setidaknya enam pertanyaan berikut.
Selain empat tugas besar dan empat kuis berbobot yang dijelaskan pada bagian asesmen, dosen dapat menggunakan latihan berikut sebagai formative checkpoints. Nilainya dapat dimasukkan ke partisipasi atau dipakai sebagai latihan tanpa bobot. Setiap checkpoint dirancang agar mahasiswa terus mengembangkan capstone.
Minggu 1 — Problem framing clinic. Setiap tim membawa dua kandidat masalah regional. Dalam 5 menit, tim harus menjelaskan stakeholder, keputusan, unit observasi, outcome, horizon waktu, dan alasan data science diperlukan. Kelas memberikan kritik apakah pertanyaan terlalu luas, normatif, atau tidak dapat diuji.
Minggu 2 — Metadata challenge. Mahasiswa menerima tiga dataset yang kelihatannya kompatibel, tetapi berbeda cakupan tahun, satuan, atau kode wilayah. Tugasnya adalah menemukan minimal lima risiko integrasi sebelum melakukan join. Kuis singkat meminta mahasiswa menghitung rate, growth, dan CAGR serta menjelaskan kapan masing-masing ukuran menyesatkan.
Minggu 3 — Data-quality audit. Mahasiswa membuat audit table berisi duplicate, missingness, range violation, impossible value, join mismatch, dan perubahan definisi. Setiap keputusan cleaning harus disertai alasan; penghapusan observasi tanpa dokumentasi dinilai sebagai kegagalan reproducibility.
Minggu 4 — EDA evidence board. Setiap tim menghasilkan empat visual/summary yang menjawab empat fungsi berbeda: distribusi, perbandingan, hubungan, dan perubahan waktu. Tim juga harus menuliskan satu temuan yang awalnya tampak menarik tetapi ternyata dapat dijelaskan oleh denominator atau outlier.
Minggu 5 — Visualization red-team. Mahasiswa saling menukar grafik dan mencari potensi manipulasi: truncated axis, kategori terlalu banyak, penggunaan warna tanpa fungsi, agregasi yang menutupi heterogenitas, atau label yang membuat korelasi tampak kausal. Revisi grafik menjadi bagian dari evidence story.
Minggu 6 — Regression defense. Mahasiswa harus memilih satu spesifikasi regresi dan satu alternatif. Mereka menjelaskan arti , asumsi, potensi confounding, multicollinearity, residual pattern, dan mengapa interaksi digunakan atau tidak digunakan. Fokusnya bukan “semua variabel signifikan”, melainkan konsistensi model dengan pertanyaan.
Minggu 7 — Validation lab. Mahasiswa membandingkan baseline mean/median, regresi, serta satu model regularized. Mereka harus menetapkan split sebelum tuning dan menjelaskan mengapa random split atau time-based split lebih sesuai. Jika data panel, mahasiswa mendiskusikan risiko satu wilayah muncul di train dan test dengan observasi tahun berbeda.
Minggu 9 — Complexity budget. Tim hanya boleh memakai model tree-based yang lebih rumit jika dapat menunjukkan peningkatan out-of-sample yang bermakna dibanding baseline dan model sederhana. Selisih metrik harus diterjemahkan ke unit outcome, bukan hanya persen peningkatan abstrak.
Minggu 10 — Threshold workshop. Untuk kasus klasifikasi prioritas intervensi, mahasiswa menghitung confusion matrix pada beberapa threshold dan menyusun tabel konsekuensi kebijakan. Pilihan threshold harus mengacu pada false-positive/false-negative cost dan kapasitas intervensi.
Minggu 11 — Cluster naming discipline. Cluster dilarang diberi nama normatif seperti “maju” dan “tertinggal” sebelum profil indikator diperiksa. Tim harus memberikan nama deskriptif yang berasal dari centroid/medoid atau distribusi indikator, lalu menguji stabilitas cluster terhadap scaling dan jumlah cluster.
Minggu 12 — PCA interpretation. Mahasiswa menjelaskan loadings, scores, eigenvalues, dan explained variance tanpa menyebut PC1 sebagai “indeks pembangunan” secara otomatis. Label substantif hanya boleh diberikan jika pola loading dan konstruk teoritis mendukungnya.
Minggu 13 — Spatial-neighbor challenge. Setiap tim membandingkan minimal dua definisi (misalnya queen contiguity dan k-nearest neighbors) dan menjelaskan perubahan Moran’s atau local pattern. Tujuannya menunjukkan bahwa hasil spasial dipengaruhi definisi neighborhood.
Minggu 14 — Robustness red-team. Tim lain mencoba “merusak” kesimpulan dengan mengganti seed, indikator, bobot, threshold, jumlah cluster, atau spesifikasi model. Kesimpulan yang berubah drastis harus dinyatakan sebagai sensitif, bukan disembunyikan.
Minggu 15 — Policy translation studio. Setiap rekomendasi harus terhubung ke satu temuan, satu kelompok sasaran, satu instrumen, satu risiko implementasi, dan satu indikator monitoring. Kalimat rekomendasi yang generik seperti “pemerintah perlu meningkatkan perhatian” harus direvisi menjadi tindakan yang dapat dinilai.
Minggu 16 — Reproducibility handover. Seorang mahasiswa dari tim lain mencoba membuka dan menjalankan paket project dengan hanya membaca README. Kegagalan karena path lokal, objek yang belum dibuat, file tidak tersedia, atau langkah manual yang tidak terdokumentasi masuk ke reproducibility defect log.
UTS bersifat individual, open-resource terbatas, berbentuk satu kasus data regional terintegrasi. Data disediakan dalam keadaan belum sepenuhnya bersih agar mahasiswa menunjukkan kemampuan audit, bukan sekadar menjalankan model. Distribusi yang disarankan adalah: 15% problem framing dan metadata; 20% cleaning/data quality; 20% EDA/visualisasi; 25% inferensi/regresi; 10% validasi dan diagnostic; 10% interpretasi kebijakan. Nilai UTS dalam komponen akhir tetap 20%; persentase di atas adalah distribusi di dalam skor UTS.
Rumus yang boleh/harus dikuasai: rate/proportion, growth dan CAGR, mean/variance/covariance/correlation, z-score, confidence interval dasar, OLS, , adjusted , RMSE dan MAE. Mahasiswa dapat diberikan satu halaman formula sheet, tetapi harus mampu menjelaskan setiap simbol dan memilih formula yang sesuai.
Contoh stimulus UTS: dataset 27 kabupaten/kota dengan TPT, pertumbuhan PDRB, kemiskinan, dan pendidikan untuk beberapa tahun. Mahasiswa diminta mengaudit denominator, membuat dua visual evidence, mengestimasi regresi, memeriksa minimal dua diagnostic, membandingkan baseline, lalu menulis rekomendasi maksimum 250 kata yang tidak melakukan klaim kausal berlebihan.
UAS menilai sintesis individual dan dipisahkan dari nilai produk kelompok capstone. Distribusi yang disarankan: 20% problem-method alignment; 20% formulasi dan penjelasan metode; 20% validasi/robustness; 20% interpretasi regional dan rekomendasi; 10% reproducibility/data provenance; 10% oral defense dan responsible AI disclosure.
Mahasiswa harus siap menurunkan atau menjelaskan minimal satu rumus yang benar-benar digunakan dalam project, misalnya OLS, logistic likelihood, k-means objective, PCA eigenproblem, atau Moran’s . Pertanyaan lisan diarahkan pada keputusan yang dibuat mahasiswa: “mengapa threshold ini?”, “mengapa ?”, “apa akibat mengganti ?”, “apa bukti bahwa model menggeneralisasi?”, “bagian mana yang dibantu AI dan bagaimana diverifikasi?”.
Setiap analisis kuantitatif pada buku ini mengikuti urutan keluaran yang konsisten agar mahasiswa tidak berhenti pada sintaks. Urutan minimal adalah (1) pemeriksaan data, (2) statistik deskriptif, (3) visualisasi eksploratif, (4) estimasi/model, (5) diagnostik atau evaluasi, (6) visualisasi hasil, dan (7) interpretasi regional. Untuk metode yang tidak memerlukan model prediktif, bagian evaluasi diganti dengan quality check, sensitivity analysis, atau pemeriksaan asumsi yang relevan.
Kode R sengaja ditulis sehingga objek yang penting dicetak langsung di bawah code chunk melalui knitr::kable(), print(), yardstick, atau objek grafik ggplot2. Dengan demikian mahasiswa dapat membaca hubungan antara kode dan hasil, bukan hanya menyalin script.
Protokol berikut berlaku untuk seluruh bab dan tidak diulang pada setiap pertemuan.
Pada jenjang magister, jawaban “package menghasilkan output tersebut” tidak cukup. Setiap output harus dapat dijelaskan melalui definisi → asumsi → keputusan analitik → hasil → ketidakpastian → implikasi regional.
E-book ini dirancang untuk membangun alur berpikir masalah regional → data → eksplorasi → model → validasi → interpretasi → insight → rekomendasi kebijakan/inovasi. R digunakan sebagai computational laboratory, bukan sebagai tujuan akhir. Karena itu, setiap bab selalu menghubungkan metode dengan pertanyaan substantif: apa masalah wilayahnya, indikator apa yang relevan, unit analisisnya apa, apa sumber ketidakpastiannya, dan keputusan apa yang akan didukung oleh hasil analisis?
Mahasiswa Magister Inovasi Regional tidak diwajibkan menjadi machine-learning engineer. Namun, mahasiswa harus mampu menjadi pengguna analitik yang kritis: dapat membedakan analisis deskriptif, inferensial, prediktif, dan kausal; memahami konsekuensi kualitas data; memilih model yang proporsional dengan masalah; mengevaluasi model secara tepat; serta menerjemahkan keluaran statistik menjadi rekomendasi yang dapat dipertanggungjawabkan. Pendekatan ini konsisten dengan orientasi program pada kebijakan publik berbasis data, data-driven decision making, evaluasi kebijakan, dan inovasi regional.
Sains_Data_Inovasi_Regional.Rmd: naskah utama e-book.references.bib: pustaka untuk sitasi otomatis.R/00_setup.R: konfigurasi package dan fungsi utilitas.R/01_generate_simulation_data.R: pembangkit data simulasi dengan set.seed().R/02_download_real_data.R: pengunduh INDO-DAPOER World Bank.R/03_prepare_indodapoer.R: penataan data INDO-DAPOER ke format tidy.R/04_open_data_jabar.R: pola impor Open Data Jawa Barat.data/: snapshot data simulasi dan katalog sumber data nyata.Setiap analisis minimal mencatat: (1) sumber data dan tanggal akses, (2) definisi unit observasi, (3) kode pembersihan data, (4) aturan penanganan missing value/outlier, (5) pemisahan data training-test bila prediktif, (6) seed untuk proses acak, (7) package dan versi, dan (8) deklarasi penggunaan Generative AI. Untuk proyek akhir, hasil yang tidak dapat direproduksi dari kode dan data yang tersedia dianggap belum selesai, meskipun visualisasinya menarik.
Contoh utama menggunakan INDO-DAPOER, basis data subnasional Indonesia dari World Bank yang mencakup lebih dari 200 indikator fiskal, ekonomi, sosial-demografi, dan infrastruktur pada level provinsi/distrik. Data ini sangat baik untuk latihan karena struktur panelnya kaya, tetapi cakupan waktunya berakhir pada 2018 sehingga tidak boleh dipresentasikan sebagai gambaran kondisi terkini. Untuk isu terbaru Jawa Barat, mahasiswa diarahkan ke Open Data Jawa Barat/BPS dan wajib mencatat status angka (final, sementara, proyeksi) serta perubahan definisi/kode wilayah. (World Bank 2026; Pemerintah Provinsi Jawa Barat 2026b; Badan Pusat Statistik 2026)
Sains data untuk inovasi regional dimulai bukan dari algoritma, melainkan dari masalah keputusan. Ketimpangan antarwilayah, kemiskinan, akses layanan, produktivitas UMKM, mobilitas, kualitas lingkungan, dan daya inovasi memiliki mekanisme berbeda. Data science membantu menyatukan data administratif, survei, geospasial, sensor, dan sumber digital menjadi bukti yang dapat diuji. Pada jenjang magister, mahasiswa perlu bergerak dari pertanyaan “metode apa yang bisa digunakan?” ke pertanyaan “bukti apa yang dibutuhkan untuk keputusan ini, dengan asumsi dan keterbatasan apa?”. (Provost dan Fawcett 2013)
Setelah bab ini, mahasiswa mampu: membedakan analisis deskriptif, diagnostik, prediktif, dan preskriptif; merumuskan masalah regional menjadi pertanyaan analitik; menentukan unit analisis; mengidentifikasi stakeholder; dan merancang minimum viable analysis untuk capstone.
Sains data adalah praktik interdisipliner yang menggabungkan pemahaman substantif, statistika, komputasi, dan komunikasi untuk mengekstraksi informasi yang dapat digunakan dari data. Dalam konteks regional, “wilayah” bukan hanya label administratif; wilayah dapat memuat kedekatan spasial, jaringan ekonomi, arus komuter, struktur demografi, dan kapasitas kelembagaan. Karena itu, dua kabupaten dengan indikator rata-rata serupa belum tentu memiliki kebutuhan kebijakan yang sama.
Empat mode analitik yang penting adalah: deskriptif (apa yang terjadi?), diagnostik (pola apa yang menyertainya?), prediktif (apa yang mungkin terjadi pada observasi baru?), dan preskriptif (alternatif tindakan apa yang layak dipertimbangkan?). Analisis prediktif yang akurat tidak otomatis menghasilkan kesimpulan kausal. Korelasi antara internet dan kemiskinan, misalnya, belum membuktikan bahwa peningkatan internet menyebabkan penurunan kemiskinan.
Secara sederhana, data dapat ditulis sebagai matriks
di mana adalah jumlah unit observasi (misalnya kabupaten-tahun), jumlah variabel, dan nilai variabel ke- pada observasi ke-. Outcome yang ingin dijelaskan/prediksi ditulis . Sebuah model prediktif mencari fungsi
dengan vektor fitur wilayah ke- dan prediksi. Kualitas model tidak hanya ditentukan oleh kedekatan terhadap , tetapi juga relevansi fitur, kualitas data, stabilitas, fairness, serta kegunaan keputusan.
Dalam pembelajaran tingkat magister, algoritma dapat dipandang sebagai prosedur untuk memilih fungsi dari suatu kelas fungsi . Jika adalah fungsi kerugian (loss function), risiko populasi didefinisikan sebagai
Distribusi populasi tidak diketahui, sehingga pada data pelatihan kita menggunakan empirical risk
Untuk outcome kontinu, pilihan yang umum adalah squared-error loss
sedangkan untuk keputusan klasifikasi biner dapat digunakan 0–1 loss
Namun biaya kebijakan sering tidak simetris. Misalkan adalah biaya false negative (wilayah membutuhkan intervensi tetapi tidak diprioritaskan) dan biaya false positive. Kerugian keputusan dapat ditulis
Konsekuensinya penting: threshold terbaik secara kebijakan tidak harus 0,5. Nilai threshold harus mempertimbangkan biaya, kapasitas intervensi, serta konsekuensi salah klasifikasi. (James dkk. 2021; Hastie, Tibshirani, dan Friedman 2009)
Banyak persoalan regional menggunakan beberapa indikator. Jika indikator memiliki unit yang berbeda, dua transformasi umum adalah min–max scaling
dan z-score standardization
Indeks komposit berbobot dapat ditulis
Jika indikator “lebih tinggi = lebih buruk”, sedangkan indikator lain “lebih tinggi = lebih baik”, arah harus diseragamkan sebelum agregasi. Untuk skala 0–1, pembalikan sederhana adalah . Pilihan bobot adalah bagian dari desain kebijakan dan harus diuji dengan sensitivity analysis. OECD/JRC menekankan pentingnya kerangka teori, seleksi indikator, normalisasi, pembobotan, agregasi, serta analisis ketidakpastian pada indeks komposit. (OECD dan Joint Research Centre, European Commission 2008)
| Simbol | Makna |
|---|---|
| jumlah unit observasi | |
| jumlah fitur/variabel prediktor | |
| matriks fitur | |
| vektor fitur observasi/wilayah ke- | |
| outcome aktual | |
| outcome prediksi | |
| fungsi/model prediksi | |
| fungsi kerugian | |
| risiko populasi | |
| empirical risk | |
| bobot indikator ke- |
Bayangkan pemerintah daerah harus menentukan 20 kecamatan prioritas. “Memilih model” baru relevan setelah definisi prioritas disepakati: apakah berdasarkan tingkat kemiskinan, tren memburuk, kerentanan guncangan, kekurangan layanan, atau kombinasi beberapa indikator? Sains data yang baik membuat definisi tersebut eksplisit sehingga hasil dapat diaudit.
Misalkan Bappeda memiliki tiga kabupaten hipotetis A, B, dan C. Outcome yang ingin diprioritaskan adalah multiple deprivation. Tiga indikator setelah orientasi “lebih tinggi = lebih buruk” adalah kemiskinan , kekurangan internet , dan kekurangan akses kesehatan . Setelah min–max scaling diperoleh:
| Wilayah | |||
|---|---|---|---|
| A | 0.90 | 0.70 | 0.40 |
| B | 0.55 | 0.85 | 0.80 |
| C | 0.35 | 0.30 | 0.90 |
Dengan bobot ,
Ranking awal adalah A–B–C. Tetapi bila stakeholder menyatakan akses layanan dasar lebih kritis dan bobot menjadi , maka Ranking berubah menjadi B–A–C. Pelajaran: ranking bukan fakta alam; ia merupakan konsekuensi data, definisi indikator, transformasi, dan preferensi bobot. Maka laporan harus memisahkan hasil empiris dari pilihan normatif. (OECD dan Joint Research Centre, European Commission 2008)
Sebelum membuka R, isi enam kotak berikut.
| Pertanyaan | Contoh jawaban |
|---|---|
| Siapa pengambil keputusan? | Bappeda provinsi + dinas terkait |
| Keputusan apa? | memilih 10 kabupaten untuk diagnostic review lanjutan |
| Unit analisis? | kabupaten–tahun |
| Outcome? | indeks kerentanan atau TPT tahun berikutnya |
| Horizon? | alokasi program tahun anggaran berikut |
| Kesalahan paling mahal? | tidak memasukkan wilayah benar-benar rentan |
Bila jawaban “keputusan apa?” masih berupa “mengetahui kondisi”, project belum cukup tajam. Ubah menjadi keputusan yang dapat ditindaklanjuti: prioritas, alokasi, screening, evaluasi, pemantauan, atau desain inovasi.
Anggap 100 wilayah: 20 benar-benar prioritas. Model A menghasilkan FN=2 dan FP=20; model B FN=7 dan FP=5. Jika dan : Walau model B mempunyai lebih sedikit false positive, model A lebih baik menurut cost policy yang ditetapkan. Jika cost berubah, pilihan dapat berubah. Karena itu pemilihan metric dan threshold harus mengikuti konsekuensi keputusan, bukan kebiasaan default software.
set.seed(260811)
idx <- tibble::tribble(
~wilayah, ~kemiskinan, ~internet, ~akses,
"A", 19, 45, 60,
"B", 14, 35, 45,
"C", 10, 70, 40
) |>
mutate(
kemiskinan_mm = (kemiskinan-min(kemiskinan))/(max(kemiskinan)-min(kemiskinan)),
kurang_internet = 1-(internet-min(internet))/(max(internet)-min(internet)),
kurang_akses = 1-(akses-min(akses))/(max(akses)-min(akses)),
score_s1 = .50*kemiskinan_mm + .30*kurang_internet + .20*kurang_akses,
score_s2 = .35*kemiskinan_mm + .25*kurang_internet + .40*kurang_akses
)
knitr::kable(idx, digits = 3, caption = "Sensitivity of regional priority scores")| wilayah | kemiskinan | internet | akses | kemiskinan_mm | kurang_internet | kurang_akses | score_s1 | score_s2 |
|---|---|---|---|---|---|---|---|---|
| A | 19 | 45 | 60 | 1.000 | 0.714 | 0.00 | 0.714 | 0.529 |
| B | 14 | 35 | 45 | 0.444 | 1.000 | 0.75 | 0.672 | 0.706 |
| C | 10 | 70 | 40 | 0.000 | 0.000 | 1.00 | 0.200 | 0.400 |
Perhatikan bahwa kode menyimpan indikator asli dan indikator tertransformasi. Jangan menimpa kolom mentah karena audit trail akan hilang.
set.seed(260801)
contoh_wilayah <- tibble(
wilayah = paste0("W", 1:12),
kemiskinan = runif(12, 4, 20),
internet = runif(12, 35, 95),
akses_layanan = runif(12, 40, 90)
) |>
mutate(skor_prioritas = 0.6*kemiskinan + 0.25*(100-internet) + 0.15*(100-akses_layanan)) |>
arrange(desc(skor_prioritas))
knitr::kable(contoh_wilayah, digits = 2, caption = "Contoh pembentukan skor prioritas wilayah (simulasi)")| wilayah | kemiskinan | internet | akses_layanan | skor_prioritas |
|---|---|---|---|---|
| W6 | 19.53 | 44.94 | 70.63 | 29.89 |
| W5 | 17.09 | 55.12 | 49.86 | 28.99 |
| W12 | 14.64 | 43.64 | 70.98 | 27.23 |
| W3 | 10.65 | 48.82 | 52.30 | 26.34 |
| W1 | 4.49 | 36.43 | 59.87 | 24.61 |
| W8 | 15.68 | 57.89 | 69.55 | 24.50 |
| W4 | 4.01 | 40.70 | 66.96 | 22.18 |
| W2 | 16.44 | 90.05 | 56.19 | 18.92 |
| W10 | 11.79 | 90.01 | 44.67 | 17.87 |
| W7 | 6.21 | 54.16 | 83.45 | 17.67 |
| W11 | 9.46 | 91.96 | 41.85 | 16.41 |
| W9 | 5.16 | 79.46 | 84.76 | 10.52 |
contoh_wilayah |>
dplyr::slice_head(n = 8) |>
ggplot2::ggplot(ggplot2::aes(x = reorder(wilayah, skor_prioritas), y = skor_prioritas)) +
ggplot2::geom_col(fill = "#145B8C") +
ggplot2::coord_flip() +
ggplot2::labs(
title = "Skor prioritas delapan wilayah teratas — data simulasi",
subtitle = "Skor merupakan alat screening; bobot tetap harus diuji sensitivitasnya",
x = NULL, y = "Skor prioritas"
)Contoh ini menunjukkan bahwa definisi indeks adalah keputusan normatif-analitik. Bobot 0,60; 0,25; dan 0,15 bukan “ditemukan” oleh R. Bobot harus dibenarkan dengan teori, proses kebijakan, atau analisis sensitivitas.
INDO-DAPOER menyediakan indikator provinsi dan kabupaten/kota Indonesia dalam kelompok fiskal, ekonomi, sosial-demografi, dan infrastruktur, dengan cakupan historis 1976-2018. Unit observasi praktisnya adalah wilayah-tahun-indikator. Sumber aslinya antara lain BPS dan kementerian/lembaga Indonesia. Lisensinya CC BY 4.0. Kelebihannya adalah keluasan indikator dan format panel; keterbatasan utamanya adalah data tidak mutakhir dan konsistensi definisi perlu diperiksa antarperiode. (World Bank 2026)
Kartu dataset real.
SI.POV.NAPR.ZS = poverty rate (% penduduk), IDX.HDI = Human Development Index, SP.POP.TOTL = total population.# Jika INDO-DAPOER sudah diunduh, gunakan data resmi; bila belum, tampilkan
# struktur indikator dari data simulasi agar e-book tetap dapat diknit offline.
if (dir.exists("data/raw/indodapoer") && length(list.files("data/raw/indodapoer")) > 0) {
source("R/03_prepare_indodapoer.R")
indo <- load_indodapoer()
out <- indo |>
dplyr::distinct(kode_indikator, indikator) |>
dplyr::filter(stringr::str_detect(indikator, stringr::regex("poverty|unemploy|development|GDP", ignore_case = TRUE))) |>
dplyr::arrange(indikator) |>
head(15)
} else {
out <- tibble::tribble(
~kode_indikator, ~indikator,
"SIM.POV", "Kemiskinan (%) — simulasi",
"SIM.TPT", "Tingkat pengangguran terbuka (%) — simulasi",
"SIM.HDI", "Indeks pembangunan manusia — simulasi",
"SIM.GDPPC", "PDRB per kapita (juta) — simulasi"
)
}
knitr::kable(out, caption = "Output: daftar indikator yang relevan dengan problem framing")| kode_indikator | indikator |
|---|---|
| SIM.POV | Kemiskinan (%) — simulasi |
| SIM.TPT | Tingkat pengangguran terbuka (%) — simulasi |
| SIM.HDI | Indeks pembangunan manusia — simulasi |
| SIM.GDPPC | PDRB per kapita (juta) — simulasi |
Langkah pertama bukan langsung memodelkan, tetapi membaca metadata dan mengecek apakah indikator benar-benar merepresentasikan konsep yang sedang dibahas.
Jika suatu wilayah memiliki kemiskinan tinggi tetapi akses internet dan layanan dasar juga rendah, masalahnya dapat mengarah pada multiple deprivation. Sebaliknya, pengangguran tinggi di kota dengan PDRB tinggi dapat menunjukkan mismatch tenaga kerja, struktur industri, atau tekanan urbanisasi. Rekomendasi kebijakan harus mengikuti pola substantif ini, bukan sekadar ranking algoritmik.
simulasi_panel_regional.csv untuk memilih lima wilayah yang tampak paling tertinggal pada 2025 berdasarkan minimal tiga indikator.Studio problem framing (formatif menuju M1). Pilih satu dari sepuluh contoh capstone atau usulkan tema lain. Buat 1 halaman yang memuat: masalah publik; stakeholder; decision question; unit analisis; outcome; minimal 5 kandidat indikator; horizon waktu; risiko salah keputusan; serta satu kalimat yang menjelaskan mengapa analisis tersebut bukan sekadar membuat dashboard.
Rubrik (100): problem significance 20; analytical question 20; unit/outcome clarity 15; data plausibility 15; decision relevance 20; caveat/ethics 10.
Milestone awal: pilih satu masalah regional, tentukan stakeholder, unit analisis, outcome/indikator utama, dan keputusan yang hendak didukung. Hasilnya berupa one-page problem brief.
Sains data regional adalah disiplin pengambilan keputusan berbasis bukti. Algoritma penting, tetapi kualitas formulasi masalah, definisi indikator, data provenance, dan interpretasi kebijakan menentukan apakah analisis benar-benar berguna.
Analisis regional sering gagal bukan karena model, melainkan karena data berasal dari sistem yang berbeda: kode wilayah berubah, definisi indikator tidak identik, periode pencatatan tidak sinkron, dan angka proyeksi diperlakukan seperti hasil observasi. Bab ini menempatkan provenance dan metadata sebagai bagian dari metode ilmiah, bukan urusan administratif.
Mahasiswa mampu memetakan ekosistem data regional, mengevaluasi kualitas sumber, membuat data inventory, membedakan data primer/sekunder/administratif/open data, dan menyusun dokumentasi dataset (datasheet).
Data provenance adalah jejak asal-usul data: siapa produsen data, bagaimana data dikumpulkan, kapan diperbarui, transformasi apa yang dilakukan, dan lisensi apa yang berlaku. Datasheets for datasets membantu mendokumentasikan motivasi, komposisi, proses pengumpulan, preprocessing, penggunaan yang direkomendasikan, serta keterbatasan. (Gebru dkk. 2021)
Dalam analisis regional, cek minimal: unit geografis, kode wilayah, frekuensi waktu, definisi denominator, perubahan metodologi, status angka sementara/final, missingness, dan revision policy. “Jumlah penduduk miskin” tidak sama dengan “persentase penduduk miskin”; perbandingan antarkabupaten membutuhkan denominator.
Untuk indikator berbasis rasio,
di mana adalah pembilang, denominator, dan konstanta skala (misalnya 100 untuk persen atau 1.000 untuk per seribu). Membandingkan tanpa mempertimbangkan dapat menimbulkan size bias.
Missingness dapat diringkas sebagai
dengan fungsi indikator. Nilai adalah proporsi missing untuk variabel .
Mahasiswa harus membedakan tipe indikator karena operasi matematis yang sah berbeda. Count adalah jumlah kejadian/unit, rate menghubungkan kejadian dengan populasi berisiko dan periode waktu, proportion adalah bagian dari keseluruhan, sedangkan index biasanya merupakan transformasi beberapa komponen.
Proporsi:
Rate per penduduk:
Perubahan absolut dan relatif:
Jika interval lebih dari satu tahun, compound annual growth rate (CAGR) adalah
Stock diukur pada titik waktu (misalnya jumlah penduduk pada pertengahan tahun), sedangkan flow diakumulasi selama periode (misalnya investasi selama tahun). Menjumlahkan atau membagi stock dan flow tanpa memperhatikan waktu dapat menghasilkan indikator yang menyesatkan.
Untuk variabel , completeness dapat diringkas sebagai
Jika kunci yang diharapkan unik adalah kombinasi wilayah–tahun, tingkat duplikasi dapat ditulis
Ketika dua sumber digabungkan dengan kunci , match rate adalah
Nilai bukan sekadar masalah teknis. Penyebabnya dapat berupa perubahan kode wilayah, pemekaran, perbedaan kapitalisasi nama, atau cakupan unit yang tidak sama. Join harus didiagnosis sebelum baris tak cocok dihapus.
Gunakan bila teramati dan bila hilang. Secara konseptual:
Klasifikasi ini penting karena complete-case analysis dapat bias ketika missing terkait dengan karakteristik wilayah. Wilayah dengan kapasitas pelaporan rendah, misalnya, mungkin memiliki missingness lebih tinggi. (Little dan Rubin 2019)
Imputasi mean sederhana mempertahankan rata-rata tetapi cenderung mengecilkan varians dan merusak hubungan antarvariabel. Untuk analisis serius, pertimbangkan multiple imputation atau model yang secara eksplisit menangani missingness, disertai sensitivity analysis. (Little dan Rubin 2019)
Jika batas wilayah berubah, indikator historis mungkin harus dikonversi ke constant geography. Secara abstrak, jika adalah nilai pada unit lama dan matriks alokasi dari unit lama ke unit baru, maka
Elemen menyatakan proporsi unit lama yang dialokasikan ke unit baru . Untuk count, bobot dapat berbasis populasi/area sesuai konsep; untuk rate, jangan langsung mengalikan tanpa merekonstruksi numerator dan denominator jika memungkinkan.
Untuk setiap dataset, simpan minimal tuple
Prinsip ini konsisten dengan datasheets for datasets: dokumentasi harus menjelaskan motivasi, komposisi, proses pengumpulan, preprocessing, penggunaan yang direkomendasikan, dan keterbatasan. (Gebru dkk. 2021)
Data berkualitas tidak selalu berarti “tanpa missing”. Yang lebih penting adalah mengetahui mengapa missing terjadi. Wilayah terpencil mungkin lebih sering tidak melaporkan data; jika demikian, menghapus baris missing dapat secara sistematis menghilangkan wilayah yang justru paling membutuhkan kebijakan.
Dua wilayah melaporkan 5.000 dan 3.000 penganggur. Tanpa denominator, wilayah pertama tampak lebih buruk. Jika angkatan kerja masing-masing 100.000 dan 40.000: Maka cerita berubah. Untuk kebijakan tenaga kerja, count berguna untuk memperkirakan volume layanan; rate berguna untuk membandingkan tingkat masalah. Keduanya dapat diperlukan, tetapi menjawab pertanyaan berbeda.
Misalkan rate tiga kabupaten adalah 4%, 8%, 12% dengan angkatan kerja 1 juta, 100 ribu, dan 50 ribu. Mean sederhana adalah 8%. Weighted rate: Perbedaan besar terjadi karena ukuran denominator tidak sama. Agregasi rate tingkat provinsi sebaiknya direkonstruksi dari numerator/denominator yang sesuai jika tersedia, bukan selalu mean kabupaten.
Bayangkan missing rate pelaporan fasilitas kesehatan adalah 5% di perkotaan dan 35% di daerah terpencil. Jika seluruh baris missing dihapus, dataset analitik menjadi lebih “urban” daripada populasi target. Untuk mendiagnosis, modelkan indikator missing: Tujuannya bukan selalu mengestimasi mekanisme missing secara formal, tetapi melihat apakah missingness berpola. (Little dan Rubin 2019)
provenance <- tibble::tribble(
~dataset, ~producer, ~period, ~unit, ~status, ~access_date,
"TPT", "BPS / Open Data Jabar", "2007-2024", "kab/kota-tahun", "published", "2026-08-07",
"UMKM", "Dinas KUK / Open Data Jabar", "2016-2023", "kab/kota-tahun", "projection", "2026-08-07",
"INDO-DAPOER", "World Bank", "1976-2018", "subnational-year", "historical", "2026-08-07"
)
knitr::kable(provenance, caption = "Contoh minimum provenance register")| dataset | producer | period | unit | status | access_date |
|---|---|---|---|---|---|
| TPT | BPS / Open Data Jabar | 2007-2024 | kab/kota-tahun | published | 2026-08-07 |
| UMKM | Dinas KUK / Open Data Jabar | 2016-2023 | kab/kota-tahun | projection | 2026-08-07 |
| INDO-DAPOER | World Bank | 1976-2018 | subnational-year | historical | 2026-08-07 |
Sebelum data dimodelkan, jawab ya/tidak:
Jika beberapa jawaban “tidak”, masalah tersebut harus masuk limitation dan dapat mengubah metode. Sumber data yang kredibel tidak berarti setiap field otomatis siap dipakai.
set.seed(260802)
dq <- tibble(
wilayah = sprintf("W%02d", 1:40),
populasi = round(runif(40, 100000, 3000000)),
kasus = rpois(40, lambda = 200),
akses_data = runif(40)
) |>
mutate(
kasus = if_else(akses_data < .12, NA_integer_, kasus),
rate_per_100k = kasus/populasi*100000
)
dq |>
summarise(n = n(), missing_kasus = mean(is.na(kasus)), median_rate = median(rate_per_100k, na.rm = TRUE)) |>
knitr::kable(digits = 3, caption = "Audit kualitas data sederhana")| n | missing_kasus | median_rate |
|---|---|---|
| 40 | 0.125 | 12.573 |
tibble::tibble(
status = ifelse(is.na(dq$kasus), "Missing", "Tersedia")
) |>
dplyr::count(status) |>
ggplot2::ggplot(ggplot2::aes(status, n, fill = status)) +
ggplot2::geom_col(show.legend = FALSE) +
ggplot2::scale_fill_manual(values = c("Missing" = "#C99A17", "Tersedia" = "#145B8C")) +
ggplot2::labs(title = "Ketersediaan data kasus — simulasi", x = NULL, y = "Jumlah observasi")Open Data Jawa Barat menyediakan dataset mentah dari perangkat daerah dan BPS, dengan pilihan CSV/Excel/API. Contoh yang relevan adalah TPT kabupaten/kota 2007-2024, jumlah penduduk miskin 2002-2025, dan proyeksi UMKM 2016-2023. Perhatikan bahwa dataset UMKM secara eksplisit berstatus proyeksi, sehingga tidak boleh ditafsirkan identik dengan sensus usaha aktual. (Pemerintah Provinsi Jawa Barat 2026b)
Kartu dataset real.
tingkat_pengangguran_terbuka = persen TPT; jumlah_penduduk_miskin = ribu jiwa; proyeksi_jumlah_umkm = proyeksi jumlah unit UMKM; satuan; tahun.katalog <- read_csv("data/katalog_data_real.csv", show_col_types = FALSE)
knitr::kable(katalog[, c("dataset","sumber","cakupan_tahun","unit_observasi")],
caption = "Katalog sumber data nyata untuk mata kuliah")| dataset | sumber | cakupan_tahun | unit_observasi |
|---|---|---|---|
| Tingkat Pengangguran Terbuka berdasarkan Kabupaten/Kota di Jawa Barat | Open Data Jawa Barat / BPS | 2007-2024 | Kabupaten/kota-tahun |
| Jumlah Penduduk Miskin berdasarkan Kabupaten/Kota di Jawa Barat | Open Data Jawa Barat / BPS | 2002-2025 | Kabupaten/kota-tahun |
| Proyeksi Jumlah UMKM berdasarkan Kabupaten/Kota di Jawa Barat | Open Data Jawa Barat / Dinas Koperasi dan Usaha Kecil | 2016-2023 | Kabupaten/kota-tahun |
| Jumlah Penduduk berdasarkan Kabupaten/Kota di Jawa Barat | Open Data Jawa Barat / BPS | 2010-2025 | Kabupaten/kota-tahun |
| Indonesia Database for Policy and Economic Research (INDO-DAPOER) | World Bank Data Catalog; sumber indikator terutama BPS dan kementerian/lembaga Indonesia | 1976-2018 | Provinsi/kabupaten/kota-tahun-indikator |
| World Bank Official Boundaries | World Bank Data Catalog | diperbarui berkala | Geometri admin 0/1/2 |
if (dir.exists("data/raw/indodapoer") && length(list.files("data/raw/indodapoer")) > 0) {
source("R/03_prepare_indodapoer.R")
indo <- load_indodapoer()
quality <- indo |>
dplyr::group_by(kode_indikator, indikator) |>
dplyr::summarise(
prop_missing = mean(is.na(nilai)),
tahun_min = min(tahun[!is.na(nilai)], na.rm = TRUE),
tahun_max = max(tahun[!is.na(nilai)], na.rm = TRUE),
.groups = "drop"
) |>
dplyr::arrange(prop_missing) |>
head(20)
} else {
demo <- readr::read_csv("data/simulasi_panel_regional.csv", show_col_types = FALSE)
quality <- tibble::tibble(
variabel = names(demo),
prop_missing = purrr::map_dbl(demo, ~mean(is.na(.x))),
kelas = purrr::map_chr(demo, ~class(.x)[1])
)
}
knitr::kable(quality, digits = 3, caption = "Output: audit kelengkapan dan struktur data")| variabel | prop_missing | kelas |
|---|---|---|
| wilayah | 0 | character |
| tahun | 0 | numeric |
| urban | 0 | numeric |
| longitude | 0 | numeric |
| latitude | 0 | numeric |
| pdrb_perkapita_juta | 0 | numeric |
| kemiskinan_persen | 0 | numeric |
| tpt_persen | 0 | numeric |
| ipm | 0 | numeric |
| internet_persen | 0 | numeric |
| umkm_per_1000 | 0 | numeric |
| indeks_pendidikan | 0 | numeric |
| akses_kesehatan | 0 | numeric |
| indeks_inovasi | 0 | numeric |
Audit metadata dapat mengubah keputusan analitik. Jika data pengangguran tersedia tahunan tetapi indikator inovasi hanya tersedia pada tahun tertentu, memaksakan model panel tahunan dapat menghasilkan banyak imputasi dan asumsi. Pilihan yang lebih defensible mungkin mengubah unit waktu atau membatasi pertanyaan pada cross-section tertentu.
Buat data dossier untuk tiga sumber data calon capstone. Setiap sumber harus memuat producer, URL, access date, periode, unit observasi, definisi variabel, status angka (final/sementara/proyeksi), lisensi, update frequency, missingness yang terlihat, dan risiko integrasi. Pilih satu sumber yang tidak jadi digunakan dan jelaskan alasan penolakannya.
Milestone 2 dimulai di sini: mahasiswa menyiapkan data dossier berisi sumber, URL, tanggal akses, definisi variabel, periode, unit observasi, lisensi, dan keterbatasan.
Model yang canggih tidak dapat memperbaiki provenance yang tidak jelas. Metadata, denominator, definisi indikator, dan perubahan metodologi adalah bagian inti dari validitas analisis regional.
Data kebijakan hampir selalu memerlukan penataan: nama wilayah tidak konsisten, angka tersimpan sebagai teks, struktur wide/long bercampur, dan indikator harus dinormalisasi. Bab ini memperlakukan data wrangling sebagai proses analitik yang terdokumentasi.
Mahasiswa mampu melakukan import, tipe data, reshape, join, deduplikasi, penanganan missing, deteksi outlier, serta konstruksi indikator yang sesuai unit dan denominator.
Data tidy memiliki satu variabel per kolom, satu observasi per baris, dan satu jenis unit observasi per tabel. (Wickham, Çetinkaya-Rundel, dan Grolemund 2023) Kunci join harus mencerminkan identitas observasi; untuk panel kabupaten/kota biasanya kombinasi kode_wilayah + tahun, bukan hanya nama wilayah.
Feature construction harus mempunyai makna substantif. UMKM per 1.000 penduduk sering lebih dapat dibandingkan antardaerah daripada jumlah UMKM mentah. Transformasi log dapat mengurangi skewness pada nilai ekonomi yang sangat lebar, tetapi interpretasinya berubah.
Standardisasi z-score:
dengan mean dan simpangan baku variabel . Transformasi log yang sering digunakan:
terutama bila dan distribusi sangat skewed. Penambahan 1 mencegah masalah , tetapi harus dinyatakan secara eksplisit.
Dalam tidy data, setiap variabel berada pada kolom, setiap observasi pada baris, dan setiap jenis unit observasi pada tabel tersendiri. Struktur ini mengurangi ambiguitas saat agregasi dan pemodelan. (Wickham 2014; Wickham, Çetinkaya-Rundel, dan Grolemund 2023)
Jika adalah nilai mentah, transformasi log sering dipakai untuk distribusi sangat menceng: dengan ketika nol mungkin muncul. Perubahan unit harus dinyatakan: koefisien pada skala log tidak identik dengan koefisien skala asli.
Z-score:
Robust z-score berbasis median dan MAD:
di mana
Konstanta 1,4826 membuat MAD mendekati simpangan baku untuk data normal. Robust scaling berguna ketika terdapat outlier yang valid secara substantif—misalnya kota metropolitan memang ekstrem dibanding kabupaten rural—dan kita tidak ingin ekstrem tersebut otomatis dianggap kesalahan.
IQR:
Aturan boxplot menandai observasi potensial di luar
Outlier tidak boleh langsung dihapus. Klasifikasikan: (a) data entry error, (b) definisi unit berbeda, (c) kejadian ekstrem nyata, atau (d) perubahan metodologi. Dalam data regional, ekstrem yang nyata sering justru menjadi objek analisis.
Beberapa fitur yang sering lebih bermakna daripada count mentah:
Per kapita
Density dengan luas wilayah.
Share
Lag temporal
Growth
Difference
Location quotient (LQ) untuk konsentrasi sektor di wilayah : menunjukkan konsentrasi relatif di atas rata-rata wilayah pembanding. Interpretasi bergantung pada definisi variabel—tenaga kerja, output, atau unit usaha.
Jika parameter preprocessing (mean, SD, imputation value, PCA loading) dihitung dari seluruh data sebelum train/test split, informasi test set bocor ke proses training. Secara benar, parameter transformasi harus dihitung hanya dari training:
Framework recipes pada tidymodels membantu menerapkan prinsip ini secara sistematis. (Kuhn dan Silge 2022)
Jika Kabupaten A memiliki 200 ribu UMKM dan Kabupaten B 80 ribu UMKM, belum tentu A lebih “entrepreneurial”. Setelah dibagi populasi usia kerja, ranking dapat berubah. Feature engineering yang baik mengubah data menjadi ukuran yang lebih dekat dengan konsep kebijakan.
Jika UMKM suatu wilayah meningkat dari 10.000 menjadi 11.500 unit, Jika baseline , growth rate tidak terdefinisi. Jangan mengganti denominator nol dengan angka kecil tanpa justifikasi karena dapat menciptakan pertumbuhan ekstrem artifisial. Gunakan perubahan absolut atau definisi alternatif.
Wilayah A memiliki 20.000 pekerja manufaktur dari total 100.000 pekerja; provinsi memiliki 300.000 pekerja manufaktur dari 3.000.000 pekerja. Artinya konsentrasi tenaga kerja manufaktur dua kali share provinsi. Bukan berarti produktivitas dua kali lebih tinggi, dan bukan bukti sektor tersebut “lebih baik”.
Jika tabel A memiliki 27 kabupaten/kota × 10 tahun = 270 key dan tabel B setelah join hanya match 258 key: 12 key yang tidak match harus diperiksa. Contoh R:
a <- tibble(wilayah=c("A","B","C"), tahun=2024, x=1:3)
b <- tibble(wilayah=c("A","B","D"), tahun=2024, y=11:13)
anti_join(a,b,by=c("wilayah","tahun"))#> # A tibble: 1 × 3
#> wilayah tahun x
#> <chr> <dbl> <int>
#> 1 C 2024 3
#> # A tibble: 1 × 3
#> wilayah tahun y
#> <chr> <dbl> <int>
#> 1 D 2024 13
anti_join() sering lebih penting daripada left_join() karena mengungkap observasi yang hilang akibat perbedaan key.
Gunakan kategori keputusan berikut:
| Temuan | Diagnosis | Tindakan |
|---|---|---|
| nilai negatif pada jumlah penduduk | impossible | cek source/parse; jangan imputasi diam-diam |
| PDRB per kapita sangat tinggi | plausible structural extreme | pertahankan; pertimbangkan log/robust scaling |
| TPT 850 | kemungkinan decimal/unit error | cek metadata/satuan |
| lon/lat di luar Indonesia | coordinate error | koreksi dari sumber atau exclude terdocumentasi |
set.seed(260813)
dat <- readr::read_csv("data/simulasi_panel_regional.csv", show_col_types = FALSE) |>
dplyr::filter(tahun == 2025) |>
dplyr::select(kemiskinan_persen, pdrb_perkapita_juta, internet_persen, tpt_persen, ipm)
split <- initial_split(dat, prop = .8, strata = kemiskinan_persen)
train <- training(split); test <- testing(split)
rec <- recipe(kemiskinan_persen ~ ., data = train) |>
step_impute_median(all_numeric_predictors()) |>
step_zv(all_predictors()) |>
step_normalize(all_numeric_predictors())
prep_rec <- prep(rec, training = train)
train_baked <- bake(prep_rec, new_data = NULL)
test_baked <- bake(prep_rec, new_data = test)
knitr::kable(head(train_baked, 6), digits = 3, caption = "Output: data training setelah preprocessing leakage-safe")| pdrb_perkapita_juta | internet_persen | tpt_persen | ipm | kemiskinan_persen |
|---|---|---|---|---|
| -1.476 | -0.628 | -0.719 | -0.328 | 9.992 |
| 0.459 | 0.524 | 1.979 | 0.718 | 6.006 |
| 0.643 | 0.396 | -0.477 | -0.561 | 8.570 |
| -0.070 | 0.398 | 0.303 | 0.000 | 10.076 |
| -0.391 | 0.275 | -0.596 | -0.468 | 11.637 |
| -0.546 | -1.018 | -0.758 | -0.899 | 8.979 |
Mean/median dan SD dipelajari dari training. Inilah alasan workflow modeling sebaiknya menyatukan preprocessing dan model. (Kuhn dan Silge 2022)
Setiap fitur baru harus memiliki: formula; denominator; unit; temporal alignment; rationale; potential leakage; dan interpretasi. Fitur growth_2024 tidak boleh digunakan untuk memprediksi outcome 2023; fitur “jumlah penerima program” dapat menjadi post-treatment variable bila digunakan untuk menjelaskan outcome setelah program.
set.seed(260803)
raw <- tibble(
kab_kota = c("Kab. A", "kab a ", "KOTA B", "Kota C"),
tahun = c("2024", "2024", "2024", "2024"),
penduduk = c("1,200,000", "1,200,000", "850,000", NA),
umkm = c(85000, 85000, 62000, 21000)
)
clean <- raw |>
clean_names() |>
mutate(
kab_kota = str_to_title(str_squish(kab_kota)),
tahun = as.integer(tahun),
penduduk = parse_number(penduduk),
umkm_per_1000 = umkm/penduduk*1000
) |>
distinct(kab_kota, tahun, .keep_all = TRUE)
knitr::kable(clean, digits = 2, caption = "Contoh cleaning dan konstruksi rate")| kab_kota | tahun | penduduk | umkm | umkm_per_1000 |
|---|---|---|---|---|
| Kab. A | 2024 | 1200000 | 85000 | 70.83 |
| Kab A | 2024 | 1200000 | 85000 | 70.83 |
| Kota B | 2024 | 850000 | 62000 | 72.94 |
| Kota C | 2024 | NA | 21000 | NA |
Dataset TPT Open Data Jawa Barat memuat kode provinsi, nama provinsi, kode kabupaten/kota, nama kabupaten/kota, TPT (%), satuan, dan tahun. Kode wilayah sebaiknya dijadikan kunci utama saat menggabungkannya dengan data penduduk atau kemiskinan. Periksa apakah standar kode wilayah konsisten antarversi dataset. (Pemerintah Provinsi Jawa Barat 2026b)
Kartu dataset real.
kode_provinsi, nama_provinsi, kode_kabupaten_kota, nama_kabupaten_kota, tingkat_pengangguran_terbuka = persentase TPT, satuan = persen, tahun.panel <- read_csv("data/simulasi_panel_regional.csv", show_col_types = FALSE)
panel_2025 <- panel |>
filter(tahun == 2025) |>
mutate(
pdrb_log = log1p(pdrb_perkapita_juta),
kemiskinan_z = as.numeric(scale(kemiskinan_persen))
)
panel_2025 |>
select(wilayah, pdrb_perkapita_juta, pdrb_log, kemiskinan_persen, kemiskinan_z) |>
head() |>
knitr::kable(digits = 3)| wilayah | pdrb_perkapita_juta | pdrb_log | kemiskinan_persen | kemiskinan_z |
|---|---|---|---|---|
| Wilayah_01 | 31.612 | 3.485 | 9.992 | 0.061 |
| Wilayah_02 | 65.249 | 4.193 | 7.681 | -1.257 |
| Wilayah_03 | 52.521 | 3.980 | 6.006 | -2.212 |
| Wilayah_04 | 54.513 | 4.017 | 8.570 | -0.750 |
| Wilayah_05 | 46.803 | 3.867 | 10.076 | 0.109 |
| Wilayah_06 | 43.338 | 3.792 | 11.637 | 0.999 |
panel_2025 |>
ggplot2::ggplot(ggplot2::aes(pdrb_perkapita_juta, pdrb_log)) +
ggplot2::geom_point(size = 2.2, colour = "#145B8C") +
ggplot2::labs(
title = "Transformasi log pada PDRB per kapita — simulasi",
subtitle = "Transformasi mengompresi nilai besar dan dapat membantu stabilisasi skala",
x = "PDRB per kapita (juta)", y = "log(1 + PDRB per kapita)"
)if (file.exists("data/raw/tpt_jabar.csv") && file.exists("data/raw/penduduk_jabar.csv")) {
tpt <- readr::read_csv("data/raw/tpt_jabar.csv", show_col_types = FALSE) |> janitor::clean_names()
penduduk <- readr::read_csv("data/raw/penduduk_jabar.csv", show_col_types = FALSE) |> janitor::clean_names()
regional <- tpt |>
dplyr::inner_join(penduduk, by = c("kode_kabupaten_kota", "tahun"), suffix = c("_tpt", "_pop"))
out <- head(regional, 8)
} else {
out <- readr::read_csv("data/simulasi_panel_regional.csv", show_col_types = FALSE) |>
dplyr::select(wilayah, tahun, tpt_persen, pdrb_perkapita_juta, kemiskinan_persen) |>
head(8)
}
knitr::kable(out, digits = 2, caption = "Output: hasil integrasi data; gunakan data simulasi bila raw data resmi belum tersedia")| wilayah | tahun | tpt_persen | pdrb_perkapita_juta | kemiskinan_persen |
|---|---|---|---|---|
| Wilayah_01 | 2019 | 7.01 | 17.25 | 17.55 |
| Wilayah_01 | 2020 | 9.29 | 18.82 | 16.01 |
| Wilayah_01 | 2021 | 8.16 | 32.33 | 15.19 |
| Wilayah_01 | 2022 | 7.82 | 29.36 | 15.32 |
| Wilayah_01 | 2023 | 7.89 | 23.84 | 15.52 |
| Wilayah_01 | 2024 | 6.99 | 28.46 | 12.75 |
| Wilayah_01 | 2025 | 7.12 | 31.61 | 9.99 |
| Wilayah_02 | 2019 | 9.07 | 44.30 | 13.41 |
Cleaning adalah bagian dari argumentasi. Menghapus duplikat tanpa memahami penyebabnya dapat menghapus kategori yang sebenarnya berbeda. Mengimputasi missing dengan mean provinsi dapat meratakan disparitas dan membuat wilayah ekstrem tampak “normal”. Setiap keputusan cleaning perlu log perubahan.
simulasi_panel_regional.csv dan tambahkan unit pada nama variabel.Gunakan dua tabel regional yang memiliki kunci wilayah–tahun. Lakukan: cleaning nama kolom; audit duplicate; audit missing; validasi join; minimal tiga feature engineering (per capita/rate, growth, lag/LQ); dokumentasikan setiap keputusan. Serahkan .Rmd dan HTML.
Rubrik: audit data 25; correctness transform 25; join validation 20; reproducibility 15; interpretasi 15.
Kuis 10–15 soal campuran konsep dan potongan kode. Kisi-kisi: unit analisis; denominator; provenance; tidy data; missingness; scaling; outlier; feature engineering; leakage preprocessing.
Mahasiswa menyerahkan data cleaning log: input, transformasi, alasan, jumlah baris sebelum/sesudah, dan isu yang belum terselesaikan.
Wrangling bukan kosmetik. Kesalahan unit, denominator, kode wilayah, dan join dapat menghasilkan kesimpulan kebijakan yang salah meskipun model dihitung dengan benar.
EDA adalah proses menguji struktur data sebelum memaksakan model. Untuk data regional, EDA harus melihat distribusi, tren, heterogenitas antardaerah, hubungan antarindikator, missingness, dan kemungkinan struktur spasial/temporal. (Tukey 1977)
Mahasiswa mampu menyusun ringkasan numerik dan grafis, membandingkan distribusi antarwilayah/waktu, mendeteksi pola nonlinier/outlier, dan merumuskan hipotesis analitik dari EDA.
Ukuran pemusatan (mean, median), penyebaran (SD, IQR), quantile, dan korelasi harus dipilih sesuai distribusi dan tujuan. Untuk data skewed, median sering lebih stabil daripada mean. Korelasi Pearson mengukur asosiasi linear, sedangkan Spearman berbasis ranking dan lebih robust terhadap nonnormalitas tertentu.
Mean dan variance sampel:
Korelasi Pearson:
Rata-rata aritmetik:
Rata-rata tertimbang—misalnya rata-rata provinsi dari rate kabupaten dengan bobot populasi yang relevan:
Varians sampel dan simpangan baku:
Coefficient of variation: berguna untuk membandingkan dispersi relatif pada variabel dengan skala berbeda ketika mean positif dan bermakna.
Pearson correlation mengukur hubungan linear, bukan hubungan kausal. Spearman correlation adalah Pearson correlation pada ranks dan lebih sesuai ketika hubungan monotonic tetapi tidak linear atau ketika robust terhadap skala ordinal dibutuhkan.
Untuk nilai non-negatif yang diurutkan , salah satu bentuk koefisien Gini adalah
menunjukkan kesetaraan sempurna; nilai lebih tinggi menunjukkan konsentrasi lebih besar. Pada indikator regional, jelaskan apa yang didistribusikan—pendapatan, PDRB per kapita, kapasitas layanan, atau investasi—karena makna normatifnya berbeda.
Theil index:
Keunggulan Theil adalah dekomposabilitas antar dan dalam kelompok, bermanfaat saat membedakan ketimpangan antarkawasan metropolitan/nonmetropolitan atau antar koridor pembangunan.
Quantile memenuhi secara konseptual . Median adalah . Untuk distribusi menceng, laporkan median dan IQR selain mean dan SD. Perbedaan mean–median sendiri dapat memberi sinyal konsentrasi ekstrem.
EDA bukan “membuat banyak grafik”, tetapi siklus
Tukey menekankan EDA sebagai eksplorasi yang membuka struktur data sebelum pemodelan konfirmatori. (Tukey 1977) Untuk konteks regional, minimal bedakan variasi antarwilayah, antarwaktu, dan interaksi wilayah–waktu.
Untuk indikator , dekomposisi konseptual memisahkan rata-rata umum , efek wilayah , efek waktu , dan residual. Walaupun belum menjadi model panel formal, struktur ini membantu mahasiswa bertanya apakah perbedaan didominasi karakteristik persisten wilayah atau shock waktu bersama.
Dua provinsi dapat memiliki mean kemiskinan sama tetapi distribusi kabupaten sangat berbeda. Salah satu homogen, yang lain memiliki beberapa kantong kemiskinan ekstrem. Kebijakan yang hanya melihat mean provinsi akan kehilangan informasi target.
Pendapatan per kapita hipotetis lima wilayah: 20, 22, 24, 26, 100. Mean: median = 24. Satu wilayah ekstrem menggeser mean jauh dari mayoritas. Tidak ada statistik yang “lebih benar” secara universal: mean relevan untuk total/expectation; median lebih representatif untuk typical region saat skew tinggi.
Jika indikator A=60 dengan populasi 1 juta dan B=80 dengan populasi 100 ribu, mean sederhana 70, tetapi Pertanyaan substantif menentukan bobot: populasi, rumah tangga, angkatan kerja, atau bobot sampling.
Untuk tiga nilai yang sudah diurutkan: Gini sensitif pada keseluruhan distribusi. Jika satu wilayah melonjak menjadi 100, Gini meningkat. Tetapi Gini tidak memberi tahu wilayah mana yang tertinggal; selalu kombinasikan dengan distribusi/ranking/peta.
Theil memberi nol ketika semua . Karena term bertambah untuk nilai yang menyimpang, indeks meningkat dengan ketimpangan. Kelebihan untuk regional analytics adalah dekomposisi: sehingga kita dapat bertanya apakah ketimpangan provinsi terutama berasal dari perbedaan antar-kawasan atau variasi di dalam kawasan.
Untuk capstone, minimal isi matriks berikut.
| Perspektif | Pertanyaan | Statistik/grafik |
|---|---|---|
| cross-section | wilayah mana ekstrem? | boxplot, rank, map |
| temporal | membaik/memburuk? | line, growth, slope |
| bivariate | variabel bergerak bersama? | scatter/correlation |
| multivariate | pola gabungan? | pairwise, PCA/cluster kemudian |
| uncertainty | seberapa stabil? | CI, sensitivity, missing analysis |
panel <- readr::read_csv("data/simulasi_panel_regional.csv", show_col_types=FALSE)
panel_2025 <- panel |> filter(tahun==2025)
panel_2025 |>
summarise(
n=n(),
mean_pov=mean(kemiskinan_persen),
median_pov=median(kemiskinan_persen),
sd_pov=sd(kemiskinan_persen),
iqr_pov=IQR(kemiskinan_persen),
cv_pov=sd_pov/mean_pov
) |> knitr::kable(digits=3)| n | mean_pov | median_pov | sd_pov | iqr_pov | cv_pov |
|---|---|---|---|---|---|
| 27 | 9.886 | 9.837 | 1.753 | 2.329 | 0.177 |
Setelah statistik keluar, tugas mahasiswa bukan membaca angka satu per satu, tetapi menghubungkan: apakah mean–median berbeda? apakah CV besar? apakah outlier valid? apakah tahun 2025 representatif atau shock?
panel <- read_csv("data/simulasi_panel_regional.csv", show_col_types = FALSE)
latest <- panel |> filter(tahun == max(tahun))
latest |>
summarise(across(c(kemiskinan_persen, tpt_persen, ipm, internet_persen),
list(mean = mean, median = median, sd = sd))) |>
pivot_longer(everything()) |>
knitr::kable(digits = 2, caption = "Ringkasan indikator regional 2025 (simulasi)")| name | value |
|---|---|
| kemiskinan_persen_mean | 9.89 |
| kemiskinan_persen_median | 9.84 |
| kemiskinan_persen_sd | 1.75 |
| tpt_persen_mean | 8.07 |
| tpt_persen_median | 7.75 |
| tpt_persen_sd | 1.10 |
| ipm_mean | 70.74 |
| ipm_median | 70.68 |
| ipm_sd | 1.18 |
| internet_persen_mean | 83.44 |
| internet_persen_median | 85.60 |
| internet_persen_sd | 8.19 |
latest |>
ggplot(aes(internet_persen, kemiskinan_persen)) +
geom_point() +
geom_smooth(method = "lm", se = TRUE) +
labs(x = "Akses internet (%)", y = "Kemiskinan (%)",
title = "EDA: hubungan internet dan kemiskinan - data simulasi")Gunakan Poverty Rate (SI.POV.NAPR.ZS), HDI (IDX.HDI), populasi (SP.POP.TOTL), dan literacy rate (SE.LITR.15UP.ZS) dari INDO-DAPOER. Metadata World Bank menyatakan sumber indikator tersebut terutama BPS/SUSENAS. Data historis dapat digunakan untuk mengamati disparitas, tetapi batas periode harus dicantumkan. (World Bank 2026)
Kartu dataset real.
SI.POV.NAPR.ZS = poverty rate (%), IDX.HDI = HDI, SP.POP.TOTL = total population, SE.LITR.15UP.ZS = literacy rate usia 15+.if (dir.exists("data/raw/indodapoer") && length(list.files("data/raw/indodapoer")) > 0) {
source("R/03_prepare_indodapoer.R")
indo <- load_indodapoer()
eda <- indo |>
dplyr::filter(kode_indikator %in% c("SI.POV.NAPR.ZS", "IDX.HDI"), tahun == 2018) |>
dplyr::select(wilayah, kode_indikator, nilai) |>
tidyr::pivot_wider(names_from = kode_indikator, values_from = nilai)
ggplot2::ggplot(eda, ggplot2::aes(IDX.HDI, SI.POV.NAPR.ZS)) +
ggplot2::geom_point(alpha = .65) + ggplot2::geom_smooth(method = "lm") +
ggplot2::labs(x = "HDI", y = "Poverty rate (%)", title = "EDA data INDO-DAPOER 2018")
} else {
eda <- readr::read_csv("data/simulasi_panel_regional.csv", show_col_types = FALSE) |> dplyr::filter(tahun == 2025)
ggplot2::ggplot(eda, ggplot2::aes(ipm, kemiskinan_persen)) +
ggplot2::geom_point(alpha = .7) + ggplot2::geom_smooth(method = "lm") +
ggplot2::labs(x = "IPM", y = "Kemiskinan (%)", title = "Output fallback: EDA data simulasi")
}eda4 <- readr::read_csv("data/simulasi_panel_regional.csv", show_col_types = FALSE) |>
dplyr::filter(tahun == 2025)
vars4 <- c("pdrb_perkapita_juta", "kemiskinan_persen", "tpt_persen", "ipm", "internet_persen", "indeks_inovasi")
summary4 <- eda4 |>
dplyr::summarise(dplyr::across(dplyr::all_of(vars4), list(mean=mean, median=median, sd=sd, min=min, q1=~quantile(.x,.25), q3=~quantile(.x,.75), max=max))) |>
tidyr::pivot_longer(dplyr::everything(), names_to=c("indikator","stat"), names_pattern="(.*)_(mean|median|sd|min|q1|q3|max)") |>
tidyr::pivot_wider(names_from=stat, values_from=value)
knitr::kable(summary4, digits=2, caption="Ringkasan lengkap indikator regional tahun 2025")| indikator | mean | median | sd | min | q1 | q3 | max |
|---|---|---|---|---|---|---|---|
| pdrb_perkapita_juta | 49.22 | 50.90 | 10.86 | 24.04 | 41.56 | 56.10 | 66.15 |
| kemiskinan_persen | 9.89 | 9.84 | 1.75 | 6.01 | 8.77 | 11.10 | 13.05 |
| tpt_persen | 8.07 | 7.75 | 1.10 | 6.69 | 7.19 | 8.72 | 10.35 |
| ipm | 70.74 | 70.68 | 1.18 | 67.78 | 70.02 | 71.50 | 73.42 |
| internet_persen | 83.44 | 85.60 | 8.19 | 65.66 | 76.90 | 88.74 | 96.99 |
| indeks_inovasi | 68.25 | 69.00 | 4.12 | 60.29 | 65.42 | 71.06 | 76.82 |
ggplot2::ggplot(eda4, ggplot2::aes(kemiskinan_persen)) +
ggplot2::geom_histogram(ggplot2::aes(y=ggplot2::after_stat(density)), bins=10) +
ggplot2::geom_density(linewidth=1) +
ggplot2::geom_vline(xintercept=median(eda4$kemiskinan_persen), linetype=2) +
ggplot2::labs(title="Distribusi kemiskinan regional", subtitle="Histogram, density, dan median", x="Kemiskinan (%)", y="Density")ggplot2::ggplot(eda4, ggplot2::aes(pdrb_perkapita_juta, kemiskinan_persen, shape=factor(urban))) +
ggplot2::geom_point(size=2.7, alpha=.8) +
ggplot2::geom_smooth(method="lm", se=TRUE) +
ggplot2::labs(title="PDRB per kapita dan kemiskinan", x="PDRB per kapita (juta)", y="Kemiskinan (%)", shape="Urban")cor4 <- cor(eda4 |> dplyr::select(dplyr::all_of(vars4)), use="pairwise.complete.obs")
cor_long4 <- as.data.frame(as.table(cor4))
ggplot2::ggplot(cor_long4, ggplot2::aes(Var1,Var2,fill=Freq)) +
ggplot2::geom_tile() + ggplot2::geom_text(ggplot2::aes(label=sprintf("%.2f",Freq)), size=3) +
ggplot2::scale_fill_gradient2(limits=c(-1,1), midpoint=0) +
ggplot2::coord_equal() + ggplot2::labs(title="Matriks korelasi indikator regional",x=NULL,y=NULL,fill="r") +
ggplot2::theme(axis.text.x=ggplot2::element_text(angle=45,hjust=1))Jika hubungan HDI-kemiskinan negatif tetapi terdapat wilayah yang jauh dari pola umum, outlier tersebut justru menarik untuk case tracing: apakah ada struktur ekonomi khusus, kualitas layanan, urbanisasi, atau masalah measurement? EDA menghasilkan pertanyaan baru, bukan hanya grafik.
Susun regional disparity profile untuk satu indikator utama dan minimal dua indikator penjelas. Wajib menyajikan mean/median/SD/IQR, CV atau ukuran ketimpangan, top–bottom regions, trend, serta dua hipotesis substantif yang belum diklaim sebagai kausal.
Milestone EDA harus menghasilkan 3-5 temuan yang dapat ditindaklanjuti, bukan puluhan grafik tanpa narasi. Setiap grafik perlu menjawab pertanyaan tertentu.
EDA adalah mekanisme quality control dan pembentuk hipotesis. Untuk konteks regional, selalu lihat distribusi, waktu, dan heterogenitas antarwilayah sebelum membangun model.
Visualisasi kebijakan harus cepat dipahami, tetapi tidak boleh mengorbankan ketepatan. Grafik yang baik mengarahkan perhatian pada pesan substantif sekaligus menyediakan konteks: unit, baseline, skala, denominator, dan ketidakpastian. Grammar of Graphics menyediakan kerangka sistematis untuk memetakan data ke estetika visual. (Wilkinson 2005; Tufte 2001)
Mahasiswa mampu memilih bentuk grafik sesuai pertanyaan, menghindari visual yang menyesatkan, membangun data story, dan merancang prototipe dashboard regional.
Data storytelling menggabungkan evidence, narrative, dan visual design. Narasi kebijakan umumnya mengikuti: konteks → gap/disparitas → siapa/di mana → faktor terkait → implikasi → opsi tindakan. Dashboard berbeda dari laporan: dashboard membantu monitoring/eksplorasi, sedangkan laporan dapat memuat argumentasi lebih panjang.
Perubahan absolut dan relatif:
Keduanya dapat menghasilkan pesan berbeda. Kenaikan 2 poin persentase dari 4% ke 6% adalah +2 pp tetapi +50% secara relatif.
Jika grafik menggunakan log scale, hubungan visual berubah. Untuk , Perbedaan pada skala log berhubungan dengan rasio pada skala asli: Karena itu, setiap transformasi sumbu harus disebutkan dan dipahami, bukan dianggap dekorasi.
Indeks dengan tahun dasar : Nilai berarti 25% di atas level tahun dasar, bukan “naik 125%”. Untuk membandingkan trajectory kabupaten dengan skala absolut sangat berbeda, indeks dapat lebih informatif daripada plot count.
Untuk dua titik waktu, Jika model tren linear , maka adalah perubahan rata-rata per unit waktu, dengan asumsi tren linear memadai.
Dalam Grammar of Graphics, grafik adalah pemetaan data ke aesthetics—position, length, color, shape, size—plus geometric objects dan coordinate system. (Wilkinson 2005) Untuk perbandingan presisi, posisi pada skala bersama umumnya lebih mudah dibaca dibanding area/volume. Karena itu bubble chart yang menarik secara visual belum tentu tepat untuk membandingkan perbedaan kecil.
Untuk choropleth, klasifikasi nilai dapat menggunakan quantile. Jika kelas, batas kuantil adalah . Namun klasifikasi quantile membuat tiap kelas berisi jumlah wilayah relatif sama dan dapat menyembunyikan gap substantif; equal interval dan natural breaks memberi pesan berbeda. Metode klasifikasi wajib dilaporkan.
Jika estimasi memiliki standard error , interval aproksimasi 95% adalah untuk kondisi asimtotik yang memadai. Menampilkan ribbon/interval membantu mencegah pembaca memperlakukan estimasi sebagai angka pasti.
Satu evidence story yang kuat memiliki struktur:
“Pengangguran turun” adalah claim; grafik trend adalah evidence; perubahan definisi atau shock pandemi adalah context; interval atau sensitivitas adalah uncertainty; implikasi target program adalah decision implication. Visualisasi yang indah tanpa lima komponen ini berisiko menjadi poster, bukan alat kebijakan. (Tufte 2001)
Grafik bar cocok untuk membandingkan kategori; line chart untuk tren waktu; scatterplot untuk hubungan; peta untuk pola geografis. Peta bukan default untuk semua indikator regional. Jika tujuan hanya ranking 27 kabupaten, sorted dot plot sering lebih mudah dibaca daripada choropleth.
Jika TPT wilayah A adalah 10% pada 2020 dan 7% pada 2024, indeks basis 2020: Artinya level 2024 adalah 70% dari level 2020 atau turun 30% relatif terhadap baseline. Jangan menulis “TPT menjadi 70%” tanpa menyebut bahwa 70 adalah indeks, bukan rate aktual.
Dari 10% menjadi 7% selama 4 tahun: Perubahan relatif: “Turun 3 percentage points” berbeda dari “turun 30 persen”. Bahasa kebijakan harus membedakan percentage point dan percent change.
Sebelum menggunakan grafik, cek:
Peta sebaiknya tidak digunakan hanya karena data memiliki nama wilayah. Jika pertanyaan adalah tren 20 tahun, line chart sering lebih efektif; peta membantu ketika spatial pattern substantif.
sel <- panel |> filter(wilayah %in% unique(wilayah)[1:5])
ggplot(sel, aes(tahun, kemiskinan_persen, group=wilayah, color=wilayah)) +
geom_line(linewidth=.8) + geom_point(size=1.5) +
labs(title="Perubahan kemiskinan lima wilayah simulasi",
subtitle="Bandingkan arah dan kecepatan perubahan, bukan hanya ranking tahun terakhir",
x=NULL, y="Kemiskinan (%)", color="Wilayah") +
theme(legend.position="bottom")Setelah grafik, tulis tiga jenis kalimat: pattern (“semua turun tetapi kecepatannya berbeda”), exception (“wilayah X stagnan”), dan implication (“intervensi seragam mungkin kurang tepat”).
Caption seharusnya menjawab: apa yang diukur; unit; periode; denominator; sumber; dan caveat. Contoh: “TPT kabupaten/kota Jawa Barat, persen angkatan kerja, 2007–2024; sumber BPS melalui Open Data Jawa Barat. Perubahan seri perlu dibaca bersama metadata dan kondisi pasar kerja.” (Badan Pusat Statistik dan Pemerintah Provinsi Jawa Barat 2026d)
latest <- read_csv("data/simulasi_panel_regional.csv", show_col_types = FALSE) |>
filter(tahun == 2025) |>
arrange(desc(kemiskinan_persen)) |>
slice_head(n = 12)
ggplot(latest, aes(x = reorder(wilayah, kemiskinan_persen), y = kemiskinan_persen)) +
geom_col() +
coord_flip() +
labs(x = NULL, y = "Kemiskinan (%)",
title = "12 wilayah dengan kemiskinan tertinggi (simulasi)",
subtitle = "Ranking digunakan untuk screening awal, bukan otomatis penetapan prioritas")TPT Open Data Jawa Barat memiliki seri tahunan 2007-2024, sehingga cocok untuk visualisasi tren dan perbandingan kabupaten/kota. Dataset menghasilkan persentase TPT, bukan jumlah penganggur; untuk beban absolut perlu sumber jumlah angkatan kerja atau jumlah penganggur. (Pemerintah Provinsi Jawa Barat 2026b)
Kartu dataset real.
tingkat_pengangguran_terbuka = persentase angkatan kerja yang menganggur menurut definisi statistik produsen; satuan = persen; tahun.if (file.exists("data/raw/tpt_jabar.csv")) {
tpt <- readr::read_csv("data/raw/tpt_jabar.csv", show_col_types = FALSE) |> janitor::clean_names()
dat_plot <- tpt |> dplyr::group_by(nama_kabupaten_kota) |> dplyr::filter(dplyr::n() >= 3) |> dplyr::ungroup() |> dplyr::slice_head(n = 80)
ggplot2::ggplot(dat_plot, ggplot2::aes(tahun, tingkat_pengangguran_terbuka, group = nama_kabupaten_kota)) +
ggplot2::geom_line(alpha=.55) + ggplot2::labs(y="TPT (%)", title="Tren TPT — data resmi yang tersedia")
} else {
dat_plot <- readr::read_csv("data/simulasi_panel_regional.csv", show_col_types = FALSE) |>
dplyr::filter(wilayah %in% unique(wilayah)[1:5])
ggplot2::ggplot(dat_plot, ggplot2::aes(tahun, tpt_persen, group=wilayah, color=wilayah)) +
ggplot2::geom_line(linewidth=.9) + ggplot2::geom_point() +
ggplot2::labs(y="TPT (%)", title="Output fallback: tren TPT lima wilayah simulasi", color="Wilayah")
}vis5 <- readr::read_csv("data/simulasi_panel_regional.csv", show_col_types = FALSE)
sel5 <- unique(vis5$wilayah)[1:6]
ggplot2::ggplot(vis5 |> dplyr::filter(wilayah %in% sel5), ggplot2::aes(tahun, kemiskinan_persen, group=wilayah, colour=wilayah)) +
ggplot2::geom_line(linewidth=.9) + ggplot2::geom_point(size=1.8) +
ggplot2::labs(title="Perubahan kemiskinan: contoh enam wilayah", y="Kemiskinan (%)", colour="Wilayah")rank5 <- vis5 |> dplyr::filter(tahun==max(tahun)) |> dplyr::arrange(dplyr::desc(kemiskinan_persen)) |>
dplyr::select(wilayah, kemiskinan_persen, tpt_persen, ipm, internet_persen)
knitr::kable(rank5, digits=2, caption="Evidence table untuk mendampingi visual ranking")| wilayah | kemiskinan_persen | tpt_persen | ipm | internet_persen |
|---|---|---|---|---|
| Wilayah_23 | 13.05 | 7.05 | 69.78 | 72.33 |
| Wilayah_07 | 12.94 | 8.68 | 71.95 | 78.72 |
| Wilayah_15 | 12.64 | 7.56 | 69.35 | 75.14 |
| Wilayah_19 | 11.81 | 7.54 | 70.19 | 76.92 |
| Wilayah_25 | 11.67 | 6.69 | 71.38 | 69.83 |
| Wilayah_06 | 11.64 | 7.25 | 69.97 | 84.58 |
| Wilayah_21 | 11.24 | 6.74 | 67.78 | 65.66 |
| Wilayah_09 | 10.97 | 9.63 | 70.38 | 85.60 |
| Wilayah_17 | 10.55 | 7.31 | 70.99 | 79.71 |
| Wilayah_27 | 10.10 | 7.65 | 69.34 | 90.37 |
| Wilayah_05 | 10.08 | 8.20 | 70.43 | 85.62 |
| Wilayah_24 | 10.06 | 8.67 | 71.73 | 88.05 |
| Wilayah_01 | 9.99 | 7.12 | 70.11 | 76.88 |
| Wilayah_18 | 9.84 | 7.75 | 70.68 | 84.59 |
| Wilayah_20 | 9.66 | 6.79 | 70.86 | 93.39 |
| Wilayah_26 | 9.61 | 9.63 | 71.71 | 75.11 |
| Wilayah_16 | 9.53 | 9.09 | 70.26 | 87.40 |
| Wilayah_22 | 9.44 | 8.76 | 71.33 | 89.43 |
| Wilayah_13 | 8.99 | 7.88 | 70.08 | 82.50 |
| Wilayah_08 | 8.98 | 7.08 | 69.54 | 73.56 |
| Wilayah_04 | 8.57 | 7.38 | 69.88 | 85.61 |
| Wilayah_10 | 8.52 | 8.09 | 71.62 | 96.99 |
| Wilayah_14 | 8.19 | 10.03 | 72.54 | 95.23 |
| Wilayah_12 | 7.98 | 10.35 | 71.12 | 93.96 |
| Wilayah_02 | 7.68 | 7.01 | 73.42 | 91.38 |
| Wilayah_11 | 7.16 | 7.94 | 72.38 | 87.64 |
| Wilayah_03 | 6.01 | 9.96 | 71.13 | 86.70 |
ggplot2::ggplot(rank5, ggplot2::aes(reorder(wilayah, kemiskinan_persen), kemiskinan_persen)) +
ggplot2::geom_col() + ggplot2::coord_flip() +
ggplot2::labs(title="Ranking kemiskinan pada tahun terakhir", x=NULL, y="Kemiskinan (%)")Visualisasi harus membedakan “nilai tinggi” dan “masalah besar”. Kota kecil dengan TPT tinggi mungkin memiliki jumlah penganggur absolut lebih sedikit daripada kabupaten besar dengan TPT sedang. Dashboard yang baik memungkinkan pembaca melihat rate dan count secara berdampingan.
before-after untuk dua tahun pada data simulasi.Buat satu halaman policy evidence story berisi maksimal empat grafik. Setiap grafik harus memiliki: pertanyaan, caption substantif, sumber, unit/satuan, periode, dan satu kalimat caveat. Sertakan satu grafik yang sengaja buruk, kemudian revisi dan jelaskan mengapa versi kedua lebih tepat.
Fokus: transformasi log; indeks tahun dasar; slope; pilihan visual encoding; masalah dual-axis; choropleth classification; uncertainty; claim–evidence–context–decision implication.
Mahasiswa membuat storyboard 5 panel: masalah, disparitas, driver/pola, model/evidence, dan rekomendasi. Ini menjadi kerangka dashboard dan presentasi akhir.
Visualisasi kebijakan adalah alat penalaran dan komunikasi. Pilih bentuk grafik berdasarkan pertanyaan, bukan karena efek visualnya menarik.
Regresi menghubungkan outcome dengan satu atau lebih prediktor dan menyediakan kerangka untuk estimasi, ketidakpastian, dan prediksi. Pada data regional, regresi sangat berguna, tetapi interpretasi harus membedakan asosiasi dari efek kausal.
Mahasiswa mampu merumuskan model regresi, menginterpretasi koefisien dan interval kepercayaan, mengecek residual secara dasar, mengenali multikolinearitas, dan menjelaskan keterbatasan inferensi observasional.
Model linear berganda menaksir hubungan kondisional: perubahan ekspektasi outcome ketika satu prediktor berubah, dengan prediktor lain ditahan konstan. Asumsi penting meliputi spesifikasi mean yang memadai, independensi/struktur error yang sesuai, serta stabilitas hubungan. Data panel dan spasial sering melanggar independensi sederhana sehingga regresi OLS harus dilihat sebagai baseline, bukan akhir analisis.
dengan outcome, prediktor, koefisien, dan error. Estimator OLS dalam notasi matriks:
Interval kepercayaan koefisien secara umum:
Misalkan i.i.d. dengan mean dan varians . Rata-rata sampel memiliki Standard error diestimasi oleh Untuk populasi normal atau sampel yang memadai, CI mean dengan adalah Interpretasi frequentist: prosedur interval tersebut memiliki coverage pada repeated sampling; bukan probabilitas posterior bahwa berada di interval tertentu.
Untuk , -value adalah probabilitas memperoleh statistik uji setidaknya se-ekstrem yang teramati jika dan asumsi model benar. -value bukan ukuran besar efek, bukan probabilitas benar, dan bukan pengganti relevansi kebijakan.
Model: Dalam bentuk matriks: OLS memilih yang, jika invertibel, memiliki solusi Residual: Estimator varians error: Varian koefisien di bawah homoskedastisitas:
Adjusted : tinggi tidak menjamin model memiliki error prediksi kecil pada data baru atau memiliki interpretasi kausal yang valid. (Harrell 2015)
Untuk prediktor , regresikan terhadap prediktor lain dan peroleh . Variance Inflation Factor: VIF menunjukkan inflasi varians koefisien akibat hubungan linear antarfitur; threshold seperti 5 atau 10 hanyalah rule-of-thumb, bukan hukum universal.
Model interaksi: Efek marginal adalah Artinya efek bergantung pada . Dalam konteks regional, dampak asosiasional digital connectivity terhadap outcome dapat berbeda menurut tingkat urbanisasi atau kapasitas fiskal.
Koefisien OLS bersifat kausal hanya di bawah asumsi identifikasi yang kuat. Jika variabel tak teramati memengaruhi dan , maka asosiasi dapat mengalami confounding. Buku kausal modern menekankan pemisahan pertanyaan prediktif dan kausal. (Hernán dan Robins 2020) Dalam mata kuliah ini, regresi terutama digunakan untuk deskripsi kondisional dan prediksi, kecuali desain identifikasi dijelaskan eksplisit.
Koefisien internet -0,05 pada model kemiskinan berarti bahwa, dalam model dan skala yang digunakan, peningkatan 1 poin persentase internet diasosiasikan dengan penurunan rata-rata 0,05 poin kemiskinan ketika variabel lain tetap. Ini bukan bukti efek kausal jika faktor confounding tidak ditangani.
Model hipotetis: Jika internet diukur persen, koefisien berarti pada data/model tersebut, kenaikan 1 percentage point internet berasosiasi dengan penurunan rata-rata 0,08 percentage point poverty, conditional on PDRBpc dan TPT. Kenaikan 10 points berasosiasi dengan 0,8 points lebih rendah. Kata “menyebabkan” tidak dibenarkan tanpa desain kausal.
Untuk model tanpa intercept yang sangat sederhana dengan Maka Prediksi . Contoh ini membantu melihat bahwa formula matriks adalah generalisasi prosedur minimisasi squared residual.
Untuk mean response pada : Untuk observasi baru: Prediction interval lebih lebar karena mencakup irreducible individual error selain uncertainty mean. Ini penting saat memberi range outcome satu wilayah, bukan hanya expected mean.
Empat pertanyaan minimum:
Pada panel regional, asumsi independence sering paling rapuh. Jika observasi wilayah berulang, standard error OLS biasa dapat tidak memadai. Mata kuliah ini mengenalkan diagnosis; model panel/spatial formal dapat menjadi studi lanjut.
d <- panel |> filter(tahun==2025)
fit6 <- lm(kemiskinan_persen ~ internet_persen + pdrb_perkapita_juta + tpt_persen,
data=d)
broom::tidy(fit6, conf.int=TRUE) |> knitr::kable(digits=3)| term | estimate | std.error | statistic | p.value | conf.low | conf.high |
|---|---|---|---|---|---|---|
| (Intercept) | 17.477 | 3.581 | 4.880 | 0.000 | 10.068 | 24.886 |
| internet_persen | -0.020 | 0.064 | -0.309 | 0.760 | -0.152 | 0.113 |
| pdrb_perkapita_juta | -0.086 | 0.047 | -1.834 | 0.080 | -0.184 | 0.011 |
| tpt_persen | -0.209 | 0.271 | -0.771 | 0.449 | -0.771 | 0.352 |
| r.squared | adj.r.squared | sigma | AIC |
|---|---|---|---|
| 0.464 | 0.394 | 1.365 | 99.102 |
Gunakan broom::augment() untuk residual/fitted. Setelah output, tulis effect scale, uncertainty, dan limitation. Koefisien kecil belum tentu tidak substantif bila satu unit perubahan variabel sangat besar; sebaliknya koefisien “signifikan” dapat tidak relevan secara kebijakan.
panel <- read_csv("data/simulasi_panel_regional.csv", show_col_types = FALSE) |>
filter(tahun == 2025)
m1 <- lm(kemiskinan_persen ~ pdrb_perkapita_juta + internet_persen + ipm + tpt_persen,
data = panel)
broom::tidy(m1, conf.int = TRUE) |>
knitr::kable(digits = 3, caption = "Regresi kemiskinan pada data simulasi")| term | estimate | std.error | statistic | p.value | conf.low | conf.high |
|---|---|---|---|---|---|---|
| (Intercept) | 7.522 | 23.830 | 0.316 | 0.755 | -41.897 | 56.941 |
| pdrb_perkapita_juta | -0.102 | 0.060 | -1.697 | 0.104 | -0.226 | 0.023 |
| internet_persen | -0.012 | 0.068 | -0.180 | 0.859 | -0.152 | 0.128 |
| ipm | 0.145 | 0.343 | 0.423 | 0.677 | -0.567 | 0.857 |
| tpt_persen | -0.233 | 0.282 | -0.826 | 0.417 | -0.818 | 0.352 |
augment(m1) |>
ggplot(aes(.fitted, .resid)) +
geom_hline(yintercept = 0, linetype = 2) +
geom_point() +
labs(x = "Fitted", y = "Residual", title = "Pemeriksaan residual dasar")INDO-DAPOER memiliki poverty rate (SI.POV.NAPR.ZS), HDI (IDX.HDI), literacy (SE.LITR.15UP.ZS), populasi (SP.POP.TOTL), unemployment counts (SL.UEM.TOTL) dan labor force (SL.TLF). TPT dapat dikonstruksi dari SL.UEM.TOTL/SL.TLF*100 jika definisi dan periode kompatibel. (World Bank 2026)
Kartu dataset real.
unemployed/labor_force*100 bila definisinya kompatibel.if (dir.exists("data/raw/indodapoer") && length(list.files("data/raw/indodapoer")) > 0) {
source("R/03_prepare_indodapoer.R")
indo <- load_indodapoer()
sel <- indo |>
dplyr::filter(kode_indikator %in% c("SI.POV.NAPR.ZS", "IDX.HDI", "SE.LITR.15UP.ZS", "SL.UEM.TOTL", "SL.TLF"), tahun == 2018) |>
dplyr::select(wilayah, kode_indikator, nilai) |>
tidyr::pivot_wider(names_from = kode_indikator, values_from = nilai) |>
dplyr::mutate(tpt_constructed = 100 * SL.UEM.TOTL / SL.TLF)
fit_real <- lm(SI.POV.NAPR.ZS ~ IDX.HDI + SE.LITR.15UP.ZS + tpt_constructed, data = sel)
} else {
sel <- readr::read_csv("data/simulasi_panel_regional.csv", show_col_types = FALSE) |> dplyr::filter(tahun == 2025)
fit_real <- lm(kemiskinan_persen ~ ipm + indeks_pendidikan + tpt_persen, data = sel)
}
broom::tidy(fit_real, conf.int = TRUE) |> knitr::kable(digits = 3, caption = "Output: estimasi model dan interval kepercayaan")| term | estimate | std.error | statistic | p.value | conf.low | conf.high |
|---|---|---|---|---|---|---|
| (Intercept) | 17.875 | 22.593 | 0.791 | 0.437 | -28.863 | 64.612 |
| ipm | 0.146 | 0.392 | 0.372 | 0.714 | -0.665 | 0.957 |
| indeks_pendidikan | -0.187 | 0.084 | -2.212 | 0.037 | -0.361 | -0.012 |
| tpt_persen | -0.640 | 0.299 | -2.138 | 0.043 | -1.259 | -0.021 |
reg6 <- readr::read_csv("data/simulasi_panel_regional.csv", show_col_types = FALSE) |>
dplyr::filter(tahun == 2025)
fit6 <- stats::lm(kemiskinan_persen ~ pdrb_perkapita_juta + tpt_persen + internet_persen + ipm + urban, data=reg6)
coef6 <- broom::tidy(fit6, conf.int=TRUE)
knitr::kable(coef6, digits=3, caption="Koefisien OLS, standard error, p-value, dan 95% CI")| term | estimate | std.error | statistic | p.value | conf.low | conf.high |
|---|---|---|---|---|---|---|
| (Intercept) | 2.866 | 24.361 | 0.118 | 0.907 | -47.796 | 53.528 |
| pdrb_perkapita_juta | -0.125 | 0.065 | -1.929 | 0.067 | -0.259 | 0.010 |
| tpt_persen | -0.434 | 0.352 | -1.234 | 0.231 | -1.165 | 0.297 |
| internet_persen | -0.017 | 0.068 | -0.254 | 0.802 | -0.158 | 0.124 |
| ipm | 0.248 | 0.360 | 0.689 | 0.498 | -0.501 | 0.997 |
| urban | 0.888 | 0.926 | 0.959 | 0.348 | -1.038 | 2.815 |
glance6 <- broom::glance(fit6) |> dplyr::select(r.squared, adj.r.squared, sigma, statistic, p.value, AIC, BIC, df.residual)
knitr::kable(glance6, digits=3, caption="Ringkasan goodness-of-fit model regresi")| r.squared | adj.r.squared | sigma | statistic | p.value | AIC | BIC | df.residual |
|---|---|---|---|---|---|---|---|
| 0.49 | 0.369 | 1.393 | 4.043 | 0.01 | 101.726 | 110.797 | 21 |
aug6 <- broom::augment(fit6)
metric6 <- tibble::tibble(
RMSE = rmse_manual(reg6$kemiskinan_persen, aug6$.fitted),
MAE = mae_manual(reg6$kemiskinan_persen, aug6$.fitted),
mean_residual = mean(aug6$.resid),
max_cooks_d = max(aug6$.cooksd)
)
knitr::kable(metric6, digits=3, caption="Ukuran error dan influence pada data estimasi")| RMSE | MAE | mean_residual | max_cooks_d |
|---|---|---|---|
| 1.228 | 0.942 | 0 | 0.256 |
ggplot2::ggplot(aug6, ggplot2::aes(.fitted, .resid)) +
ggplot2::geom_hline(yintercept=0, linetype=2) + ggplot2::geom_point(alpha=.8) +
ggplot2::geom_smooth(se=FALSE) + ggplot2::labs(title="Residual versus fitted", x="Fitted", y="Residual")ggplot2::ggplot(aug6, ggplot2::aes(sample=.std.resid)) +
ggplot2::stat_qq() + ggplot2::stat_qq_line() +
ggplot2::labs(title="Normal Q–Q plot standardized residual")ggplot2::ggplot(aug6, ggplot2::aes(kemiskinan_persen, .fitted)) +
ggplot2::geom_abline(slope=1,intercept=0,linetype=2) + ggplot2::geom_point(size=2.5) +
ggplot2::labs(title="Aktual versus fitted OLS", x="Aktual (%)", y="Fitted (%)")Koefisien harus dibaca bersama skala, interval ketidakpastian, dan plausibilitas substantif. Jika model menunjukkan HDI dan literacy sama-sama kuat tetapi sangat berkorelasi, koefisien individual dapat menjadi tidak stabil. Untuk kebijakan, fokus pada evidence pattern dan ketidakpastian, bukan pada signifikansi p-value saja.
Bangun baseline regression untuk outcome regional. Laporkan model equation, coefficient table, CI, residual diagnostics, VIF, satu interaction term yang punya justifikasi, dan interpretasi substantif. Tuliskan satu paragraf berjudul “Apa yang tidak dapat saya simpulkan secara kausal dari model ini.”
Kelompok menyusun baseline statistical model dan mendokumentasikan asumsi. Baseline dibutuhkan agar model ML yang lebih kompleks memiliki pembanding yang bermakna.
Regresi adalah alat dasar yang sangat kuat untuk regional analytics jika digunakan dengan disiplin interpretasi, diagnostik, dan kesadaran terhadap confounding serta struktur data.
Prediksi menilai kemampuan model untuk bekerja pada data yang tidak digunakan saat fitting. Kesalahan umum dalam proyek regional adalah mengevaluasi model pada data training atau melakukan preprocessing menggunakan seluruh data sebelum split, sehingga kinerja terlihat terlalu baik.
Mahasiswa mampu membangun workflow train/test, cross-validation, baseline, feature preprocessing, serta mendeteksi leakage temporal dan geografis.
Generalization error adalah error pada observasi baru. Data leakage terjadi ketika informasi yang seharusnya tidak tersedia saat prediksi masuk ke proses training. Untuk forecast atau panel waktu, random split dapat membocorkan informasi masa depan. Untuk wilayah, random split juga dapat terlalu optimistis bila wilayah tetangga sangat serupa.
MSE dan RMSE:
MAE:
Dalam -fold cross-validation,
dengan loss pada fold ke-.
Tujuan prediksi bukan meminimalkan training error, tetapi error pada data baru: Test error adalah estimator praktis dari kuantitas ini ketika test set benar-benar independen dari proses training/tuning.
Data training dibagi menjadi fold . Model dilatih tanpa fold . Estimator CV risk: Untuk panel regional, random CV dapat terlalu optimistis bila observasi wilayah yang sama muncul di train dan validation. Gunakan grouped CV, spatial blocking, atau rolling/temporal split sesuai target deployment. (Kuhn dan Silge 2022)
MAPE bermasalah saat dekat nol. Untuk indikator seperti growth yang dapat nol/negatif, MAE/RMSE atau scaled errors biasanya lebih aman.
Untuk squared error pada titik , Model sangat fleksibel dapat menurunkan bias tetapi meningkatkan variance. Resampling membantu memilih kompleksitas yang memberi trade-off generalization terbaik. (Hastie, Tibshirani, dan Friedman 2009)
Ridge: Lasso: Ridge mengecilkan koefisien; lasso dapat menghasilkan beberapa koefisien tepat nol. Prediktor sebaiknya distandardisasi sebelum regularisasi. (Hoerl dan Kennard 1970; Tibshirani 1996)
Misalkan transformasi preprocessing memiliki parameter . Leakage terjadi jika ketika seharusnya Contoh: standardisasi, imputasi, feature selection, PCA, atau tuning threshold menggunakan test set. Test set baru “dibuka” setelah seluruh keputusan model selesai.
RMSE lebih memberi penalti pada error besar. Jika kebijakan sangat sensitif terhadap kegagalan memprediksi wilayah ekstrem, RMSE bisa lebih relevan daripada MAE. Tetapi metric harus terkait keputusan, bukan dipilih hanya karena umum digunakan.
Tujuan: memprediksi indikator 2025 menggunakan informasi hingga 2024. Maka split random yang memasukkan observasi 2025 ke training melanggar deployment. Gunakan Validation dipakai tuning; test hanya evaluasi final.
Error model A: . MAE=, RMSE=. Error ekstrem mendapat penalti lebih kuat pada RMSE. Jika kebijakan sangat sensitif terhadap miss besar, RMSE mungkin lebih sesuai; jika robust typical absolute error lebih penting, MAE informatif.
Untuk 5-fold CV, setiap observasi menjadi validation tepat sekali. Jika fold RMSE = 2.1, 2.4, 1.9, 2.6, 2.2: Laporkan distribusi, bukan hanya mean. Variability tinggi berarti model sensitif terhadap sample composition.
Jika dua prediktor sangat berkorelasi, OLS dapat menghasilkan koefisien besar dengan tanda tidak stabil. Ridge menambah , sehingga solusi menerima sedikit bias untuk mengurangi variance. lambda bukan dipilih dari test set; gunakan resampling training.
set.seed(260817)
dat <- readr::read_csv("data/simulasi_panel_regional.csv", show_col_types = FALSE) |>
dplyr::select(kemiskinan_persen, pdrb_perkapita_juta, tpt_persen, internet_persen, ipm, umkm_per_1000)
spl <- initial_split(dat, prop = .8)
tr <- training(spl)
folds <- vfold_cv(tr, v = 5)
rec <- recipe(kemiskinan_persen ~ ., data = tr) |> step_normalize(all_numeric_predictors())
mod <- linear_reg() |> set_engine("lm")
wf <- workflow() |> add_recipe(rec) |> add_model(mod)
res <- fit_resamples(wf, resamples = folds, metrics = metric_set(rmse, mae, rsq))
collect_metrics(res) |> knitr::kable(digits = 3, caption = "Output: 5-fold cross-validation baseline")| .metric | .estimator | mean | n | std_err | .config |
|---|---|---|---|---|---|
| mae | standard | 1.024 | 5 | 0.030 | pre0_mod0_post0 |
| rmse | standard | 1.313 | 5 | 0.050 | pre0_mod0_post0 |
| rsq | standard | 0.711 | 5 | 0.027 | pre0_mod0_post0 |
| Komponen | Fit hanya pada train/resample? | Risiko jika tidak |
|---|---|---|
| median imputation | ya | test distribution bocor |
| normalization | ya | mean/SD test bocor |
| feature selection | ya | selection optimism |
| PCA | ya | loading memakai test |
| hyperparameter tuning | ya | overfit test |
| threshold selection | validation | inflated test metric |
Pertanyaan validasi bukan “split mana yang paling mudah”, tetapi “data apa yang akan tersedia saat model benar-benar dipakai?”. Untuk prediksi wilayah baru, group split by region mungkin tepat. Untuk masa depan, temporal split. Untuk generalisasi geografis, spatial block. (Kuhn dan Silge 2022)
panel <- read_csv("data/simulasi_panel_regional.csv", show_col_types = FALSE)
train <- panel |> filter(tahun <= 2023)
test <- panel |> filter(tahun >= 2024)
fit <- lm(kemiskinan_persen ~ pdrb_perkapita_juta + tpt_persen + internet_persen + ipm,
data = train)
pred <- test |> mutate(.pred = predict(fit, newdata = test))
pred |>
summarise(RMSE = rmse_manual(kemiskinan_persen, .pred),
MAE = mae_manual(kemiskinan_persen, .pred)) |>
knitr::kable(digits = 3)| RMSE | MAE |
|---|---|
| 1.413 | 1.096 |
pred |>
ggplot2::ggplot(ggplot2::aes(kemiskinan_persen, .pred)) +
ggplot2::geom_abline(slope = 1, intercept = 0, linetype = 2, colour = "#C99A17") +
ggplot2::geom_point(alpha = .7, colour = "#145B8C") +
ggplot2::labs(
title = "Evaluasi out-of-time: aktual versus prediksi",
x = "Kemiskinan aktual (%)", y = "Kemiskinan prediksi (%)"
)Data panel INDO-DAPOER dapat dibagi berdasarkan waktu, misalnya training sampai 2015 dan test 2016-2018, selama indikator memiliki kelengkapan memadai. Karena data historis, tujuan latihan adalah mengevaluasi pipeline, bukan memberi rekomendasi kebijakan terkini.
Kartu dataset real.
library(tidymodels)
set.seed(260807)
reg <- read_csv("data/simulasi_panel_regional.csv", show_col_types = FALSE) |> filter(tahun == 2025)
split <- initial_split(reg, prop = .8, strata = kemiskinan_persen)
tr <- training(split); te <- testing(split)
rec <- recipe(kemiskinan_persen ~ pdrb_perkapita_juta + tpt_persen + internet_persen + ipm + umkm_per_1000,
data = tr) |>
step_normalize(all_numeric_predictors())
mod <- linear_reg() |> set_engine("lm")
wf <- workflow() |> add_recipe(rec) |> add_model(mod) |> fit(tr)
p <- predict(wf, te) |> bind_cols(te |> select(kemiskinan_persen))
yardstick::metrics(p, truth = kemiskinan_persen, estimate = .pred)#> # A tibble: 3 × 3
#> .metric .estimator .estimate
#> <chr> <chr> <dbl>
#> 1 rmse standard 1.66
#> 2 rsq standard 0.369
#> 3 mae standard 1.42
set.seed(260817)
dat7 <- readr::read_csv("data/simulasi_panel_regional.csv", show_col_types = FALSE) |>
dplyr::select(kemiskinan_persen, pdrb_perkapita_juta, tpt_persen, internet_persen, ipm, umkm_per_1000)
split7 <- rsample::initial_split(dat7, prop=.8)
tr7 <- rsample::training(split7); te7 <- rsample::testing(split7)
folds7 <- rsample::vfold_cv(tr7, v=5)
wf7 <- workflows::workflow() |>
workflows::add_recipe(recipes::recipe(kemiskinan_persen ~ ., data=tr7) |> recipes::step_normalize(recipes::all_numeric_predictors())) |>
workflows::add_model(parsnip::linear_reg() |> parsnip::set_engine("lm"))
res7 <- tune::fit_resamples(wf7, resamples=folds7, metrics=yardstick::metric_set(yardstick::rmse, yardstick::mae, yardstick::rsq))
fold_metric7 <- tune::collect_metrics(res7, summarize=FALSE)
knitr::kable(fold_metric7, digits=3, caption="Metric setiap fold — bukan hanya rata-rata")| id | .metric | .estimator | .estimate | .config |
|---|---|---|---|---|
| Fold1 | rmse | standard | 1.123 | pre0_mod0_post0 |
| Fold1 | mae | standard | 0.926 | pre0_mod0_post0 |
| Fold1 | rsq | standard | 0.802 | pre0_mod0_post0 |
| Fold2 | rmse | standard | 1.346 | pre0_mod0_post0 |
| Fold2 | mae | standard | 1.086 | pre0_mod0_post0 |
| Fold2 | rsq | standard | 0.647 | pre0_mod0_post0 |
| Fold3 | rmse | standard | 1.328 | pre0_mod0_post0 |
| Fold3 | mae | standard | 1.084 | pre0_mod0_post0 |
| Fold3 | rsq | standard | 0.667 | pre0_mod0_post0 |
| Fold4 | rmse | standard | 1.356 | pre0_mod0_post0 |
| Fold4 | mae | standard | 1.016 | pre0_mod0_post0 |
| Fold4 | rsq | standard | 0.724 | pre0_mod0_post0 |
| Fold5 | rmse | standard | 1.414 | pre0_mod0_post0 |
| Fold5 | mae | standard | 1.007 | pre0_mod0_post0 |
| Fold5 | rsq | standard | 0.714 | pre0_mod0_post0 |
ggplot2::ggplot(fold_metric7 |> dplyr::filter(.metric %in% c("rmse","mae")), ggplot2::aes(.metric,.estimate)) +
ggplot2::geom_boxplot(width=.45) + ggplot2::geom_jitter(width=.08, size=2) +
ggplot2::labs(title="Variabilitas metric antar-fold", x=NULL, y="Nilai metric")fit7 <- generics::fit(wf7, data = tr7)
pred7 <- predict(fit7, te7) |> dplyr::bind_cols(te7 |> dplyr::select(kemiskinan_persen))
yardstick::metrics(pred7, truth=kemiskinan_persen, estimate=.pred) |>
knitr::kable(digits=3, caption="Final test metrics setelah resampling selesai")| .metric | .estimator | .estimate |
|---|---|---|
| rmse | standard | 1.096 |
| rsq | standard | 0.719 |
| mae | standard | 0.870 |
Model dengan RMSE 1,2 poin kemiskinan berarti error tipikal berada pada skala sekitar satu poin persentase, tetapi implikasinya berbeda bagi wilayah 3% dan 20%. Evaluasi perlu melihat error menurut kelompok: urban/rural, wilayah miskin/nonmiskin, dan wilayah dengan data terbatas.
Bandingkan minimal dua model pada split yang sesuai dengan deployment (random/group/time). Laporkan baseline, CV metric distribution, final test metric, dan tabel leakage audit. Setiap transformasi harus dikerjakan hanya pada training/resample yang relevan.
Kisi-kisi: summary/inequality; visualisasi; OLS; CI; interaction; RMSE/MAE; cross-validation; bias–variance; ridge/lasso; leakage; baseline comparison.
Kelompok harus menetapkan evaluation protocol sebelum mencoba banyak model: unit split, metric utama, metric sekunder, baseline, dan subgroup check.
Evaluasi yang jujur lebih penting daripada skor spektakuler. Leakage dapat membuat model tampak hebat namun gagal saat digunakan untuk keputusan nyata.
UTS menguji integrasi kompetensi minggu 1-7. Fokusnya bukan menghafal sintaks, melainkan membuat keputusan analitik yang dapat dipertanggungjawabkan.
Mahasiswa mampu mengaudit dataset, merumuskan pertanyaan, melakukan EDA, membangun baseline model, mengevaluasi, dan menulis interpretasi kebijakan singkat secara individual.
UTS menggunakan open-book analytical case. Mahasiswa dapat melihat dokumentasi R, tetapi harus menjelaskan alasan pilihan metode dan interpretasi. Data dapat berupa potongan indikator kabupaten/kota dengan masalah kualitas yang sengaja disisipkan.
Formula yang diujikan berasal dari bab 1-7: rate, standardisasi, mean/variance, korelasi, regresi, RMSE, dan MAE. Mahasiswa tidak dinilai karena menghafal formula, tetapi karena memilih formula yang sesuai dan menjelaskan simbol serta unitnya.
UTS mengintegrasikan materi minggu 1–7. Mahasiswa harus dapat menjelaskan kapan setiap rumus relevan dan asumsi apa yang menyertainya.
Rate dan growth
Z-score
Correlation
OLS
RMSE/MAE
CV risk
UTS bukan ujian “mengetik kode tercepat”. Sebuah jawaban lengkap memiliki empat lapis:
| Area | Proporsi skor UTS | Kemampuan yang diuji |
|---|---|---|
| Problem framing & metadata | 15% | unit analisis, outcome, provenance, keterbatasan |
| Data quality & wrangling | 20% | missing, duplicate, join, feature construction |
| EDA & visualization | 20% | memilih ringkasan/grafik dan membaca disparitas |
| Inferensi/regresi | 20% | formulasi, asumsi, interpretasi koefisien/CI |
| Prediction & validation | 15% | split/CV, RMSE/MAE, leakage |
| Policy interpretation | 10% | insight, caveat, recommendation |
.Rmd/.qmd atau notebook + PDF/HTML hasil render.Setiap bagian dinilai: ketepatan (40%) + alasan metodologis (25%) + interpretasi regional (25%) + reproducibility/komunikasi (10%). Kesalahan yang menghasilkan klaim kebijakan tidak valid dapat menurunkan skor lebih besar daripada kesalahan sintaks kecil yang mudah diperbaiki.
UTS mensimulasikan situasi analis: data belum sempurna, waktu terbatas, dan stakeholder membutuhkan ringkasan yang akurat. Jawaban terbaik bukan yang memakai model paling kompleks, tetapi yang menjaga validitas dari awal sampai interpretasi.
Kasus: dataset 27 kabupaten/kota × 2016–2024 berisi TPT, kemiskinan, pertumbuhan PDRB, internet, dan pendidikan. Ada duplikasi 6 key, missing internet 2020 untuk 4 wilayah, dan satu nilai TPT=82 akibat salah decimal.
Langkah 1 — audit. Jangan langsung drop_na(). Identifikasi duplicate key dan nilai impossible. Verifikasi dari source sebelum koreksi.
Langkah 2 — feature. Untuk memprediksi TPT 2024, fitur yang berasal dari outcome 2024 tidak boleh digunakan. Gunakan lag 2023 atau indikator yang tersedia sebelum keputusan.
Langkah 3 — EDA. Minimal satu grafik trend, satu cross-sectional relationship, satu regional ranking/map. Setiap grafik punya source/unit.
Langkah 4 — baseline. Fit model linear pada ≤2022, validasi 2023, test 2024. Interpretasikan conditional associations.
Langkah 5 — metric. Jika RMSE 1.4 percentage points, terjemahkan: “typical squared-error scale sekitar 1.4 poin TPT”, bukan “akurasi 98.6%”.
Langkah 6 — policy memo. Pisahkan observation, hypothesis, dan recommendation.
Jawaban dengan kode sempurna tetapi menggunakan data 2024 untuk feature yang memprediksi 2024 dapat kehilangan skor besar karena target leakage. Sebaliknya syntax kecil yang tidak memengaruhi kesimpulan dapat mendapat penalti lebih ringan. Ini menegaskan prioritas validitas dibanding kosmetika.
Mahasiswa seharusnya mampu menghitung dan menjelaskan makna tiap hasil.
File harus dapat di-knit dari awal. Gunakan path relatif; jangan menggunakan setwd("/Users/nama/Desktop"); jangan menyunting angka output secara manual; dan catat package yang dipakai. Bila data ujian disediakan lokal, gunakan here atau struktur folder sederhana.
set.seed(260808)
uts_case <- read_csv("data/simulasi_panel_regional.csv", show_col_types = FALSE) |>
filter(tahun %in% c(2023, 2024, 2025)) |>
sample_n(60) |>
mutate(internet_persen = if_else(row_number() %% 13 == 0, NA_real_, internet_persen))
knitr::kable(head(uts_case, 8), digits = 2, caption = "Contoh struktur data case UTS")| wilayah | tahun | urban | longitude | latitude | pdrb_perkapita_juta | kemiskinan_persen | tpt_persen | ipm | internet_persen | umkm_per_1000 | indeks_pendidikan | akses_kesehatan | indeks_inovasi |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Wilayah_23 | 2025 | 0 | 106.92 | -6.89 | 41.20 | 13.05 | 7.05 | 69.78 | 72.33 | 35.41 | 65.93 | 70.35 | 70.57 |
| Wilayah_27 | 2023 | 1 | 107.67 | -6.04 | 42.78 | 12.10 | 8.44 | 67.63 | 77.99 | 31.82 | 65.90 | 59.45 | 66.14 |
| Wilayah_08 | 2023 | 0 | 106.96 | -6.76 | 32.64 | 12.09 | 6.92 | 68.94 | 64.86 | 30.16 | 70.45 | 60.78 | 59.17 |
| Wilayah_18 | 2025 | 1 | 107.84 | -7.68 | 53.71 | 9.84 | 7.75 | 70.68 | 84.59 | 40.48 | 64.91 | 63.78 | 67.93 |
| Wilayah_24 | 2024 | 1 | 108.35 | -6.50 | 52.89 | 11.27 | 7.99 | 68.66 | 82.10 | 38.27 | 62.40 | 60.52 | 63.88 |
| Wilayah_16 | 2023 | 1 | 107.54 | -7.54 | 46.36 | 9.45 | 9.43 | 65.87 | 77.38 | 32.02 | 59.58 | 55.15 | 64.34 |
| Wilayah_21 | 2025 | 0 | 107.06 | -6.75 | 24.04 | 11.24 | 6.74 | 67.78 | 65.66 | 31.20 | 60.43 | 64.54 | 60.84 |
| Wilayah_10 | 2025 | 1 | 107.47 | -7.51 | 66.15 | 8.52 | 8.09 | 71.62 | 96.99 | 46.95 | 77.19 | 76.32 | 70.22 |
uts_case |>
dplyr::summarise(dplyr::across(dplyr::everything(), ~mean(is.na(.x)))) |>
tidyr::pivot_longer(dplyr::everything(), names_to = "variabel", values_to = "prop_missing") |>
dplyr::filter(prop_missing > 0) |>
ggplot2::ggplot(ggplot2::aes(reorder(variabel, prop_missing), prop_missing)) +
ggplot2::geom_col(fill = "#C99A17") +
ggplot2::coord_flip() +
ggplot2::scale_y_continuous(labels = scales::percent) +
ggplot2::labs(title = "Proporsi missing pada data kasus UTS", x = NULL, y = "Proporsi missing")Dosen dapat mengganti case dengan subset Open Data Jabar yang diunduh sebelum ujian. Dataset dan metadata diberikan bersama agar ujian mengukur analisis, bukan kemampuan mencari URL.
Kartu dataset real untuk UTS.
Template minimum jawaban:
dat <- uts_case |> tidyr::drop_na()
fit <- lm(kemiskinan_persen ~ internet_persen + pdrb_perkapita_juta + tpt_persen, data = dat)
broom::glance(fit) |>
dplyr::select(r.squared, adj.r.squared, sigma, AIC) |>
knitr::kable(digits = 3, caption = "Output contoh UTS: ringkasan baseline regression")| r.squared | adj.r.squared | sigma | AIC |
|---|---|---|---|
| 0.573 | 0.549 | 1.246 | 189.426 |
Nilai tinggi diberikan untuk interpretasi yang mengenali trade-off dan ketidakpastian. Mahasiswa harus menghindari kalimat kausal jika desain data hanya observasional.
Kerjakan satu mock case 90 menit: data kabupaten–tahun dengan dua masalah kualitas, satu missing mechanism yang perlu didiskusikan, satu visualisasi yang salah, dan satu baseline regression. Jawaban harus memuat kode serta policy interpretation.
Mahasiswa harus dapat menjelaskan tanpa membuka catatan: unit analisis; denominator; z-score; correlation; OLS objective; arti CI; RMSE vs MAE; K-fold CV; data leakage; dan mengapa prediksi tidak identik dengan kausalitas.
UTS menjadi quality gate: kelemahan individu yang muncul pada UTS harus diperbaiki sebelum tim masuk ke model ML capstone.
UTS menilai integrasi, bukan potongan teknik. Kemampuan mendokumentasikan keputusan analitik sama pentingnya dengan mendapatkan output model.
Machine learning berguna ketika hubungan antarvariabel kompleks, interaksi banyak, atau tujuan utama adalah prediksi. Namun model harus dibandingkan dengan baseline yang sederhana dan dipilih berdasarkan generalisasi, interpretabilitas, biaya kesalahan, serta konteks implementasi. (James dkk. 2021; Kuhn dan Silge 2022)
Mahasiswa mampu menjelaskan bias-variance trade-off, membangun workflow ML dengan resampling, menggunakan tree-based model, dan membandingkan kinerja dengan regresi baseline.
Bias adalah error sistematis dari model yang terlalu sederhana; variance adalah sensitivitas model terhadap perubahan sampel. Random forest menggabungkan banyak pohon dengan bootstrap dan random feature selection sehingga variance berkurang. (Breiman 2001)
Dekomposisi error prediksi secara konseptual:
Untuk random forest regresi, prediksi adalah rata-rata pohon:
dengan jumlah pohon.
Pada node , prediksi konstan terbaik untuk squared error adalah mean
Split dipilih untuk meminimalkan
Tree yang terlalu dalam cenderung overfit; hyperparameter seperti min_n, depth, atau cost complexity mengendalikan kompleksitas. (James dkk. 2021)
Jika node memiliki proporsi kelas , Entropy: Split dicari untuk menurunkan impurity tertimbang.
Untuk bootstrap sample , fit tree . Prediksi regresi bagging: Random forest menambahkan random subset fitur pada setiap split untuk mengurangi korelasi antar-tree; prinsip ini dapat menurunkan variance ensemble. (Breiman 2001)
Untuk klasifikasi, probabilitas dapat diperkirakan dari rata-rata probabilitas tree atau proporsi votes:
Boosting membangun model aditif dengan weak learner , step size , dan learning rate . Pada setiap iterasi, learner baru diarahkan untuk mengurangi loss melalui negative gradient. (Friedman 2001)
XGBoost menambahkan regularization pada objective: dengan penalti kompleksitas tree . (Chen dan Guestrin 2016)
Permutation importance untuk fitur dapat diringkas sebagai kenaikan error setelah nilai fitur tersebut diacak: Jika dua prediktor sangat berkorelasi, importance dapat tersebar/tidak stabil. Importance menunjukkan kontribusi prediktif dalam model dan distribusi data tertentu, bukan efek intervensi. Untuk kebijakan, gunakan sebagai alat diagnosis model, bukan klaim kausal.
Model kompleks harus dibandingkan dengan baseline . Perbaikan relatif error: Jika perbaikan sangat kecil tetapi kompleksitas, biaya komputasi, dan kesulitan interpretasi meningkat tajam, baseline dapat lebih layak untuk sistem kebijakan.
Satu pohon mudah dijelaskan tetapi tidak stabil. Random forest membuat banyak pohon yang berbeda dan merata-ratakan keputusan. Kinerja dapat meningkat, tetapi interpretasi kebijakan menjadi lebih tidak langsung; gunakan variable importance atau partial dependence secara hati-hati, bukan sebagai bukti kausal.
Node memiliki outcome dan satu fitur yang memungkinkan split setelah observasi ke-3. Mean kiri =4, mean kanan =11.667. SSE split: Total 6.667. Tree membandingkan candidate split lain dan memilih penurunan impurity terbesar.
Node memiliki 8 prioritas dan 2 non-prioritas: Node pure 10/0 memiliki Gini=0. Split yang menghasilkan child lebih pure menurunkan weighted impurity.
Jika estimator individual memiliki variance dan pairwise correlation , variance rata-rata kira-kira Menambah mengurangi komponen kedua, tetapi tidak menghilangkan komponen korelasi. Random feature selection pada random forest bertujuan menurunkan correlation antartree. (Breiman 2001)
Learning rate kecil memerlukan lebih banyak trees tetapi sering memberi regularization lebih baik. Ada trade-off antara trees, tree_depth, dan learn_rate. Tuning harus dilakukan pada resamples training; jangan memilih parameter karena satu test metric terlihat paling baik.
Untuk model project, buat tabel:
| Elemen | Isi |
|---|---|
| Intended use | screening wilayah untuk review |
| Not intended | menentukan penerima individu |
| Training period | contoh 2015–2022 |
| Target | TPT 2023 atau prioritas biner |
| Metrics | RMSE/MAE atau PR-AUC/calibration |
| Key limitations | historical coverage, spatial dependence |
| Fairness slices | urban/rural atau kawasan bila justified |
Dokumentasi model semacam ini sejalan dengan gagasan model cards. (Mitchell dkk. 2019)
models <- tibble::tribble(
~model, ~kompleksitas, ~kekuatan, ~risiko,
"Linear regression", "Rendah", "Interpretabel; baseline kuat", "Nonlinearitas tidak tertangkap",
"Decision tree", "Sedang", "Aturan keputusan mudah dijelaskan", "Tidak stabil; mudah overfit",
"Random forest", "Tinggi", "Menangkap nonlinearitas/interaksi", "Interpretasi lebih sulit"
)
knitr::kable(models, caption = "Output: model comparison matrix sebelum tuning")| model | kompleksitas | kekuatan | risiko |
|---|---|---|---|
| Linear regression | Rendah | Interpretabel; baseline kuat | Nonlinearitas tidak tertangkap |
| Decision tree | Sedang | Aturan keputusan mudah dijelaskan | Tidak stabil; mudah overfit |
| Random forest | Tinggi | Menangkap nonlinearitas/interaksi | Interpretasi lebih sulit |
Gunakan tiga lapis: (1) global performance, (2) global structure/importance, (3) local prediction explanation. Jangan meloncat ke local explanation bila model global tidak tervalidasi. Penjelasan model tidak memperbaiki model yang salah atau data yang tidak relevan.
library(tidymodels)
set.seed(260809)
dat <- read_csv("data/simulasi_panel_regional.csv", show_col_types = FALSE) |> filter(tahun == 2025)
s <- initial_split(dat, prop = .8)
tr <- training(s); te <- testing(s)
rf_spec <- rand_forest(trees = 500, mtry = 4, min_n = 3) |>
set_engine("ranger", importance = "permutation") |>
set_mode("regression")
rf_fit <- workflow() |>
add_formula(kemiskinan_persen ~ pdrb_perkapita_juta + tpt_persen + ipm + internet_persen + umkm_per_1000 + akses_kesehatan) |>
add_model(rf_spec) |>
fit(tr)
predict(rf_fit, te) |>
bind_cols(te |> select(kemiskinan_persen)) |>
yardstick::metrics(truth = kemiskinan_persen, estimate = .pred)#> # A tibble: 3 × 3
#> .metric .estimator .estimate
#> <chr> <chr> <dbl>
#> 1 rmse standard 1.90
#> 2 rsq standard 0.00147
#> 3 mae standard 1.51
INDO-DAPOER dapat menyediakan fitur sosial-ekonomi lintas kabupaten. Karena jumlah indikator sangat banyak dan missingness bervariasi, pemilihan fitur harus mengikuti teori dan data availability; memasukkan semua indikator tanpa screening dapat meningkatkan leakage dan instability.
Kartu dataset real.
# Bandingkan model sederhana dan RF pada split yang sama.
lm_fit <- linear_reg() |> set_engine("lm") |>
fit(kemiskinan_persen ~ pdrb_perkapita_juta + tpt_persen + ipm + internet_persen + umkm_per_1000 + akses_kesehatan,
data = tr)
lm_pred <- predict(lm_fit, te) |> bind_cols(te |> select(kemiskinan_persen))
rf_pred <- predict(rf_fit, te) |> bind_cols(te |> select(kemiskinan_persen))
bind_rows(
yardstick::metrics(lm_pred, kemiskinan_persen, .pred) |> mutate(model = "Linear"),
yardstick::metrics(rf_pred, kemiskinan_persen, .pred) |> mutate(model = "Random forest")
) |>
filter(.metric %in% c("rmse", "mae")) |>
select(model, .metric, .estimate) |>
knitr::kable(digits = 3)| model | .metric | .estimate |
|---|---|---|
| Linear | rmse | 2.114 |
| Linear | mae | 1.797 |
| Random forest | rmse | 1.896 |
| Random forest | mae | 1.510 |
vis_compare <- dplyr::bind_rows(
lm_pred |> dplyr::transmute(actual = kemiskinan_persen, pred = .pred, model = "Linear regression"),
rf_pred |> dplyr::transmute(actual = kemiskinan_persen, pred = .pred, model = "Random forest")
)
ggplot2::ggplot(vis_compare, ggplot2::aes(actual, pred)) +
ggplot2::geom_abline(slope = 1, intercept = 0, linetype = 2, colour = "#C99A17") +
ggplot2::geom_point(alpha = .7, colour = "#145B8C") +
ggplot2::facet_wrap(~model) +
ggplot2::labs(title = "Aktual versus prediksi pada split yang sama", x = "Aktual", y = "Prediksi")rf_engine9 <- workflows::extract_fit_engine(rf_fit)
imp9 <- tibble::enframe(rf_engine9$variable.importance, name="feature", value="importance") |>
dplyr::arrange(dplyr::desc(importance))
knitr::kable(imp9, digits=3, caption="Permutation variable importance Random Forest")| feature | importance |
|---|---|
| pdrb_perkapita_juta | 2.214 |
| internet_persen | 0.132 |
| umkm_per_1000 | 0.032 |
| akses_kesehatan | 0.014 |
| tpt_persen | -0.060 |
| ipm | -0.071 |
ggplot2::ggplot(imp9, ggplot2::aes(reorder(feature, importance), importance)) +
ggplot2::geom_col() + ggplot2::coord_flip() +
ggplot2::labs(title="Variable importance Random Forest", x=NULL, y="Permutation importance")error9 <- dplyr::bind_rows(
lm_pred |> dplyr::mutate(model="Linear"),
rf_pred |> dplyr::mutate(model="Random forest")
) |> dplyr::mutate(error=.pred-kemiskinan_persen)
err_summary9 <- error9 |> dplyr::group_by(model) |>
dplyr::summarise(RMSE=sqrt(mean(error^2)), MAE=mean(abs(error)), Bias=mean(error), MaxAbs=max(abs(error)), .groups="drop")
knitr::kable(err_summary9, digits=3, caption="Perbandingan distribusi error model")| model | RMSE | MAE | Bias | MaxAbs |
|---|---|---|---|---|
| Linear | 2.114 | 1.797 | 0.401 | 3.534 |
| Random forest | 1.896 | 1.510 | 0.464 | 3.876 |
ggplot2::ggplot(error9, ggplot2::aes(.pred, error)) +
ggplot2::geom_hline(yintercept=0,linetype=2) + ggplot2::geom_point(alpha=.75) +
ggplot2::facet_wrap(~model) + ggplot2::labs(title="Residual diagnostic pada holdout", x="Prediksi", y="Error prediksi")Jika random forest hanya memperbaiki RMSE sedikit tetapi jauh lebih sulit dijelaskan, model linear mungkin lebih berguna untuk dialog kebijakan. Sebaliknya, jika tujuan operasional adalah screening ribuan unit dan RF mengurangi false negatives secara substansial, kompleksitas tambahan dapat dibenarkan.
mtry dan min_n lalu bandingkan kinerja.Gunakan dataset yang sama untuk baseline linear model, regression tree, dan random forest. Pastikan split sama. Bandingkan RMSE/MAE, training time secara sederhana, dan interpretability. Beri rekomendasi model untuk deployment pemerintah daerah—boleh memilih model yang bukan paling akurat bila alasannya kuat.
Milestone model dimulai: minimal satu baseline interpretable dan satu model alternatif. Tim harus mendokumentasikan alasan perbandingan, bukan sekadar menambah algoritma.
Machine learning memberi fleksibilitas, bukan otomatis validitas. Keunggulannya harus dibuktikan pada data holdout dan dikaitkan dengan keputusan kebijakan.
Classification relevan saat outcome bersifat kategori: desa prioritas/nonprioritas, risiko tinggi/rendah, UMKM potensial/tidak, atau keberhasilan program. Namun threshold classification adalah keputusan yang membawa konsekuensi alokasi sumber daya.
Mahasiswa mampu menerapkan logistic regression dan classifier, membaca confusion matrix, precision, recall, specificity, F1, ROC-AUC, dan memilih threshold berdasarkan biaya kesalahan.
False negative dapat lebih mahal daripada false positive jika model digunakan untuk mendeteksi wilayah yang sangat rentan. Karena itu, accuracy saja tidak cukup, terutama bila kelas tidak seimbang.
Logistic regression:
dengan .
Precision dan recall:
F1:
Untuk , Logit model: Sehingga Odds ratio untuk kenaikan satu unit adalah , dengan prediktor lain tetap. Interpretasi odds ratio bukan perubahan probabilitas absolut yang konstan.
Likelihood Bernoulli: Negative log-likelihood / binary cross-entropy:
Dengan TP, TN, FP, FN:
Balanced accuracy: Untuk kelas prioritas yang jarang, accuracy dapat tinggi walaupun seluruh kasus prioritas gagal ditemukan.
Jika tindakan diberikan saat , expected classification cost pada validation data: Pilih yang meminimalkan biaya atau memenuhi kapasitas intervensi. Jika pemerintah hanya mampu menangani 15% wilayah, threshold dapat dikaitkan dengan kuantil risk score, tetapi keputusan itu harus transparan.
ROC memplot TPR vs FPR dengan AUC dapat dipahami sebagai probabilitas satu observasi positif acak memperoleh score lebih tinggi daripada observasi negatif acak. (Fawcett 2006)
AUC mengukur ranking discrimination, bukan calibration dan bukan manfaat kebijakan. Untuk kelas sangat imbalanced, precision–recall curve sering lebih informatif.
Prediksi terkalibrasi berarti di antara unit dengan , sekitar 20% benar-benar positif pada data serupa. Calibration intercept/slope dapat diperiksa melalui model Idealnya dan . Calibration penting jika probabilitas dipakai untuk alokasi sumber daya, bukan hanya ranking.
Threshold 0,5 bukan hukum alam. Jika anggaran hanya mampu mengintervensi 15% desa, threshold dapat ditetapkan berdasarkan kapasitas program dan tujuan, lalu kinerja serta fairness dinilai pada threshold itu.
Dari 200 wilayah/desa: TP=30, FN=10, FP=40, TN=120. Interpretasi: model menemukan 75% kasus prioritas, tetapi hanya 43% dari unit yang ditandai benar-benar prioritas berdasarkan label. Jika verifikasi lapangan murah, precision ini mungkin dapat diterima; jika intervensi mahal, threshold perlu ditinjau.
Jika threshold turun, secara umum sensitivity naik dan specificity turun. Pilih threshold dari validation, bukan test. Bila , : Bandingkan beberapa , lalu lakukan sanity check apakah jumlah unit terpilih sesuai kapasitas program.
Jika , odds ratio=2. Bila baseline probability 0.10, odds=0.111; setelah dua kali odds=0.222, probability=0.182. Kenaikan probability hanya 8.2 points. Bila baseline probability 0.50, odds=1 →2, probability=0.667, naik 16.7 points. Efek probability bergantung baseline.
Bagi prediksi menjadi deciles/bin. Untuk bin : Plot vs ; garis ideal . Untuk kebijakan risk-based, calibration dapat lebih penting daripada sedikit perbedaan AUC.
set.seed(260820)
prob <- runif(200)
y <- rbinom(200,1,prob)
thresholds <- c(.2,.3,.4,.5,.6)
threshold_table <- purrr::map_dfr(thresholds, function(t){
pred <- as.integer(prob>=t)
TP <- sum(pred==1 & y==1); FN <- sum(pred==0 & y==1)
FP <- sum(pred==1 & y==0); TN <- sum(pred==0 & y==0)
tibble(threshold=t,
sensitivity=TP/(TP+FN), specificity=TN/(TN+FP),
precision=ifelse(TP+FP==0,NA,TP/(TP+FP)),
selected=TP+FP, cost=4*FN+FP)
})
knitr::kable(threshold_table, digits=3)| threshold | sensitivity | specificity | precision | selected | cost |
|---|---|---|---|---|---|
| 0.2 | 0.980 | 0.314 | 0.578 | 166 | 78 |
| 0.3 | 0.939 | 0.500 | 0.643 | 143 | 75 |
| 0.4 | 0.898 | 0.588 | 0.677 | 130 | 82 |
| 0.5 | 0.827 | 0.735 | 0.750 | 108 | 95 |
| 0.6 | 0.724 | 0.833 | 0.807 | 88 | 125 |
Tidak ada “metric terbaik” tanpa decision context. (Fawcett 2006)
library(tidymodels)
set.seed(260810)
# Membaca data simulasi dan menstandarkan label kelas.
# "prioritas" sengaja ditempatkan sebagai level pertama karena dalam yardstick
# level pertama adalah event class secara default.
desa <- read_csv("data/simulasi_klasifikasi_desa.csv", show_col_types = FALSE) |>
mutate(
.label_raw = tolower(trimws(as.character(prioritas_intervensi))),
prioritas_intervensi = case_when(
.label_raw %in% c("1", "prioritas", "ya", "yes", "true") ~ "prioritas",
.label_raw %in% c("0", "non", "non-prioritas", "tidak", "no", "false") ~ "non",
TRUE ~ NA_character_
)
) |>
select(-.label_raw)
# Guardrail pedagogis: ROC hanya terdefinisi jika kedua kelas tersedia.
# Jika file simulasi lama memiliki kelas yang terlalu timpang atau labelnya tidak
# dikenali, label simulasi dibentuk ulang dari skor kerentanan regional.
zscore_safe <- function(x) {
sx <- stats::sd(x, na.rm = TRUE)
mx <- mean(x, na.rm = TRUE)
if (!is.finite(sx) || sx == 0) return(rep(0, length(x)))
(x - mx) / sx
}
class_count <- desa |>
filter(!is.na(prioritas_intervensi)) |>
count(prioritas_intervensi, name = "n")
if (nrow(class_count) < 2 || min(class_count$n) < 8 || anyNA(desa$prioritas_intervensi)) {
skor_kerentanan <- with(
desa,
1.00 * zscore_safe(kemiskinan_persen) +
0.55 * zscore_safe(jarak_pusat_km) -
0.45 * zscore_safe(akses_kesehatan) -
0.40 * zscore_safe(kualitas_jalan) -
0.50 * zscore_safe(internet_persen)
)
batas_prioritas <- as.numeric(stats::quantile(
skor_kerentanan, probs = 0.70, na.rm = TRUE, names = FALSE
))
desa <- desa |>
mutate(
prioritas_intervensi = if_else(
skor_kerentanan >= batas_prioritas, "prioritas", "non"
)
)
}
desa <- desa |>
mutate(
prioritas_intervensi = factor(
prioritas_intervensi,
levels = c("prioritas", "non")
)
)
# Tampilkan keseimbangan kelas sebelum pemodelan.
class_count <- desa |>
count(prioritas_intervensi, name = "n") |>
mutate(proporsi = n / sum(n))
knitr::kable(
class_count, digits = 3,
caption = "Distribusi kelas sebelum train-test split"
)| prioritas_intervensi | n | proporsi |
|---|---|---|
| prioritas | 240 | 0.3 |
| non | 560 | 0.7 |
# Stratified split mempertahankan proporsi kelas pada training dan testing.
sp <- initial_split(desa, prop = .8, strata = prioritas_intervensi)
trc <- training(sp)
tec <- testing(sp)
# Pemeriksaan eksplisit agar evaluasi classification tidak berjalan pada test set
# yang hanya berisi satu kelas.
if (dplyr::n_distinct(tec$prioritas_intervensi) < 2) {
stop(
"Testing set hanya memiliki satu kelas. Periksa distribusi prioritas_intervensi ",
"atau gunakan data simulasi yang telah diperbarui."
)
}
knitr::kable(
tec |> count(prioritas_intervensi, name = "n_test"),
caption = "Distribusi kelas pada testing set"
)| prioritas_intervensi | n_test |
|---|---|
| prioritas | 48 |
| non | 112 |
logit <- logistic_reg() |>
set_engine("glm") |>
fit(
prioritas_intervensi ~ kemiskinan_persen + jarak_pusat_km +
akses_kesehatan + kualitas_jalan + internet_persen,
data = trc
)
pr <- predict(logit, tec, type = "prob") |>
bind_cols(predict(logit, tec, type = "class")) |>
bind_cols(tec |> select(prioritas_intervensi))
conf_mat(pr, truth = prioritas_intervensi, estimate = .pred_class)#> Truth
#> Prediction prioritas non
#> prioritas 47 0
#> non 1 112
metric_set(accuracy, sens, spec, precision, recall, f_meas)(
pr,
truth = prioritas_intervensi,
estimate = .pred_class
)#> # A tibble: 6 × 3
#> .metric .estimator .estimate
#> <chr> <chr> <dbl>
#> 1 accuracy binary 0.994
#> 2 sens binary 0.979
#> 3 spec binary 1
#> 4 precision binary 1
#> 5 recall binary 0.979
#> 6 f_meas binary 0.989
# AUC dan ROC menggunakan "prioritas" sebagai event class.
auc_out <- yardstick::roc_auc(
pr,
truth = prioritas_intervensi,
.pred_prioritas,
event_level = "first"
)
knitr::kable(auc_out, digits = 3, caption = "ROC AUC pada testing set")| .metric | .estimator | .estimate |
|---|---|---|
| roc_auc | binary | 1 |
roc_out <- yardstick::roc_curve(
pr,
truth = prioritas_intervensi,
.pred_prioritas,
event_level = "first"
)
autoplot(roc_out) +
ggplot2::geom_abline(linetype = 2, alpha = .6) +
ggplot2::labs(
title = "ROC Curve — Klasifikasi Prioritas Intervensi",
subtitle = "Event class: prioritas; data simulasi",
x = "1 - Specificity",
y = "Sensitivity"
)Classification dapat dibentuk dari data nyata dengan mendefinisikan label kebijakan, misalnya kabupaten dengan poverty rate di atas quantile 75 sebagai screening target. Tetapi label berbasis cut-off statistik bukan ground truth kebijakan; mahasiswa wajib menjelaskan bahwa label dibuat untuk latihan dan tidak otomatis valid untuk penetapan program.
Kartu dataset real.
SI.POV.NAPR.ZS = poverty rate; label latihan prioritas=1 dibuat dari cut-off eksplisit (mis. kuantil 75), sementara predictors dipilih dari indikator yang tersedia sebelum keputusan.# Threshold 0.30 untuk meningkatkan sensitivitas terhadap kelas prioritas.
pr2 <- pr |>
mutate(.pred_30 = factor(if_else(.pred_prioritas >= .30, "prioritas", "non"),
levels = c("prioritas", "non")))
conf_mat(pr2, truth = prioritas_intervensi, estimate = .pred_30)#> Truth
#> Prediction prioritas non
#> prioritas 47 0
#> non 1 112
class10 <- pr |>
dplyr::mutate(.pred_class = factor(ifelse(.pred_prioritas >= .5, "prioritas", "non"), levels=levels(prioritas_intervensi)))
cm10 <- yardstick::conf_mat(class10, truth=prioritas_intervensi, estimate=.pred_class)
cm10#> Truth
#> Prediction prioritas non
#> prioritas 47 0
#> non 1 112
yardstick::metric_set(yardstick::accuracy, yardstick::sens, yardstick::spec, yardstick::ppv, yardstick::npv, yardstick::f_meas)(
class10, truth=prioritas_intervensi, estimate=.pred_class, event_level="first"
) |> knitr::kable(digits=3, caption="Metric klasifikasi pada threshold 0,50")| .metric | .estimator | .estimate |
|---|---|---|
| accuracy | binary | 0.994 |
| sens | binary | 0.979 |
| spec | binary | 1.000 |
| ppv | binary | 1.000 |
| npv | binary | 0.991 |
| f_meas | binary | 0.989 |
ggplot2::ggplot(pr, ggplot2::aes(.pred_prioritas, fill=prioritas_intervensi)) +
ggplot2::geom_histogram(position="identity", alpha=.55, bins=12) +
ggplot2::labs(title="Distribusi probabilitas prediksi menurut kelas aktual", x="Predicted probability: prioritas", fill="Aktual")cal10 <- pr |>
dplyr::mutate(bin=dplyr::ntile(.pred_prioritas, 5), y=as.integer(prioritas_intervensi=="prioritas")) |>
dplyr::group_by(bin) |>
dplyr::summarise(mean_pred=mean(.pred_prioritas), observed_rate=mean(y), n=dplyr::n(), .groups="drop")
knitr::kable(cal10, digits=3, caption="Calibration table per kuintil probabilitas")| bin | mean_pred | observed_rate | n |
|---|---|---|---|
| 1 | 0.000 | 0.0 | 32 |
| 2 | 0.000 | 0.0 | 32 |
| 3 | 0.000 | 0.0 | 32 |
| 4 | 0.469 | 0.5 | 32 |
| 5 | 1.000 | 1.0 | 32 |
ggplot2::ggplot(cal10, ggplot2::aes(mean_pred, observed_rate)) +
ggplot2::geom_abline(slope=1,intercept=0,linetype=2) + ggplot2::geom_point(size=3) + ggplot2::geom_line() +
ggplot2::coord_equal(xlim=c(0,1),ylim=c(0,1)) +
ggplot2::labs(title="Calibration plot", x="Mean predicted probability", y="Observed event rate")Jika recall meningkat dari 0,60 menjadi 0,82 setelah threshold diturunkan, lebih banyak wilayah rentan berhasil terdeteksi, tetapi false positives juga naik. Implikasinya adalah kebutuhan verifikasi lapangan lebih besar. Pilihan threshold harus dibahas bersama kapasitas program.
Definisikan binary priority outcome dari kasus regional secara transparan. Fit logistic regression dan satu model non-linear. Bandingkan ROC-AUC, PR behavior, sensitivity, precision, calibration, dan minimal tiga threshold. Pilih threshold dengan alasan kapasitas/biaya kebijakan.
Kisi-kisi: tree impurity; random forest; boosting; logistic probability/odds; confusion matrix; sensitivity/specificity; precision/F1; ROC-AUC; calibration; threshold berbasis cost.
Jika proyek menggunakan classification, tim harus menyertakan cost-of-error statement: siapa yang dirugikan oleh FP/FN dan bagaimana threshold dipilih.
Classification adalah mekanisme keputusan. Metric dan threshold harus dikaitkan dengan kapasitas program, risiko, fairness, dan prosedur verifikasi manusia.
Clustering digunakan untuk menyusun tipologi wilayah berdasarkan kemiripan profil indikator, bukan untuk menentukan peringkat “baik–buruk”. Dalam inovasi regional, segmentasi dapat membantu pemerintah merancang paket intervensi yang berbeda untuk kelompok daerah dengan kebutuhan berbeda. Karena hasil cluster sensitif terhadap pemilihan indikator, skala, distance metric, jumlah cluster, dan initialization, analisis harus menampilkan proses pemilihan cluster dan profil akhirnya secara transparan. (Kaufman dan Rousseeuw 1990; Hastie, Tibshirani, dan Friedman 2009; James dkk. 2021)
Setelah pertemuan ini mahasiswa mampu:
Untuk wilayah dengan indikator, tulis vektor fitur sebagai . Karena indikator memiliki unit berbeda, fitur umumnya distandardisasi:
dengan rata-rata indikator dan simpangan bakunya.
K-means membagi observasi ke cluster dengan meminimumkan within-cluster sum of squares:
di mana adalah centroid cluster .
Untuk observasi , silhouette didefinisikan sebagai
dengan rata-rata jarak ke anggota cluster sendiri dan rata-rata jarak minimum ke cluster lain. Nilai mendekati 1 menunjukkan pemisahan yang baik, mendekati 0 menunjukkan observasi berada di perbatasan, dan negatif mengindikasikan kemungkinan salah pengelompokan. (Rousseeuw 1987)
Hierarchical clustering dengan Ward meminimumkan kenaikan variasi dalam-cluster ketika dua kelompok digabung. Untuk dua cluster dan , perubahan error sum of squares dapat ditulis secara intuitif sebagai fungsi jarak centroid dan ukuran kedua cluster. Karena itu Ward cocok sebagai pembanding K-means ketika tujuan utamanya adalah cluster kompak.
Cluster merupakan ringkasan geometri data yang dipilih analis. Jika fitur hanya ekonomi, hasilnya terutama tipologi ekonomi; jika ditambah pendidikan, kesehatan, digitalisasi, dan UMKM, definisi “kemiripan wilayah” berubah. Karena itu pemilihan fitur adalah keputusan substantif, bukan sekadar teknis.
reg11 <- readr::read_csv("data/simulasi_panel_regional.csv", show_col_types = FALSE) |>
dplyr::filter(tahun == 2025) |>
dplyr::select(
wilayah, pdrb_perkapita_juta, kemiskinan_persen, tpt_persen,
ipm, internet_persen, umkm_per_1000, indeks_inovasi
) |>
tidyr::drop_na()
vars11 <- c("pdrb_perkapita_juta", "kemiskinan_persen", "tpt_persen",
"ipm", "internet_persen", "umkm_per_1000", "indeks_inovasi")
ringkas11 <- reg11 |>
dplyr::summarise(dplyr::across(
dplyr::all_of(vars11),
list(mean = mean, sd = sd, min = min, median = median, max = max)
)) |>
tidyr::pivot_longer(dplyr::everything(), names_to = c("indikator", ".value"), names_pattern = "(.*)_(mean|sd|min|median|max)$")
knitr::kable(ringkas11, digits = 2, caption = "Statistik deskriptif indikator sebelum clustering")| indikator | mean | sd | min | median | max |
|---|---|---|---|---|---|
| pdrb_perkapita_juta | 49.22 | 10.86 | 24.04 | 50.90 | 66.15 |
| kemiskinan_persen | 9.89 | 1.75 | 6.01 | 9.84 | 13.05 |
| tpt_persen | 8.07 | 1.10 | 6.69 | 7.75 | 10.35 |
| ipm | 70.74 | 1.18 | 67.78 | 70.68 | 73.42 |
| internet_persen | 83.44 | 8.19 | 65.66 | 85.60 | 96.99 |
| umkm_per_1000 | 38.60 | 5.12 | 29.37 | 39.66 | 48.99 |
| indeks_inovasi | 68.25 | 4.12 | 60.29 | 69.00 | 76.82 |
Output ini wajib dibaca sebelum standardisasi. Perbedaan rentang yang besar menjelaskan mengapa Euclidean distance pada skala asli dapat didominasi variabel tertentu.
cor11 <- cor(reg11 |> dplyr::select(dplyr::all_of(vars11)), use = "pairwise.complete.obs")
cor_long11 <- as.data.frame(as.table(cor11))
ggplot2::ggplot(cor_long11, ggplot2::aes(Var1, Var2, fill = Freq)) +
ggplot2::geom_tile() +
ggplot2::geom_text(ggplot2::aes(label = sprintf("%.2f", Freq)), size = 3) +
ggplot2::scale_fill_gradient2(limits = c(-1, 1), midpoint = 0) +
ggplot2::coord_equal() +
ggplot2::labs(title = "Korelasi antarindikator sebelum clustering", x = NULL, y = NULL, fill = "r") +
ggplot2::theme(axis.text.x = ggplot2::element_text(angle = 45, hjust = 1))Korelasi tinggi tidak otomatis membuat indikator harus dibuang, tetapi fitur yang sangat redundan dapat memberi bobot geometris berlebih pada satu dimensi substantif.
X11 <- scale(reg11 |> dplyr::select(dplyr::all_of(vars11)))
scale_check11 <- tibble::tibble(
indikator = colnames(X11),
mean_z = apply(X11, 2, mean),
sd_z = apply(X11, 2, sd)
)
knitr::kable(scale_check11, digits = 4, caption = "Pemeriksaan hasil standardisasi")| indikator | mean_z | sd_z |
|---|---|---|
| pdrb_perkapita_juta | 0 | 1 |
| kemiskinan_persen | 0 | 1 |
| tpt_persen | 0 | 1 |
| ipm | 0 | 1 |
| internet_persen | 0 | 1 |
| umkm_per_1000 | 0 | 1 |
| indeks_inovasi | 0 | 1 |
Secara numerik, setiap kolom hasil z-score seharusnya memiliki rata-rata mendekati 0 dan simpangan baku mendekati 1.
set.seed(260811)
d11 <- stats::dist(X11)
eval_k11 <- purrr::map_dfr(2:6, function(k) {
km_tmp <- stats::kmeans(X11, centers = k, nstart = 100)
sil_tmp <- cluster::silhouette(km_tmp$cluster, d11)
tibble::tibble(
K = k,
total_WSS = km_tmp$tot.withinss,
avg_silhouette = mean(sil_tmp[, "sil_width"]),
betweenSS_ratio = km_tmp$betweenss / km_tmp$totss
)
})
knitr::kable(eval_k11, digits = 3, caption = "Perbandingan kandidat jumlah cluster")| K | total_WSS | avg_silhouette | betweenSS_ratio |
|---|---|---|---|
| 2 | 97.396 | 0.372 | 0.465 |
| 3 | 72.859 | 0.290 | 0.600 |
| 4 | 62.985 | 0.265 | 0.654 |
| 5 | 54.639 | 0.202 | 0.700 |
| 6 | 47.707 | 0.196 | 0.738 |
ggplot2::ggplot(eval_k11, ggplot2::aes(K, total_WSS)) +
ggplot2::geom_line(linewidth = 1) +
ggplot2::geom_point(size = 2.7) +
ggplot2::scale_x_continuous(breaks = 2:6) +
ggplot2::labs(title = "Elbow plot", subtitle = "WSS selalu turun; cari perubahan kemiringan yang masuk akal", y = "Total within-cluster SS")ggplot2::ggplot(eval_k11, ggplot2::aes(K, avg_silhouette)) +
ggplot2::geom_line(linewidth = 1) +
ggplot2::geom_point(size = 2.7) +
ggplot2::scale_x_continuous(breaks = 2:6) +
ggplot2::labs(title = "Rata-rata silhouette untuk beberapa nilai K", y = "Average silhouette width")Pemilihan tidak didasarkan pada satu grafik saja. Dalam contoh ini, kandidat awal dipilih dari silhouette tertinggi, lalu diperiksa kembali dari sisi interpretabilitas dan kegunaan kebijakan.
k11 <- eval_k11 |> dplyr::slice_max(avg_silhouette, n = 1, with_ties = FALSE) |> dplyr::pull(K)
set.seed(260811)
km11 <- stats::kmeans(X11, centers = k11, nstart = 200)
fit_summary11 <- tibble::tibble(
jumlah_cluster = k11,
total_SS = km11$totss,
within_SS = km11$tot.withinss,
between_SS = km11$betweenss,
proporsi_between_SS = km11$betweenss / km11$totss
)
knitr::kable(fit_summary11, digits = 3, caption = "Ringkasan fit K-means final")| jumlah_cluster | total_SS | within_SS | between_SS | proporsi_between_SS |
|---|---|---|---|---|
| 2 | 182 | 97.396 | 84.604 | 0.465 |
membership11 <- reg11 |>
dplyr::mutate(cluster = factor(km11$cluster)) |>
dplyr::arrange(cluster, dplyr::desc(kemiskinan_persen)) |>
dplyr::select(wilayah, cluster, dplyr::all_of(vars11))
knitr::kable(membership11, digits = 2, caption = "Keanggotaan cluster dan indikator setiap wilayah")| wilayah | cluster | pdrb_perkapita_juta | kemiskinan_persen | tpt_persen | ipm | internet_persen | umkm_per_1000 | indeks_inovasi |
|---|---|---|---|---|---|---|---|---|
| Wilayah_23 | 1 | 41.20 | 13.05 | 7.05 | 69.78 | 72.33 | 35.41 | 70.57 |
| Wilayah_15 | 1 | 36.80 | 12.64 | 7.56 | 69.35 | 75.14 | 30.74 | 63.42 |
| Wilayah_19 | 1 | 34.46 | 11.81 | 7.54 | 70.19 | 76.92 | 31.66 | 63.60 |
| Wilayah_25 | 1 | 41.46 | 11.67 | 6.69 | 71.38 | 69.83 | 33.05 | 64.86 |
| Wilayah_06 | 1 | 43.34 | 11.64 | 7.25 | 69.97 | 84.58 | 36.00 | 60.29 |
| Wilayah_21 | 1 | 24.04 | 11.24 | 6.74 | 67.78 | 65.66 | 31.20 | 60.84 |
| Wilayah_17 | 1 | 39.58 | 10.55 | 7.31 | 70.99 | 79.71 | 35.69 | 69.55 |
| Wilayah_01 | 1 | 31.61 | 9.99 | 7.12 | 70.11 | 76.88 | 33.97 | 63.79 |
| Wilayah_08 | 1 | 41.66 | 8.98 | 7.08 | 69.54 | 73.56 | 29.37 | 61.57 |
| Wilayah_07 | 2 | 44.19 | 12.94 | 8.68 | 71.95 | 78.72 | 43.01 | 67.37 |
| Wilayah_09 | 2 | 45.12 | 10.97 | 9.63 | 70.38 | 85.60 | 40.47 | 68.69 |
| Wilayah_27 | 2 | 52.01 | 10.10 | 7.65 | 69.34 | 90.37 | 40.48 | 69.92 |
| Wilayah_05 | 2 | 46.80 | 10.08 | 8.20 | 70.43 | 85.62 | 40.55 | 69.04 |
| Wilayah_24 | 2 | 53.89 | 10.06 | 8.67 | 71.73 | 88.05 | 36.22 | 71.50 |
| Wilayah_18 | 2 | 53.71 | 9.84 | 7.75 | 70.68 | 84.59 | 40.48 | 67.93 |
| Wilayah_20 | 2 | 62.74 | 9.66 | 6.79 | 70.86 | 93.39 | 41.84 | 71.42 |
| Wilayah_26 | 2 | 54.20 | 9.61 | 9.63 | 71.71 | 75.11 | 38.96 | 65.99 |
| Wilayah_16 | 2 | 50.13 | 9.53 | 9.09 | 70.26 | 87.40 | 40.24 | 67.09 |
| Wilayah_22 | 2 | 59.50 | 9.44 | 8.76 | 71.33 | 89.43 | 44.67 | 74.23 |
| Wilayah_13 | 2 | 50.90 | 8.99 | 7.88 | 70.08 | 82.50 | 39.66 | 69.00 |
| Wilayah_04 | 2 | 54.51 | 8.57 | 7.38 | 69.88 | 85.61 | 37.62 | 71.90 |
| Wilayah_10 | 2 | 66.15 | 8.52 | 8.09 | 71.62 | 96.99 | 46.95 | 70.22 |
| Wilayah_14 | 2 | 64.33 | 8.19 | 10.03 | 72.54 | 95.23 | 42.66 | 71.74 |
| Wilayah_12 | 2 | 57.69 | 7.98 | 10.35 | 71.12 | 93.96 | 48.99 | 72.47 |
| Wilayah_02 | 2 | 65.25 | 7.68 | 7.01 | 73.42 | 91.38 | 41.63 | 70.70 |
| Wilayah_11 | 2 | 61.14 | 7.16 | 7.94 | 72.38 | 87.64 | 45.55 | 76.82 |
| Wilayah_03 | 2 | 52.52 | 6.01 | 9.96 | 71.13 | 86.70 | 35.17 | 68.19 |
Tabel di atas sengaja ditampilkan lengkap. Pada HTML, tabel lebar dapat digeser ke kiri–kanan sehingga nama wilayah dan seluruh indikator tetap dapat diperiksa.
profile11 <- membership11 |>
dplyr::group_by(cluster) |>
dplyr::summarise(
n = dplyr::n(),
dplyr::across(dplyr::all_of(vars11), mean),
.groups = "drop"
)
knitr::kable(profile11, digits = 2, caption = "Profil rata-rata setiap cluster pada skala asli")| cluster | n | pdrb_perkapita_juta | kemiskinan_persen | tpt_persen | ipm | internet_persen | umkm_per_1000 | indeks_inovasi |
|---|---|---|---|---|---|---|---|---|
| 1 | 9 | 37.13 | 11.29 | 7.15 | 69.90 | 74.96 | 33.01 | 64.28 |
| 2 | 18 | 55.27 | 9.19 | 8.53 | 71.16 | 87.68 | 41.40 | 70.24 |
profile_z11 <- as.data.frame(X11) |>
dplyr::mutate(cluster = factor(km11$cluster)) |>
dplyr::group_by(cluster) |>
dplyr::summarise(dplyr::across(dplyr::everything(), mean), .groups = "drop") |>
tidyr::pivot_longer(-cluster, names_to = "indikator", values_to = "mean_z")
ggplot2::ggplot(profile_z11, ggplot2::aes(indikator, cluster, fill = mean_z)) +
ggplot2::geom_tile() +
ggplot2::geom_text(ggplot2::aes(label = sprintf("%.2f", mean_z)), size = 3.2) +
ggplot2::scale_fill_gradient2(midpoint = 0) +
ggplot2::labs(title = "Heatmap profil cluster", subtitle = "Nilai adalah rata-rata z-score; positif berarti di atas rata-rata keseluruhan", x = NULL, y = "Cluster", fill = "Mean z") +
ggplot2::theme(axis.text.x = ggplot2::element_text(angle = 45, hjust = 1))Heatmap lebih berguna untuk penamaan cluster daripada centroid mentah karena seluruh indikator telah berada pada skala yang sebanding.
sil11 <- cluster::silhouette(km11$cluster, d11)
sil_tbl11 <- tibble::as_tibble(as.data.frame(sil11)) |>
dplyr::mutate(wilayah = reg11$wilayah) |>
dplyr::arrange(sil_width)
knitr::kable(
sil_tbl11 |> dplyr::select(wilayah, cluster, neighbor, sil_width),
digits = 3,
caption = "Silhouette setiap wilayah; nilai rendah/negatif perlu diperiksa"
)| wilayah | cluster | neighbor | sil_width |
|---|---|---|---|
| Wilayah_07 | 2 | 1 | 0.037 |
| Wilayah_17 | 1 | 2 | 0.171 |
| Wilayah_26 | 2 | 1 | 0.213 |
| Wilayah_09 | 2 | 1 | 0.252 |
| Wilayah_27 | 2 | 1 | 0.252 |
| Wilayah_13 | 2 | 1 | 0.254 |
| Wilayah_04 | 2 | 1 | 0.278 |
| Wilayah_05 | 2 | 1 | 0.280 |
| Wilayah_18 | 2 | 1 | 0.302 |
| Wilayah_03 | 2 | 1 | 0.319 |
| Wilayah_16 | 2 | 1 | 0.344 |
| Wilayah_23 | 1 | 2 | 0.362 |
| Wilayah_06 | 1 | 2 | 0.367 |
| Wilayah_24 | 2 | 1 | 0.381 |
| Wilayah_20 | 2 | 1 | 0.389 |
| Wilayah_02 | 2 | 1 | 0.389 |
| Wilayah_25 | 1 | 2 | 0.456 |
| Wilayah_11 | 2 | 1 | 0.456 |
| Wilayah_08 | 1 | 2 | 0.456 |
| Wilayah_12 | 2 | 1 | 0.472 |
| Wilayah_21 | 1 | 2 | 0.483 |
| Wilayah_14 | 2 | 1 | 0.489 |
| Wilayah_10 | 2 | 1 | 0.494 |
| Wilayah_01 | 1 | 2 | 0.511 |
| Wilayah_22 | 2 | 1 | 0.520 |
| Wilayah_15 | 1 | 2 | 0.560 |
| Wilayah_19 | 1 | 2 | 0.568 |
ggplot2::ggplot(sil_tbl11, ggplot2::aes(reorder(wilayah, sil_width), sil_width, fill = factor(cluster))) +
ggplot2::geom_col() +
ggplot2::coord_flip() +
ggplot2::geom_hline(yintercept = 0, linetype = 2) +
ggplot2::labs(title = "Silhouette per wilayah", x = NULL, y = "Silhouette width", fill = "Cluster")Wilayah dengan silhouette dekat nol adalah kasus transisi; kebijakan sebaiknya tidak memperlakukan batas cluster sebagai kategori keras.
pca11 <- stats::prcomp(X11, center = FALSE, scale. = FALSE)
pca_score11 <- tibble::as_tibble(pca11$x[, 1:2]) |>
dplyr::mutate(wilayah = reg11$wilayah, cluster = factor(km11$cluster))
ggplot2::ggplot(pca_score11, ggplot2::aes(PC1, PC2, colour = cluster)) +
ggplot2::geom_point(size = 3, alpha = .85) +
ggplot2::labs(
title = "Visualisasi cluster pada dua komponen utama",
subtitle = paste0("PC1 + PC2 menjelaskan ", round(100 * sum(summary(pca11)$importance[2,1:2]), 1), "% variasi terstandardisasi"),
colour = "Cluster"
)Plot PCA hanya proyeksi dua dimensi; keputusan K-means tetap menggunakan seluruh indikator terstandardisasi, bukan hanya PC1–PC2.
hc11 <- stats::hclust(d11, method = "ward.D2")
plot(hc11, labels = reg11$wilayah, cex = .65,
main = "Dendrogram hierarchical clustering — Ward.D2", xlab = "", sub = "")
rect.hclust(hc11, k = k11, border = 2:(k11 + 1))hc_group11 <- stats::cutree(hc11, k = k11)
agreement11 <- table(KMeans = km11$cluster, Ward = hc_group11)
knitr::kable(as.data.frame.matrix(agreement11), caption = "Tabulasi silang K-means versus Ward")| 1 | 2 |
|---|---|
| 9 | 0 |
| 0 | 18 |
Perbedaan keanggotaan tidak selalu berarti salah. Ia menunjukkan bahwa tipologi sensitif terhadap definisi cluster dan perlu dibaca sebagai alat eksplorasi.
Interpretasi dilakukan dari tabel profil dan heatmap, bukan dari nomor cluster. Misalnya, sebuah cluster dengan kemiskinan dan TPT di atas rata-rata serta internet dan IPM di bawah rata-rata dapat diberi label “tekanan sosial-ekonomi tinggi–kapabilitas layanan lebih rendah”. Cluster dengan PDRB dan internet tinggi tetapi TPT tetap tinggi dapat menunjukkan “ekonomi kuat–mismatch pasar kerja”. Kebijakan untuk kedua kelompok tidak seharusnya sama.
Cluster tidak membuktikan mekanisme sebab-akibat. Setelah tipologi terbentuk, mahasiswa harus kembali ke data sektoral, konteks institusi, dan informasi lapangan untuk memeriksa apakah paket kebijakan yang diusulkan masuk akal.
Gunakan 5–8 indikator pada capstone project. Tampilkan statistik deskriptif, korelasi, alasan standardisasi, evaluasi , tabel membership lengkap, profil cluster, silhouette, heatmap, dan minimal satu sensitivity check. Akhiri dengan satu halaman strategi kebijakan yang berbeda untuk setiap tipologi.
Milestone minggu ini adalah regional segmentation package: fitur terpilih, hasil evaluasi , membership, profil, visualisasi, sensitivity analysis, dan satu set rekomendasi berbeda menurut tipologi.
Clustering bernilai ketika ia mengubah data multivariat menjadi tipologi yang dapat dipahami dan diuji. Analisis yang hanya menghasilkan nomor cluster tanpa profil, silhouette, membership, dan sensitivity check belum cukup untuk jenjang magister.
Indikator pembangunan sering saling berkorelasi: pendidikan, kesehatan, internet, pendapatan, dan layanan dasar bergerak bersama. PCA membantu mereduksi dimensi dan mengidentifikasi kombinasi laten, tetapi komponen harus ditafsirkan dengan hati-hati.
Mahasiswa mampu melakukan PCA pada data yang distandardisasi, membaca variance explained dan loadings, serta menggunakan komponen untuk visualisasi/segmentasi tanpa kehilangan interpretasi kebijakan.
PCA mencari arah linear yang menjelaskan variasi maksimum. PC1 adalah kombinasi linear dengan variance terbesar, PC2 orthogonal terhadap PC1 dan menjelaskan variance terbesar berikutnya. PCA tidak secara otomatis menghasilkan “indeks pembangunan” yang normatif.
Untuk data terpusat , covariance matrix
PCA menyelesaikan
di mana eigenvector/loading PC ke- dan variance yang dijelaskan. Skor komponen:
Untuk data berukuran , pusatkan setiap kolom: Covariance matrix: Jika variabel memiliki unit/skala sangat berbeda, gunakan correlation PCA dengan data standardisasi .
PCA mencari arah unit yang memaksimalkan variance proyeksi: Solusinya adalah eigenvector dari : dengan .
Score principal component: Loading menunjukkan kontribusi variabel pada komponen .
Pemilihan jumlah komponen tidak boleh hanya berdasarkan threshold 80%/90%; interpretability dan tujuan project harus dipertimbangkan. (Jolliffe dan Cadima 2016)
Dengan komponen: Reconstruction error: PCA memilih subspace linear yang meminimalkan squared reconstruction error, tetapi komponen yang menjelaskan variance tinggi belum tentu paling relevan untuk outcome kebijakan tertentu.
Skor PC1 dapat dipakai sebagai data-driven index: Namun tanda eigenvector dapat terbalik tanpa mengubah solusi; orientasi indeks harus ditentukan agar “lebih tinggi” memiliki arti substantif konsisten. PCA juga menimbang berdasarkan struktur covariance, bukan prioritas normatif. Bandingkan dengan indeks berbobot teori dan lakukan sensitivity analysis. (OECD dan Joint Research Centre, European Commission 2008)
Sudut antar loading vector secara kasar berkaitan dengan korelasi: arah sejalan ≈ korelasi positif, berlawanan ≈ negatif, hampir tegak lurus ≈ korelasi kecil. Panjang dan skala biplot bergantung implementasi, jadi interpretasi harus mengikuti definisi scaling perangkat lunak.
Jika internet, IPM, pendidikan, dan akses kesehatan semuanya tinggi bersama, PC1 dapat menangkap “kapabilitas layanan/manusia” secara statistik. Tetapi penamaan tersebut harus didukung pola loading, bukan asumsi.
Misalkan covariance matrix standardized dua indikator adalah Eigenvalue memenuhi : Total variance=2, sehingga Eigenvector pertama proporsional , artinya PC1 kira-kira rata-rata standardized kedua indikator; PC2 menangkap kontras di antara keduanya.
Jika adalah eigenvector, juga eigenvector dengan eigenvalue sama. Karena itu software dapat memberikan PC1 dengan tanda berlawanan tanpa mengubah geometri. Untuk indeks, pilih orientasi agar makna substantif konsisten dan dokumentasikan pembalikan tanda.
Jika variabel berbeda unit, covariance PCA dapat didominasi variabel variance besar. Correlation PCA ekuivalen PCA pada standardized. Namun standardisasi menganggap satu SD setiap variabel comparable; jika measurement reliability berbeda, pertimbangkan hal tersebut dalam interpretasi.
Dengan komponen, prediksi data standardized: Residual reconstruction menunjukkan informasi yang tidak ditangkap komponen. Wilayah dengan reconstruction error tinggi bisa merupakan pola unik/outlier yang justru penting secara kebijakan.
xp <- panel |> filter(tahun==2025) |>
select(kemiskinan_persen, tpt_persen, internet_persen, ipm, indeks_inovasi)
pca <- prcomp(xp, center=TRUE, scale.=TRUE)
summary(pca)#> Importance of components:
#> PC1 PC2 PC3 PC4 PC5
#> Standard deviation 1.7221 0.8432 0.7656 0.6708 0.53601
#> Proportion of Variance 0.5931 0.1422 0.1172 0.0900 0.05746
#> Cumulative Proportion 0.5931 0.7353 0.8525 0.9425 1.00000
#> PC1 PC2 PC3
#> kemiskinan_persen -0.443 -0.003 -0.696
#> tpt_persen 0.367 0.893 -0.190
#> internet_persen 0.501 -0.108 0.215
#> ipm 0.439 -0.217 -0.645
#> indeks_inovasi 0.475 -0.379 -0.133
Baca sdev^2 sebagai eigenvalue (untuk covariance matrix dari data transformed sesuai prcomp), rotation sebagai loading/eigenvectors, dan x sebagai score.
Jika PC1 memberi loading besar pada internet dan IPM karena variance/correlation dominan, tetapi stakeholder menilai akses kesehatan normatif sangat penting, PC1 tidak otomatis menggantikan indeks teori. Laporkan dua pendekatan dan sensitivitas. (Jolliffe dan Cadima 2016; OECD dan Joint Research Centre, European Commission 2008)
reg <- read_csv("data/simulasi_panel_regional.csv", show_col_types = FALSE) |>
filter(tahun == 2025)
X <- reg |> select(ipm, internet_persen, indeks_pendidikan, akses_kesehatan, pdrb_perkapita_juta, umkm_per_1000)
pca <- prcomp(X, center = TRUE, scale. = TRUE)
summary(pca)#> Importance of components:
#> PC1 PC2 PC3 PC4 PC5 PC6
#> Standard deviation 2.0253 0.8835 0.72790 0.58744 0.39925 0.28818
#> Proportion of Variance 0.6837 0.1301 0.08831 0.05751 0.02657 0.01384
#> Cumulative Proportion 0.6837 0.8138 0.90208 0.95959 0.98616 1.00000
| PC1 | PC2 | PC3 | |
|---|---|---|---|
| ipm | 0.400 | 0.240 | 0.544 |
| internet_persen | 0.417 | -0.503 | 0.002 |
| indeks_pendidikan | 0.402 | 0.401 | 0.345 |
| akses_kesehatan | 0.347 | 0.597 | -0.633 |
| pdrb_perkapita_juta | 0.454 | -0.267 | 0.087 |
| umkm_per_1000 | 0.422 | -0.318 | -0.420 |
INDO-DAPOER menyediakan banyak indikator yang secara substantif saling terkait. Sebelum PCA, pilih satu periode dan pastikan kelengkapan data memadai. Jangan mencampur level provinsi dan kabupaten atau indikator dengan tahun berbeda tanpa justifikasi.
Kartu dataset real.
eigen12 <- pca$sdev^2
pve12 <- eigen12/sum(eigen12)
eigen_tbl12 <- tibble::tibble(
PC=paste0("PC",seq_along(eigen12)), eigenvalue=eigen12,
PVE=pve12, cumulative_PVE=cumsum(pve12)
)
knitr::kable(eigen_tbl12, digits=3, caption="Eigenvalue, proportion variance explained, dan kumulatif")| PC | eigenvalue | PVE | cumulative_PVE |
|---|---|---|---|
| PC1 | 4.102 | 0.684 | 0.684 |
| PC2 | 0.781 | 0.130 | 0.814 |
| PC3 | 0.530 | 0.088 | 0.902 |
| PC4 | 0.345 | 0.058 | 0.960 |
| PC5 | 0.159 | 0.027 | 0.986 |
| PC6 | 0.083 | 0.014 | 1.000 |
ggplot2::ggplot(eigen_tbl12, ggplot2::aes(seq_along(eigenvalue), PVE)) +
ggplot2::geom_col() + ggplot2::geom_line(ggplot2::aes(y=cumulative_PVE), linewidth=1) +
ggplot2::geom_point(ggplot2::aes(y=cumulative_PVE), size=2.5) +
ggplot2::scale_x_continuous(breaks=seq_along(eigen12), labels=eigen_tbl12$PC) +
ggplot2::labs(title="Scree dan cumulative explained variance", x="Principal component", y="Proporsi variance")load12 <- as.data.frame(pca$rotation[,1:min(4,ncol(pca$rotation)),drop=FALSE]) |>
tibble::rownames_to_column("indikator")
knitr::kable(load12, digits=3, caption="Loading komponen utama")| indikator | PC1 | PC2 | PC3 | PC4 |
|---|---|---|---|---|
| ipm | 0.400 | 0.240 | 0.544 | -0.623 |
| internet_persen | 0.417 | -0.503 | 0.002 | 0.394 |
| indeks_pendidikan | 0.402 | 0.401 | 0.345 | 0.595 |
| akses_kesehatan | 0.347 | 0.597 | -0.633 | -0.004 |
| pdrb_perkapita_juta | 0.454 | -0.267 | 0.087 | -0.042 |
| umkm_per_1000 | 0.422 | -0.318 | -0.420 | -0.318 |
load_long12 <- load12 |> tidyr::pivot_longer(-indikator, names_to="PC", values_to="loading")
ggplot2::ggplot(load_long12, ggplot2::aes(indikator, loading, fill=loading>0)) +
ggplot2::geom_col(show.legend=FALSE) + ggplot2::facet_wrap(~PC) +
ggplot2::coord_flip() + ggplot2::labs(title="Loading profile setiap principal component", x=NULL)score12 <- tibble::as_tibble(pca$x[,1:2,drop=FALSE]) |> dplyr::mutate(wilayah=reg$wilayah) |>
dplyr::select(wilayah, dplyr::everything()) |> dplyr::arrange(dplyr::desc(PC1))
knitr::kable(score12, digits=3, caption="Score PC1 dan PC2 setiap wilayah")| wilayah | PC1 | PC2 |
|---|---|---|
| Wilayah_02 | 4.146 | 2.029 |
| Wilayah_10 | 3.727 | 0.336 |
| Wilayah_11 | 3.071 | 0.842 |
| Wilayah_14 | 2.711 | -0.433 |
| Wilayah_12 | 2.306 | -0.714 |
| Wilayah_20 | 1.926 | -0.475 |
| Wilayah_22 | 1.851 | -0.243 |
| Wilayah_07 | 0.362 | 0.607 |
| Wilayah_13 | 0.087 | 0.052 |
| Wilayah_03 | 0.059 | -0.019 |
| Wilayah_24 | -0.174 | -1.209 |
| Wilayah_16 | -0.196 | -1.101 |
| Wilayah_09 | -0.214 | -0.485 |
| Wilayah_26 | -0.225 | 0.081 |
| Wilayah_18 | -0.245 | -1.078 |
| Wilayah_27 | -0.268 | -1.448 |
| Wilayah_06 | -0.550 | 0.202 |
| Wilayah_05 | -0.601 | -1.098 |
| Wilayah_04 | -0.679 | -1.347 |
| Wilayah_17 | -0.948 | 0.353 |
| Wilayah_25 | -1.483 | 1.228 |
| Wilayah_23 | -1.508 | 1.097 |
| Wilayah_19 | -1.673 | 0.919 |
| Wilayah_01 | -2.113 | 0.296 |
| Wilayah_08 | -2.237 | 0.790 |
| Wilayah_15 | -2.646 | 0.267 |
| Wilayah_21 | -4.486 | 0.551 |
Jika PC1 memberi loading positif tinggi pada IPM, internet, pendidikan, kesehatan, dan PDRB, skor PC1 tinggi dapat dibaca sebagai kombinasi kapabilitas pembangunan. Namun PCA memaksimalkan variance, bukan relevansi kebijakan; indikator penting dengan variasi kecil dapat terabaikan.
Lakukan PCA pada minimal lima indikator regional. Laporkan eigenvalues, PVE, loading, score, dan biplot. Bandingkan ranking berbasis PC1 dengan indeks berbobot teori. Jelaskan minimal dua perbedaan dan implikasinya.
Fokus: covariance vs correlation PCA; eigenvalue/eigenvector; score/loading; PVE; reconstruction; tanda PC; keterbatasan PCA untuk indeks kebijakan.
PCA dapat dipakai bila proyek memiliki banyak indikator berkorelasi atau untuk membangun visual 2D sebelum clustering. Tim harus tetap menyertakan tabel loading dan interpretasi.
PCA mereduksi kompleksitas statistik, bukan kompleksitas kebijakan. Komponen harus dibaca melalui loadings, variance explained, dan konteks indikator.
Analisis regional pada tingkat kabupaten/kota secara alami merupakan data areal: setiap observasi mewakili suatu polygon administratif, bukan satu titik koordinat. Karena itu pembelajaran spasial pada bab ini menggunakan batas kabupaten/kota Jawa Barat dari berkas polygon yang disediakan bersama e-book dan menggabungkannya dengan persentase penduduk miskin tahun 2024. Dataset kemiskinan kabupaten/kota Jawa Barat dipublikasikan oleh Badan Pusat Statistik dan didiseminasikan melalui Open Data Jawa Barat; seri persentase tersedia untuk 2010–2025, sedangkan publikasi resmi BPS Jawa Barat juga mendokumentasikan kemiskinan kabupaten/kota 2019–2024. (Badan Pusat Statistik dan Pemerintah Provinsi Jawa Barat 2026c; Badan Pusat Statistik Provinsi Jawa Barat 2025)
Bab ini membahas tiga lapis analisis: (1) pemetaan choropleth, (2) pembentukan struktur ketetanggaan areal, dan (3) autocorrelation global serta lokal. Peta sendiri hanya menunjukkan lokasi nilai; statistik spasial diperlukan untuk menilai apakah wilayah dengan nilai serupa cenderung berdekatan. (Moran 1950; Anselin 1995; Bivand, Pebesma, dan Gómez-Rubio 2013; Pebesma dan Bivand 2023)
Setelah pertemuan ini mahasiswa mampu:
sf;Misalkan Jawa Barat dibagi menjadi wilayah administratif. Untuk setiap polygon diamati outcome , misalnya persentase penduduk miskin. Dua wilayah disebut bertetangga bila polygon mereka memenuhi aturan tertentu.
Secara klasik, Queen contiguity menyatakan dua polygon bertetangga bila berbagi sisi atau titik sudut, sedangkan Rook contiguity mensyaratkan sisi bersama. Namun shapefile administratif dapat memiliki overlap, enclave, atau ketidaksempurnaan topologi. Karena itu pada contoh ini bobot utama dibangun dari hubungan intersection antar-polygon:
untuk . Sebagai sensitivity analysis, digunakan bobot kedua berbasis jarak minimum antar-polygon sampai 10 km. Ini tetap merupakan analisis areal karena jarak dihitung dari geometry polygon, bukan mengganti wilayah menjadi data point. Matriks bobot kemudian di-row-standardize:
sehingga spatial lag untuk wilayah adalah rata-rata tertimbang nilai tetangganya:
Definisikan deviasi dari rata-rata . Moran’s adalah
dengan
Secara umum, menunjukkan nilai serupa cenderung berdekatan, menunjukkan pola tetangga yang kontras, dan nilai dekat ekspektasi acak menunjukkan tidak ada autocorrelation yang kuat. Interpretasi tidak boleh hanya berdasarkan tanda; gunakan randomization/permutation inference. (Moran 1950)
Jika adalah Moran’s dari permutasi label wilayah, pseudo p-value dapat dihitung dari proporsi statistik permutasi yang sama atau lebih ekstrem daripada nilai observasi, dengan koreksi Monte Carlo.
Local Moran untuk wilayah dapat ditulis
dengan
Gabungan tanda dan spatial lag menghasilkan empat pola:
LISA bersifat lokal dan melibatkan banyak pengujian. Peta LISA harus dibaca sebagai screening pola lokal, bukan bukti kausal. (Anselin 1995)
Geometry. Folder data/spatial_jabar/ berasal dari ZIP batas administratif yang diberikan untuk mata kuliah. Berkas utama adalah JABAR.shp, JABAR.shx, dan JABAR.dbf. Shapefile tidak menyertakan .prj, sehingga CRS tidak tersimpan secara eksplisit. Koordinat berada pada rentang longitude–latitude Jawa Barat; dalam latihan ini CRS ditetapkan sebagai EPSG:4326 setelah pemeriksaan. Pada riset nyata, CRS wajib diverifikasi pada sumber geodata sebelum penetapan manual.
Outcome. File data/kemiskinan_jabar_2024.csv berisi persentase penduduk miskin 27 kabupaten/kota Jawa Barat tahun 2024 dan disiapkan sebagai teaching extract dari seri BPS/Open Data Jawa Barat. Portal resminya mendokumentasikan variabel kabupaten/kota, persentase penduduk miskin, satuan persen, dan tahun; publikasi BPS Jawa Barat 2019–2024 menjadi rujukan substantif tambahan untuk konteks indikator kemiskinan. (Badan Pusat Statistik dan Pemerintah Provinsi Jawa Barat 2026c; Badan Pusat Statistik Provinsi Jawa Barat 2025)
KABKOTNO, lalu nama tampilan diambil dari tabel kemiskinan. Ini menunjukkan mengapa kode wilayah lebih aman daripada fuzzy matching nama.
jabar13 <- sf::st_read("data/spatial_jabar/JABAR.shp", quiet = TRUE) |>
sf::st_make_valid() |>
dplyr::mutate(KABKOTNO = stringr::str_pad(as.character(KABKOTNO), 2, pad = "0"))
if (is.na(sf::st_crs(jabar13))) {
sf::st_crs(jabar13) <- 4326
}
geom_audit13 <- tibble::tibble(
n_polygon = nrow(jabar13),
crs_epsg = sf::st_crs(jabar13)$epsg,
geometry_valid = sum(sf::st_is_valid(jabar13)),
geometry_invalid = sum(!sf::st_is_valid(jabar13)),
type_polygon = sum(as.character(sf::st_geometry_type(jabar13)) == "POLYGON"),
type_multipolygon = sum(as.character(sf::st_geometry_type(jabar13)) == "MULTIPOLYGON")
)
knitr::kable(geom_audit13, caption = "Audit awal geometri Jawa Barat")| n_polygon | crs_epsg | geometry_valid | geometry_invalid | type_polygon | type_multipolygon |
|---|---|---|---|---|---|
| 27 | 4326 | 27 | 0 | 23 | 4 |
poverty13 <- readr::read_csv("data/kemiskinan_jabar_2024.csv", show_col_types = FALSE) |>
dplyr::mutate(KABKOTNO = stringr::str_pad(as.character(KABKOTNO), 2, pad = "0"))
jabar13 <- jabar13 |>
dplyr::select(KABKOTNO, geometry) |>
dplyr::left_join(poverty13, by = "KABKOTNO")
join_audit13 <- tibble::tibble(
polygon = nrow(jabar13),
outcome_non_missing = sum(!is.na(jabar13$kemiskinan_persen_2024)),
outcome_missing = sum(is.na(jabar13$kemiskinan_persen_2024)),
duplicate_code = sum(duplicated(jabar13$KABKOTNO))
)
knitr::kable(join_audit13, caption = "Audit spatial join geometry dan data kemiskinan")| polygon | outcome_non_missing | outcome_missing | duplicate_code |
|---|---|---|---|
| 27 | 27 | 0 | 0 |
Analisis dilanjutkan hanya jika seluruh 27 polygon memiliki outcome dan tidak ada duplikasi kode.
desc13 <- jabar13 |>
sf::st_drop_geometry() |>
dplyr::summarise(
n = dplyr::n(),
mean = mean(kemiskinan_persen_2024),
median = median(kemiskinan_persen_2024),
sd = sd(kemiskinan_persen_2024),
q1 = quantile(kemiskinan_persen_2024, .25),
q3 = quantile(kemiskinan_persen_2024, .75),
min = min(kemiskinan_persen_2024),
max = max(kemiskinan_persen_2024),
cv = sd / mean
)
knitr::kable(desc13, digits = 2, caption = "Statistik deskriptif persentase penduduk miskin, 2024")| n | mean | median | sd | q1 | q3 | min | max | cv |
|---|---|---|---|---|---|---|---|---|
| 27 | 8.01 | 8.41 | 2.65 | 6.36 | 10.19 | 2.34 | 11.93 | 0.33 |
rank13 <- jabar13 |>
sf::st_drop_geometry() |>
dplyr::arrange(dplyr::desc(kemiskinan_persen_2024)) |>
dplyr::mutate(rank = dplyr::row_number()) |>
dplyr::select(rank, nama_kabupaten_kota, kemiskinan_persen_2024)
knitr::kable(rank13, digits = 2, caption = "Ranking deskriptif kemiskinan kabupaten/kota Jawa Barat, 2024")| rank | nama_kabupaten_kota | kemiskinan_persen_2024 |
|---|---|---|
| 1 | KABUPATEN INDRAMAYU | 11.93 |
| 2 | KABUPATEN KUNINGAN | 11.88 |
| 3 | KOTA TASIKMALAYA | 11.10 |
| 4 | KABUPATEN CIREBON | 11.00 |
| 5 | KABUPATEN MAJALENGKA | 10.82 |
| 6 | KABUPATEN BANDUNG BARAT | 10.49 |
| 7 | KABUPATEN TASIKMALAYA | 10.23 |
| 8 | KABUPATEN CIANJUR | 10.14 |
| 9 | KABUPATEN GARUT | 9.68 |
| 10 | KABUPATEN SUBANG | 9.49 |
| 11 | KABUPATEN SUMEDANG | 9.10 |
| 12 | KOTA CIREBON | 9.02 |
| 13 | KABUPATEN PANGANDARAN | 8.75 |
| 14 | KABUPATEN PURWAKARTA | 8.41 |
| 15 | KABUPATEN KARAWANG | 7.86 |
| 16 | KABUPATEN CIAMIS | 7.39 |
| 17 | KOTA SUKABUMI | 7.20 |
| 18 | KABUPATEN BOGOR | 7.05 |
| 19 | KABUPATEN SUKABUMI | 6.87 |
| 20 | KOTA BOGOR | 6.53 |
| 21 | KABUPATEN BANDUNG | 6.19 |
| 22 | KOTA BANJAR | 5.85 |
| 23 | KABUPATEN BEKASI | 4.80 |
| 24 | KOTA CIMAHI | 4.39 |
| 25 | KOTA BEKASI | 4.01 |
| 26 | KOTA BANDUNG | 3.87 |
| 27 | KOTA DEPOK | 2.34 |
Ranking hanya deskriptif. Ia belum mempertimbangkan ukuran populasi, kedalaman kemiskinan, kerentanan, atau hubungan spasial.
ggplot2::ggplot(sf::st_drop_geometry(jabar13), ggplot2::aes(kemiskinan_persen_2024)) +
ggplot2::geom_histogram(bins = 8, boundary = 0) +
ggplot2::geom_vline(xintercept = mean(jabar13$kemiskinan_persen_2024), linetype = 2) +
ggplot2::labs(title = "Distribusi persentase penduduk miskin antarkabupaten/kota", x = "Penduduk miskin (%)", y = "Jumlah wilayah")ggplot2::ggplot(jabar13) +
ggplot2::geom_sf(ggplot2::aes(fill = kemiskinan_persen_2024), colour = "white", linewidth = .25) +
ggplot2::scale_fill_viridis_c(option = "C", direction = -1) +
ggplot2::labs(title = "Persentase Penduduk Miskin Kabupaten/Kota Jawa Barat, 2024", fill = "Kemiskinan (%)", caption = "Sumber indikator: BPS/Open Data Jawa Barat; batas wilayah: berkas polygon mata kuliah") +
ggplot2::theme_void() +
ggplot2::theme(plot.title = ggplot2::element_text(face = "bold"), plot.caption = ggplot2::element_text(hjust = 0))Choropleth menampilkan rate, bukan jumlah absolut. Ini penting karena polygon luas atau berpenduduk besar tidak otomatis memiliki tingkat kemiskinan tinggi.
# Bobot utama: polygon saling beririsan/bersinggungan (intersection adjacency).
rel_inter13 <- sf::st_intersects(jabar13)
n13 <- nrow(jabar13)
W_inter13 <- matrix(0, n13, n13)
for (i in seq_len(n13)) {
jj <- setdiff(rel_inter13[[i]], i)
if (length(jj) > 0) W_inter13[i, jj] <- 1
}
# Bobot alternatif: jarak minimum antar-polygon <= 10 km.
jabar13_m <- sf::st_transform(jabar13, 32748)
D13 <- units::drop_units(sf::st_distance(jabar13_m))
diag(D13) <- Inf
W_10km13 <- 1L * (D13 <= 10000)
diag(W_10km13) <- 0L
neighbor_tbl13 <- tibble::tibble(
nama_kabupaten_kota = jabar13$nama_kabupaten_kota,
intersection_neighbors = rowSums(W_inter13),
neighbors_within_10km = rowSums(W_10km13)
)
knitr::kable(neighbor_tbl13, caption = "Jumlah tetangga areal: intersection dan proximity 10 km")| nama_kabupaten_kota | intersection_neighbors | neighbors_within_10km |
|---|---|---|
| KABUPATEN BOGOR | 8 | 8 |
| KABUPATEN SUKABUMI | 3 | 4 |
| KABUPATEN CIANJUR | 6 | 8 |
| KABUPATEN BANDUNG | 7 | 7 |
| KABUPATEN GARUT | 4 | 6 |
| KABUPATEN TASIKMALAYA | 6 | 7 |
| KABUPATEN CIAMIS | 6 | 8 |
| KABUPATEN KUNINGAN | 3 | 4 |
| KABUPATEN CIREBON | 4 | 4 |
| KABUPATEN MAJALENGKA | 6 | 7 |
| KABUPATEN SUMEDANG | 6 | 9 |
| KABUPATEN INDRAMAYU | 4 | 4 |
| KABUPATEN SUBANG | 6 | 8 |
| KABUPATEN PURWAKARTA | 5 | 8 |
| KABUPATEN KARAWANG | 4 | 5 |
| KABUPATEN BEKASI | 3 | 5 |
| KABUPATEN BANDUNG BARAT | 6 | 7 |
| KABUPATEN PANGANDARAN | 2 | 3 |
| KOTA BOGOR | 1 | 3 |
| KOTA SUKABUMI | 1 | 2 |
| KOTA BANDUNG | 3 | 6 |
| KOTA CIREBON | 1 | 2 |
| KOTA BEKASI | 3 | 3 |
| KOTA DEPOK | 2 | 4 |
| KOTA CIMAHI | 3 | 5 |
| KOTA TASIKMALAYA | 2 | 2 |
| KOTA BANJAR | 1 | 3 |
ggplot2::ggplot(neighbor_tbl13, ggplot2::aes(reorder(nama_kabupaten_kota, intersection_neighbors), intersection_neighbors)) +
ggplot2::geom_col() +
ggplot2::coord_flip() +
ggplot2::labs(title = "Jumlah tetangga berdasarkan intersection polygon", x = NULL, y = "Jumlah tetangga")Perbedaan degree menunjukkan bahwa setiap wilayah memiliki jumlah tetangga berbeda. Row-standardization mencegah wilayah dengan banyak tetangga secara otomatis memiliki spatial lag yang lebih besar hanya karena jumlah koneksi.
lw_inter13 <- spdep::mat2listw(W_inter13, style = "W", zero.policy = TRUE)
y13 <- jabar13$kemiskinan_persen_2024
moran_test13 <- spdep::moran.test(y13, lw_inter13, zero.policy = TRUE, randomisation = TRUE)
set.seed(260813)
moran_mc13 <- spdep::moran.mc(y13, lw_inter13, nsim = 999, zero.policy = TRUE)
moran_out13 <- tibble::tibble(
statistic = "Moran's I — polygon intersection",
I_observed = unname(moran_test13$estimate[[1]]),
expectation = unname(moran_test13$estimate[[2]]),
variance = unname(moran_test13$estimate[[3]]),
p_asymptotic = moran_test13$p.value,
p_permutation = moran_mc13$p.value
)
knitr::kable(moran_out13, digits = 4, caption = "Autocorrelation global kemiskinan Jawa Barat")| statistic | I_observed | expectation | variance | p_asymptotic | p_permutation |
|---|---|---|---|---|---|
| Moran’s I — polygon intersection | 0.4776 | -0.0385 | 0.0199 | 0.0001 | 0.001 |
P-value permutation lebih sesuai untuk pembelajaran karena secara eksplisit membandingkan pola observasi dengan distribusi acak hasil pengacakan label wilayah.
z13 <- as.numeric(scale(y13))
lag_z13 <- spdep::lag.listw(lw_inter13, z13, zero.policy = TRUE)
scatter13 <- tibble::tibble(
wilayah = jabar13$nama_kabupaten_kota,
z = z13,
spatial_lag_z = lag_z13
)
ggplot2::ggplot(scatter13, ggplot2::aes(z, spatial_lag_z)) +
ggplot2::geom_hline(yintercept = 0, linetype = 2) +
ggplot2::geom_vline(xintercept = 0, linetype = 2) +
ggplot2::geom_smooth(method = "lm", se = FALSE) +
ggplot2::geom_point(size = 2.6) +
ggplot2::labs(title = "Moran scatterplot kemiskinan 2024", x = "Kemiskinan terstandardisasi (z)", y = "Spatial lag z")Kuadran kanan-atas dan kiri-bawah merepresentasikan kemiripan lokal (high–high dan low–low), sedangkan dua kuadran lainnya menandai kontras lokal.
local13 <- spdep::localmoran(y13, lw_inter13, zero.policy = TRUE)
jabar13$Ii <- local13[, "Ii"]
jabar13$Z_Ii <- local13[, "Z.Ii"]
pcol13 <- grep("^Pr", colnames(local13), value = TRUE)[1]
jabar13$p_local <- local13[, pcol13]
jabar13$z <- z13
jabar13$lag_z <- lag_z13
jabar13$quadrant <- dplyr::case_when(
jabar13$z >= 0 & jabar13$lag_z >= 0 ~ "High–High",
jabar13$z < 0 & jabar13$lag_z < 0 ~ "Low–Low",
jabar13$z >= 0 & jabar13$lag_z < 0 ~ "High–Low",
TRUE ~ "Low–High"
)
jabar13$lisa_class <- ifelse(jabar13$p_local <= .05, jabar13$quadrant, "Tidak signifikan")
local_tbl13 <- jabar13 |>
sf::st_drop_geometry() |>
dplyr::select(nama_kabupaten_kota, kemiskinan_persen_2024, Ii, Z_Ii, p_local, lisa_class) |>
dplyr::arrange(p_local)
knitr::kable(local_tbl13, digits = 4, caption = "Local Moran dan klasifikasi LISA")| nama_kabupaten_kota | kemiskinan_persen_2024 | Ii | Z_Ii | p_local | lisa_class |
|---|---|---|---|---|---|
| KABUPATEN CIREBON | 11.00 | 1.2809 | 2.4893 | 0.0128 | High–High |
| KABUPATEN MAJALENGKA | 10.82 | 0.9306 | 2.4846 | 0.0130 | High–High |
| KOTA BEKASI | 4.01 | 1.9470 | 2.4593 | 0.0139 | Low–Low |
| KABUPATEN BOGOR | 7.05 | 0.2348 | 2.1219 | 0.0338 | Low–Low |
| KABUPATEN INDRAMAYU | 11.93 | 1.2103 | 1.8862 | 0.0593 | Tidak signifikan |
| KABUPATEN SUMEDANG | 9.10 | 0.2746 | 1.8163 | 0.0693 | Tidak signifikan |
| KABUPATEN CIAMIS | 7.39 | -0.1624 | -1.7941 | 0.0728 | Tidak signifikan |
| KOTA DEPOK | 2.34 | 2.0870 | 1.6298 | 0.1031 | Tidak signifikan |
| KABUPATEN TASIKMALAYA | 10.23 | 0.4785 | 1.6194 | 0.1054 | Tidak signifikan |
| KABUPATEN KUNINGAN | 11.88 | 0.9855 | 1.3336 | 0.1823 | Tidak signifikan |
| KABUPATEN BEKASI | 4.80 | 0.8127 | 1.2871 | 0.1981 | Tidak signifikan |
| KOTA CIREBON | 9.02 | 0.4444 | 1.1451 | 0.2522 | Tidak signifikan |
| KABUPATEN SUBANG | 9.49 | 0.2146 | 1.0810 | 0.2797 | Tidak signifikan |
| KABUPATEN PURWAKARTA | 8.41 | 0.0581 | 0.9278 | 0.3535 | Tidak signifikan |
| KOTA CIMAHI | 4.39 | 0.6248 | 0.9242 | 0.3554 | Tidak signifikan |
| KABUPATEN BANDUNG BARAT | 10.49 | -0.3418 | -0.8816 | 0.3780 | Tidak signifikan |
| KOTA BANDUNG | 3.87 | 0.6081 | 0.8258 | 0.4089 | Tidak signifikan |
| KABUPATEN GARUT | 9.68 | 0.2220 | 0.7827 | 0.4338 | Tidak signifikan |
| KOTA TASIKMALAYA | 11.10 | 0.3634 | 0.5123 | 0.6084 | Tidak signifikan |
| KABUPATEN KARAWANG | 7.86 | 0.0132 | 0.4692 | 0.6389 | Tidak signifikan |
| KABUPATEN PANGANDARAN | 8.75 | 0.0866 | 0.4497 | 0.6530 | Tidak signifikan |
| KOTA SUKABUMI | 7.20 | 0.1380 | 0.4448 | 0.6565 | Tidak signifikan |
| KOTA BOGOR | 6.53 | 0.2119 | 0.3881 | 0.6979 | Tidak signifikan |
| KOTA BANJAR | 5.85 | 0.2001 | 0.2708 | 0.7865 | Tidak signifikan |
| KABUPATEN CIANJUR | 10.14 | 0.0316 | 0.1910 | 0.8485 | Tidak signifikan |
| KABUPATEN BANDUNG | 6.19 | -0.0409 | -0.0938 | 0.9253 | Tidak signifikan |
| KABUPATEN SUKABUMI | 6.87 | -0.0196 | -0.0490 | 0.9610 | Tidak signifikan |
ggplot2::ggplot(jabar13) +
ggplot2::geom_sf(ggplot2::aes(fill = lisa_class), colour = "white", linewidth = .25) +
ggplot2::labs(title = "Peta Local Moran (LISA) kemiskinan Jawa Barat, 2024", fill = "LISA class", caption = "p lokal ≤ 0,05 ditampilkan sebagai pola lokal; interpretasi bersifat screening") +
ggplot2::theme_void() +
ggplot2::theme(plot.title = ggplot2::element_text(face = "bold"), plot.caption = ggplot2::element_text(hjust = 0))lw_10km13 <- spdep::mat2listw(W_10km13, style = "W", zero.policy = TRUE)
set.seed(260813)
mc_inter13 <- spdep::moran.mc(y13, lw_inter13, nsim = 999, zero.policy = TRUE)
set.seed(260813)
mc_10km13 <- spdep::moran.mc(y13, lw_10km13, nsim = 999, zero.policy = TRUE)
sens13 <- tibble::tibble(
neighborhood = c("Polygon intersection", "Polygon distance <= 10 km"),
Moran_I = c(unname(mc_inter13$statistic), unname(mc_10km13$statistic)),
p_permutation = c(mc_inter13$p.value, mc_10km13$p.value),
mean_neighbors = c(mean(rowSums(W_inter13)), mean(rowSums(W_10km13)))
)
knitr::kable(sens13, digits = 4, caption = "Sensitivity Moran's I terhadap definisi neighborhood areal")| neighborhood | Moran_I | p_permutation | mean_neighbors |
|---|---|---|---|
| Polygon intersection | 0.4776 | 0.001 | 3.9259 |
| Polygon distance <= 10 km | 0.4060 | 0.001 | 5.2593 |
Jika tanda, magnitude, atau kesimpulan inferensial berubah drastis antara intersection adjacency dan proximity 10 km, hasil harus dilaporkan sebagai sensitif terhadap definisi konektivitas. Neighborhood seharusnya mewakili mekanisme regional yang masuk akal; adjacency administratif belum tentu cocok untuk mobilitas komuter, perdagangan, DAS, atau jaringan transportasi.
pal13 <- leaflet::colorNumeric("YlOrRd", domain = jabar13$kemiskinan_persen_2024)
leaflet::leaflet(jabar13) |>
leaflet::addProviderTiles("CartoDB.Positron") |>
leaflet::addPolygons(
fillColor = ~pal13(kemiskinan_persen_2024),
fillOpacity = .75,
weight = .8,
color = "white",
popup = ~paste0(
"<b>", nama_kabupaten_kota, "</b><br>",
"Kemiskinan 2024: ", round(kemiskinan_persen_2024, 2), "%<br>",
"LISA: ", lisa_class
)
) |>
leaflet::addLegend(pal = pal13, values = ~kemiskinan_persen_2024, title = "Kemiskinan (%)")Analisis areal mengubah pertanyaan dari “kabupaten mana paling tinggi?” menjadi “apakah kabupaten dengan kemiskinan tinggi berada dalam lingkungan regional yang juga memiliki nilai tinggi?”. Jika terdapat pola High–High, intervensi lintas batas dapat dipertimbangkan karena akses pekerjaan, transportasi, pasar, dan layanan publik tidak berhenti di garis administrasi. Sebaliknya, High–Low dapat menunjukkan wilayah yang berbeda tajam dari tetangganya dan layak ditelaah sebagai kasus khusus.
Namun spatial autocorrelation tidak menjelaskan penyebab. Pola dapat muncul karena struktur ekonomi yang mirip, topografi, aksesibilitas, urbanisasi, kebijakan historis, atau proses pengukuran. Untuk membuat klaim mekanisme diperlukan variabel tambahan dan model yang sesuai.
Modifiable Areal Unit Problem (MAUP) berarti hasil statistik dapat berubah bila batas atau tingkat agregasi wilayah diubah. Kabupaten/kota adalah satu pilihan agregasi administratif, bukan satu-satunya representasi proses sosial-ekonomi.
Ecological fallacy terjadi jika hubungan pada tingkat kabupaten langsung diterapkan kepada individu. Misalnya, kabupaten dengan kemiskinan tinggi tidak berarti setiap rumah tangga di kabupaten itu miskin, dan asosiasi antara internet dan kemiskinan antarkabupaten tidak sama dengan hubungan pada rumah tangga. (Pebesma dan Bivand 2023; Lovelace, Nowosad, dan Muenchow 2025)
Gunakan polygon Jawa Barat dan outcome regional dari BPS/Open Data Jabar. Tampilkan audit geometry, audit join, statistik deskriptif, ranking, choropleth, degree neighborhood, Moran’s I + permutation test, Moran scatterplot, Local Moran/LISA map, dan sensitivity intersection vs proximity polygon. Akhiri dengan memo 300–400 kata yang memisahkan temuan deskriptif, temuan spasial, hipotesis mekanisme, dan rekomendasi data lanjutan.
Jika capstone menggunakan unit wilayah, tim harus memutuskan apakah geografi hanya untuk visualisasi atau merupakan bagian dari mekanisme analitik. Bila struktur spasial relevan, minimal lakukan audit neighborhood dan satu sensitivity analysis. Peta tidak boleh menjadi dekorasi; ia harus menjawab pertanyaan substantif.
Regional data science membutuhkan areal thinking. Untuk indikator kabupaten/kota, polygon, neighborhood, spatial lag, global Moran, dan Local Moran memberi kerangka yang lebih tepat daripada sekadar plot titik. Analisis tetap harus menjaga batas inferensi: pola spasial adalah evidence tentang struktur, bukan otomatis evidence tentang sebab.
Model terbaik bukan selalu model dengan metric agregat paling kecil. Keputusan regional membutuhkan evaluasi robustness, uncertainty, subgroup performance, fairness, dan konsekuensi operasional. Model card adalah salah satu cara mendokumentasikan intended use, metric, keterbatasan, dan kelompok kinerja. (Mitchell dkk. 2019)
Mahasiswa mampu membandingkan model pada metric yang relevan, menganalisis residual/subgroup, melakukan sensitivity analysis sederhana, dan menyusun model card.
Robustness adalah kestabilan kesimpulan terhadap perubahan data/model yang wajar. Fairness di konteks regional berarti memeriksa apakah error sistematis lebih besar pada kelompok wilayah tertentu. Hal ini bukan sekadar masalah teknis; definisi fairness terkait tujuan program.
Perbedaan error antargrup:
Coverage interval prediksi:
dengan interval prediksi. Coverage nominal 95% idealnya mendekati 0,95 pada data yang relevan.
Jika adalah nilai metrik model pada resample , rata-rata dan standard error resampling: Selisih kecil dibanding variability resampling tidak layak diperlakukan sebagai bukti bahwa satu model “pasti terbaik”. Pertimbangkan kesederhanaan, interpretability, latency, fairness, dan data requirements. (Kuhn dan Silge 2022)
Ambil bootstrap samples dan hitung statistic . Bootstrap standard error: Bootstrap dapat diterapkan pada koefisien, ranking, atau metrik model, dengan resampling scheme yang menghormati struktur panel/spasial jika diperlukan.
Jika dan adalah ranking wilayah di dua skenario bobot/model, Spearman rank correlation: Jika daftar “10 wilayah prioritas” berubah drastis karena sedikit perubahan bobot, rekomendasi harus dilaporkan sebagai tidak stabil.
Untuk protected/context group :
Demographic parity difference
Equal opportunity difference
Tidak ada satu fairness metric yang selalu tepat; kriteria dapat saling bertentangan dan konteks hukum/etik menentukan apa yang relevan. Dalam regional policy, group dapat berupa urban/rural, pulau/kawasan, atau kategori kapasitas fiskal—tetapi penggunaan kategori harus punya dasar substantif dan tidak menstigmatisasi. (Hardt, Price, dan Srebro 2016)
Jika benefit intervensi dan cost berbeda, net benefit pada threshold dapat ditulis secara sederhana: Rumus berasal dari decision-analytic framing tertentu dan tidak otomatis berlaku untuk semua kebijakan; gunakan sebagai contoh bahwa threshold harus dihubungkan dengan trade-off keputusan.
Jika ada treated group dan control , sebelum () dan sesudah (), estimand DID: Regresi: Interpretasi kausal membutuhkan asumsi parallel trends dan desain yang kredibel. DID dimasukkan untuk menunjukkan perbedaan antara “memprediksi outcome” dan “mengevaluasi apakah kebijakan menyebabkan perubahan”. (Callaway dan Sant’Anna 2021; Hernán dan Robins 2020)
Model yang rata-rata bagus bisa buruk untuk daerah berpenduduk kecil atau data terbatas. Jika model digunakan untuk alokasi bantuan, error tidak merata dapat memperkuat ketimpangan.
Model A RMSE fold: 2.1,2.2,2.0,2.4,2.3 → mean 2.20. Model B: 2.05,2.18,1.98,2.36,2.28 → mean 2.17. Selisih 0.03 sangat kecil dibanding variasi antar-fold. Menyebut B “jauh lebih baik” tidak didukung. Pertimbangkan paired resample differences dan simplicity.
Untuk setiap bootstrap , hitung score/ranking wilayah. Untuk wilayah , laporkan median rank dan interval percentile: Jika wilayah ranking 8 memiliki interval 3–19, penetapan cut-off “top 10” harus hati-hati.
Group urban: TPR=0.90; rural: TPR=0.65. Equal opportunity difference urban–rural=0.25. Ini memberi sinyal model lebih sering melewatkan prioritas rural. Penyebab dapat berasal dari data quality, feature availability, label process, atau heterogeneity; fairness diagnostic bukan diagnosis penyebab.
Treated outcome: pre 60, post 75 → +15. Control: pre 58, post 65 → +7. Interpretasi kausal memerlukan parallel trends dan tidak adanya perubahan berbeda lain yang confound treatment timing. Uji/plot pre-trends penting, dan modern DID perlu memperhatikan staggered adoption. (Callaway dan Sant’Anna 2021)
| Analytic choice | Base | Alternative | Result stable? |
|---|---|---|---|
| weights index | 0.5/0.3/0.2 | equal weights | yes/no |
| split | temporal | grouped region | yes/no |
| model | RF | ridge/logit | yes/no |
| W spatial | queen | kNN | yes/no |
| missing | complete case | imputation/sensitivity | yes/no |
Capstone harus menyimpulkan bukan hanya “hasil”, tetapi set of results that survive reasonable alternatives.
Bedakan: 1. sampling uncertainty; 2. measurement error; 3. model uncertainty; 4. hyperparameter uncertainty; 5. scenario/weight uncertainty; 6. structural uncertainty tentang mekanisme regional.
CI koefisien hanya menangkap sebagian dari daftar tersebut. Kebijakan berbasis data harus menghindari false precision.
panel <- read_csv("data/simulasi_panel_regional.csv", show_col_types = FALSE)
train <- panel |> filter(tahun <= 2023)
test <- panel |> filter(tahun >= 2024)
fit <- lm(kemiskinan_persen ~ pdrb_perkapita_juta + tpt_persen + internet_persen + ipm, data = train)
ev <- test |> mutate(pred = predict(fit, newdata = test), abs_err = abs(kemiskinan_persen-pred))
ev |>
group_by(urban) |>
summarise(n=n(), MAE=mean(abs_err), RMSE=sqrt(mean((kemiskinan_persen-pred)^2))) |>
knitr::kable(digits=3, caption="Kinerja model menurut tipe wilayah - simulasi")| urban | n | MAE | RMSE |
|---|---|---|---|
| 0 | 22 | 1.343 | 1.611 |
| 1 | 32 | 0.927 | 1.259 |
Pada INDO-DAPOER atau Open Data Jabar, subgroup dapat dibentuk dari status kota/kabupaten, quantile populasi, zona geografis, atau kategori berbasis teori. Hindari menciptakan subgroup kecil yang membuat metric sangat tidak stabil.
Kartu dataset real.
# Sensitivitas ranking prioritas terhadap bobot indikator.
latest <- panel |> filter(tahun == 2025)
rank_a <- latest |>
mutate(score = .6*as.numeric(scale(kemiskinan_persen)) + .4*as.numeric(scale(tpt_persen))) |>
arrange(desc(score)) |>
mutate(rank_a = row_number())
rank_b <- latest |>
mutate(score = .4*as.numeric(scale(kemiskinan_persen)) + .3*as.numeric(scale(tpt_persen)) - .3*as.numeric(scale(ipm))) |>
arrange(desc(score)) |>
mutate(rank_b = row_number())
left_join(rank_a |> select(wilayah, rank_a), rank_b |> select(wilayah, rank_b), by="wilayah") |>
mutate(delta_rank = rank_b-rank_a) |>
arrange(desc(abs(delta_rank))) |>
head(10) |>
knitr::kable()| wilayah | rank_a | rank_b | delta_rank |
|---|---|---|---|
| Wilayah_21 | 15 | 3 | -12 |
| Wilayah_14 | 11 | 22 | 11 |
| Wilayah_27 | 17 | 9 | -8 |
| Wilayah_26 | 5 | 11 | 6 |
| Wilayah_25 | 13 | 19 | 6 |
| Wilayah_24 | 8 | 13 | 5 |
| Wilayah_07 | 1 | 5 | 4 |
| Wilayah_01 | 19 | 15 | -4 |
| Wilayah_10 | 21 | 25 | 4 |
| Wilayah_08 | 24 | 20 | -4 |
d14 <- readr::read_csv("data/simulasi_panel_regional.csv", show_col_types=FALSE) |>
dplyr::filter(tahun==2025)
set.seed(260814)
s14 <- rsample::initial_split(d14, prop=.8)
tr14 <- rsample::training(s14); te14 <- rsample::testing(s14)
lm14 <- stats::lm(kemiskinan_persen ~ pdrb_perkapita_juta+tpt_persen+ipm+internet_persen+umkm_per_1000, data=tr14)
rf14 <- ranger::ranger(kemiskinan_persen ~ pdrb_perkapita_juta+tpt_persen+ipm+internet_persen+umkm_per_1000, data=tr14, num.trees=500, seed=260814)
pred14 <- dplyr::bind_rows(
tibble::tibble(actual=te14$kemiskinan_persen, pred=predict(lm14,newdata=te14), model="Linear"),
tibble::tibble(actual=te14$kemiskinan_persen, pred=predict(rf14,data=te14)$predictions, model="Random forest")
) |> dplyr::mutate(error=pred-actual)
metric14 <- pred14 |> dplyr::group_by(model) |>
dplyr::summarise(RMSE=sqrt(mean(error^2)), MAE=mean(abs(error)), Bias=mean(error), P90_AbsError=quantile(abs(error),.90), .groups="drop")
knitr::kable(metric14, digits=3, caption="Perbandingan metric utama dan tail error")| model | RMSE | MAE | Bias | P90_AbsError |
|---|---|---|---|---|
| Linear | 1.171 | 1.032 | -0.993 | 1.626 |
| Random forest | 0.954 | 0.821 | -0.800 | 1.349 |
ggplot2::ggplot(pred14, ggplot2::aes(error, fill=model)) +
ggplot2::geom_density(alpha=.35) + ggplot2::geom_vline(xintercept=0,linetype=2) +
ggplot2::labs(title="Distribusi error holdout", x="Prediction error", fill="Model")worst14 <- pred14 |> dplyr::group_by(model) |> dplyr::slice_max(abs(error), n=5, with_ties=FALSE) |> dplyr::ungroup()
knitr::kable(worst14, digits=3, caption="Lima error absolut terbesar per model")| actual | pred | model | error |
|---|---|---|---|
| 11.637 | 9.856 | Linear | -1.781 |
| 10.966 | 9.495 | Linear | -1.471 |
| 10.098 | 8.929 | Linear | -1.169 |
| 11.810 | 10.715 | Linear | -1.095 |
| 9.444 | 8.887 | Linear | -0.557 |
| 11.637 | 9.994 | Random forest | -1.643 |
| 10.966 | 9.911 | Random forest | -1.055 |
| 9.444 | 8.495 | Random forest | -0.949 |
| 11.810 | 11.166 | Random forest | -0.644 |
| 10.098 | 9.528 | Random forest | -0.570 |
Jika prioritas berubah drastis hanya karena bobot sedikit berubah, sistem ranking rapuh. Kebijakan sebaiknya menampilkan tier atau range, bukan ranking presisi 1-27 yang memberi kesan kepastian palsu.
Lakukan robustness audit capstone: minimal dua skenario bobot/fitur, satu alternatif resampling/model, satu fairness slice, dan satu uncertainty summary. Buat tabel “temuan yang stabil” vs “temuan yang sensitif”.
Kisi-kisi: k-means objective; silhouette; PCA; Moran’s I; spatial weights; bootstrap SE; rank stability; fairness metric; calibration; prediction vs policy evaluation; DID intuition.
Milestone evaluasi: tim menyertakan tabel comparison, subgroup check, sensitivity analysis, dan model card 1 halaman.
Evaluasi model adalah evaluasi risiko keputusan. Metric agregat harus dilengkapi robustness, subgroup performance, uncertainty, dan keterbatasan penggunaan.
Tahap akhir analisis adalah mengubah bukti menjadi opsi kebijakan. Rekomendasi yang baik menunjukkan evidence chain: masalah → data → hasil → ketidakpastian → opsi → konsekuensi. Generative AI dapat mempercepat coding dan dokumentasi, tetapi juga dapat menghasilkan kode salah, referensi fiktif, atau interpretasi terlalu percaya diri. (Miao dan Holmes 2023; Tabassi 2023)
Mahasiswa mampu menyusun policy insight, membedakan temuan dan rekomendasi, membuat dashboard ringkas, menggunakan GenAI secara transparan, dan mendokumentasikan verifikasi.
Evidence-based policy bukan berarti keputusan dibuat oleh model. Bukti adalah input bersama nilai publik, hukum, anggaran, political feasibility, local knowledge, dan equity. AI berperan sebagai assistant, bukan otoritas epistemik.
Penggunaan GenAI yang diperbolehkan: menjelaskan dokumentasi package, menghasilkan skeleton kode, debugging, membuat alternatif visual, merapikan dokumentasi, dan brainstorming interpretasi awal. Kewajiban mahasiswa: memeriksa kode, memvalidasi output, membaca sumber asli, menguji asumsi, menghapus data sensitif, dan mendeklarasikan penggunaan AI.
Untuk keputusan berbasis expected loss, secara konseptual pilih tindakan yang meminimalkan
di mana adalah loss dari tindakan ketika keadaan sebenarnya , dan adalah bukti/data. Formula ini menekankan bahwa keputusan bergantung pada loss/konsekuensi, bukan hanya prediksi.
Jika kebijakan mempertimbangkan kriteria, score sederhana: Tetapi jika model menghasilkan risk probability , score kebijakan dapat menggabungkan risiko dan feasibility: dengan feasibility dan equity score. Persamaan ini bukan resep universal; tujuannya memperlihatkan bahwa transisi model→policy memerlukan pilihan eksplisit yang dapat diaudit.
Jika intervensi , benefit ekspektasian , biaya , anggaran : Ini adalah bentuk knapsack/optimization sederhana. Model prediksi dapat membantu memperkirakan atau risiko, tetapi alokasi akhir tetap constrained decision problem.
Jika dashboard menampilkan KPI, setiap KPI harus memiliki definisi matematis. Misalnya coverage:
Change vs target:
Percent target achievement (untuk target positif): Hindari persentase bila denominator nol/tidak stabil. Dashboard harus menampilkan sumber, periode, update time, dan status data.
Setiap keluaran AI yang memengaruhi analisis melewati empat lapis verifikasi:
di mana setiap pada checklist minimum. Jika salah satu nol, artefak belum layak dipakai. Ini bukan probabilistic score, tetapi process-control device.
UNESCO menekankan pendekatan human-centred dan validasi etis-pedagogis untuk GenAI; NIST AI RMF mendorong governance, mapping, measurement, dan management risiko AI. (Miao dan Holmes 2023; Tabassi 2023; Autio dkk. 2024)
Untuk setiap project, simpan tabel:
| Elemen | Isi minimum |
|---|---|
| Tool/model | nama layanan/model bila diketahui |
| Tanggal | kapan digunakan |
| Tujuan | dokumentasi, debugging, ide visualisasi, dsb. |
| Prompt category | ringkasan, bukan data sensitif mentah |
| Output used | bagian apa yang benar-benar digunakan |
| Verification | bagaimana kode/sumber/hasil diverifikasi |
| Human revision | perubahan substansial yang dilakukan mahasiswa |
Data personal, data rahasia, atau data dengan pembatasan lisensi tidak boleh ditempelkan ke layanan AI publik tanpa dasar dan izin yang sesuai.
Analisis yang reproducible dapat dipandang sebagai fungsi
Jika salah satu komponen tidak tersedia atau berubah tanpa dokumentasi, output tidak dapat diaudit. Catat sessionInfo(), seed, package versions, sumber data, dan semua parameter preprocessing/model.
Model dapat memberi probabilitas desa rentan 0,72. Kebijakan tetap harus menjawab: kapasitas verifikasi berapa, biaya salah sasaran berapa, data apa yang sensitif, siapa yang dapat mengajukan koreksi, dan kapan model ditinjau ulang.
Empat wilayah memiliki expected benefit dan cost juta; budget 50. Memilih dua benefit terbesar A+B membutuhkan 50 dan benefit 90. Kombinasi A+D cost 40 benefit 80; B+C cost 40 benefit 75; B+C+D cost 50 benefit 105. Maka ranking benefit individual tidak cukup; constraint menghasilkan portfolio berbeda.
Ini memperjelas transisi dari risk prediction ke decision optimization. Model dapat menghasilkan risk/benefit estimate, tetapi resource allocation membutuhkan fungsi objective dan constraints.
Gunakan lima tingkat klaim:
Jangan melompat dari tingkat 1–3 langsung ke 5 tanpa penjelasan tambahan.
Dashboard kebijakan sebaiknya memiliki empat layer: overview → comparison → drill-down → methodology. Overview menampilkan 3–5 KPI; comparison memungkinkan lintas wilayah/waktu; drill-down menampilkan profile; methodology menjelaskan source, formula, update, dan limitation.
Jika data terakhir tahun dan dashboard dibuka tahun , lag: KPI dengan lag besar harus diberi badge “historical”/“latest available”, bukan ditampilkan seolah real-time. INDO-DAPOER berhenti 2018 sehingga cocok untuk latihan historis dan bukan kondisi terkini. (World Bank 2026)
AI menyarankan scale() sebelum split. Mahasiswa harus mengoreksi karena leakage. AI mengutip dataset “BPS Innovation Index 2025” yang tidak ditemukan: source verification gagal. AI menulis interpretasi “internet menurunkan kemiskinan”: interpretation verification gagal karena model hanya asosiasional. Contoh ini menunjukkan kode yang syntactically plausible tetap dapat salah secara ilmiah.
ai_log <- tibble::tribble(
~tanggal, ~tool, ~tujuan, ~output_used, ~verification,
"2026-09-15", "Generative AI", "debug join", "saran anti_join", "dicek pada toy data dan dokumentasi dplyr",
"2026-10-01", "Generative AI", "draft caption", "struktur caption", "angka dan klaim diverifikasi dari output sendiri"
)
knitr::kable(ai_log, caption="Contoh AI-use log")| tanggal | tool | tujuan | output_used | verification |
|---|---|---|---|---|
| 2026-09-15 | Generative AI | debug join | saran anti_join | dicek pada toy data dan dokumentasi dplyr |
| 2026-10-01 | Generative AI | draft caption | struktur caption | angka dan klaim diverifikasi dari output sendiri |
Setiap recommendation harus bisa ditelusuri ke evidence. Gunakan format: Temuan → interpretasi → opsi → rekomendasi → indikator monitoring → caveat. Jika satu rekomendasi tidak memiliki evidence chain, hapus atau ubah menjadi hipotesis untuk penelitian berikutnya.
latest <- read_csv("data/simulasi_panel_regional.csv", show_col_types = FALSE) |>
filter(tahun == 2025) |>
mutate(
prioritas = case_when(
kemiskinan_persen >= quantile(kemiskinan_persen,.75) & internet_persen < median(internet_persen) ~ "Inklusi digital + perlindungan sosial",
tpt_persen >= quantile(tpt_persen,.75) & pdrb_perkapita_juta > median(pdrb_perkapita_juta) ~ "Matching tenaga kerja-industri",
TRUE ~ "Monitoring / intervensi sektoral"
)
)
latest |> count(prioritas) |> knitr::kable(caption="Contoh penerjemahan pola menjadi opsi intervensi - simulasi")| prioritas | n |
|---|---|
| Inklusi digital + perlindungan sosial | 7 |
| Matching tenaga kerja-industri | 5 |
| Monitoring / intervensi sektoral | 15 |
latest |>
dplyr::count(prioritas) |>
ggplot2::ggplot(ggplot2::aes(reorder(prioritas, n), n)) +
ggplot2::geom_col(fill = "#145B8C") +
ggplot2::coord_flip() +
ggplot2::labs(title = "Distribusi opsi intervensi — simulasi", x = NULL, y = "Jumlah wilayah")Untuk dashboard Jawa Barat, sumber data dapat berasal dari Open Data Jabar/BPS; dashboard harus menampilkan tahun data, sumber, status angka, dan definisi indikator pada tooltip/metadata. Jangan mencampur indikator 2025 dan 2022 dalam satu “snapshot 2025” tanpa label.
Kartu dataset real.
data/katalog_data_real.csv.map_policy <- latest
leaflet::leaflet(map_policy) |>
leaflet::addProviderTiles("CartoDB.Positron") |>
leaflet::addCircleMarkers(~longitude, ~latitude, radius = 6,
popup = ~paste0("<b>", wilayah, "</b><br>", prioritas))Gunakan tabel log berikut untuk project:
| Elemen | Contoh isi |
|---|---|
| Tool/model | Nama layanan/model yang digunakan |
| Tanggal | YYYY-MM-DD |
| Tujuan | Debugging pivot_longer() / ide visualisasi / dokumentasi |
| Ringkasan prompt | Bukan data rahasia; cukup ringkas tujuan |
| Output yang dipakai | Fungsi/kode/paragraf apa yang diadaptasi |
| Verifikasi | Dibandingkan dokumentasi resmi, unit test, cek hasil manual |
| Modifikasi manusia | Perubahan yang dilakukan mahasiswa |
Tidak diperbolehkan: membuat sumber/referensi fiktif, mengunggah data individual rahasia tanpa izin, menyalin interpretasi AI tanpa pemeriksaan, atau menyembunyikan penggunaan AI ketika berkontribusi substantif pada produk akhir.
Policy recommendation perlu memiliki tingkat kepastian yang sebanding dengan bukti. Gunakan bahasa “data menunjukkan asosiasi/pola”, “model memprediksi”, atau “hasil mendukung prioritas eksplorasi”, bukan klaim sebab-akibat yang tidak didukung desain.
Buat policy translation memo maksimum 2 halaman: tiga temuan, dua opsi kebijakan, satu rekomendasi, stakeholder, implementation risk, data limitation, dan indikator monitoring. Lampirkan screenshot/dashboard beta. Isi AI-use log bila AI digunakan.
Minggu 15 adalah policy and communication gate: kelompok menyerahkan dashboard beta, policy memo 2 halaman, AI-use log, dan mendapatkan peer review.
Nilai sains data muncul ketika bukti diterjemahkan menjadi keputusan secara transparan. AI dapat mempercepat kerja, tetapi tanggung jawab ilmiah tetap berada pada analis manusia.
Pertemuan akhir menguji dua hal berbeda: produk tim melalui presentasi capstone dan penguasaan individu melalui UAS/defense. Pemisahan ini mencegah keberhasilan kelompok menutupi ketidaksiapan individu.
Mahasiswa mampu mempertahankan keputusan analitik, menjawab kritik, menunjukkan reproducibility, membedakan evidence dari asumsi, dan menyusun rekomendasi regional yang proporsional.
Reproducibility audit memeriksa apakah data, kode, seed, dependency, dan output dapat ditelusuri. Replicability lebih luas dan berkaitan dengan apakah temuan serupa diperoleh dengan data/prosedur baru. Untuk mata kuliah ini, fokus minimum adalah reproducibility.
Tidak ada formula baru. Mahasiswa harus mampu menjelaskan kembali metric/model yang digunakan pada project, termasuk unit outcome dan arti koefisien/probabilitas/cluster/metric.
Project adalah kerja kelompok, tetapi UAS mengukur penguasaan individu. Secara konseptual skor final presentation/defense dapat dipisahkan: Bobot ini berada di dalam komponen UAS 20%, bukan menambah bobot semester.
Gunakan checklist dengan komponen dan bobot : Komponen minimum: data provenance, raw/processed separation, executable script, fixed seed, environment information, model object/parameter, generated tables/figures, AI declaration, dan README.
Mahasiswa menerima satu mini-case atau cuplikan hasil analisis yang belum sempurna dan harus:
Kisi-kisi UAS:
| Area | Proporsi skor UAS | Fokus |
|---|---|---|
| Integrasi workflow | 15% | problem→data→model→decision |
| ML/classification | 20% | tree/ensemble/logit/threshold/metrics |
| Unsupervised & spatial | 20% | cluster/PCA/Moran/peta |
| Validation & uncertainty | 20% | resampling, calibration, sensitivity, fairness |
| Policy & AI governance | 15% | evidence-based recommendation, AI declaration |
| Oral defense | 10% | menjelaskan keputusan analitik secara individual |
Folder minimum:
capstone/
README.md
data_raw/ # bila lisensi mengizinkan
data_processed/
R/
01_import.R
02_clean.R
03_eda.R
04_model.R
05_validate.R
06_visualize.R
report/
final_report.Rmd
dashboard/
output/
metadata/
data_dictionary.csv
provenance.csv
ai_use_log.csv
sessionInfo.txt
Final package dianggap berhasil jika dosen dapat mengikuti README dan meregenerasi tabel/grafik utama tanpa menebak langkah tersembunyi.
Jika sebuah angka pada slide tidak dapat ditelusuri ke kode atau tabel sumber, angka tersebut belum siap menjadi bukti kebijakan. Audit trail adalah perlindungan terhadap kesalahan analitik dan ketergantungan berlebihan pada AI.
Mahasiswa memperoleh Project=84, Partisipasi=90, Kuis=80, Tugas=88, UTS=76, UAS=82. Nilai numerik: Konversi ke huruf mengikuti ketentuan akademik program/universitas yang berlaku; e-book tidak menetapkan boundary huruf bila belum diberikan secara resmi.
Oral defense bertujuan membedakan team product dan individual understanding. Dosen dapat memilih satu grafik, satu formula, satu code chunk, dan satu recommendation secara acak. Mahasiswa harus menjelaskan: - apa input dan output; - mengapa metode dipilih; - apa asumsi; - apa alternative; - apa keterbatasan; - bagaimana hasil memengaruhi keputusan.
Dosen/peer reviewer menjalankan project dari clean session. Failure modes umum:
| Pertanyaan | Bukti yang diharapkan |
|---|---|
| “Apa masalahnya?” | decision question dan stakeholder |
| “Mengapa data ini?” | metadata, representativeness, period |
| “Mengapa model ini?” | baseline comparison + validation |
| “Seberapa pasti?” | CV/bootstrap/sensitivity/calibration |
| “Apakah adil?” | subgroup analysis bila relevan |
| “Apakah spasial?” | map + W sensitivity jika dipakai |
| “Apa tindakan?” | recommendation traceable to findings |
| “Apa peran AI?” | AI-use log + verification |
Pekerjaan magister tidak ditentukan oleh jumlah algoritma. Standar yang diharapkan adalah argumentasi: mahasiswa mampu menjelaskan mengapa satu pilihan analitik lebih defensible daripada alternatif, mengukur uncertainty, mengenali asumsi yang rapuh, serta menahan diri dari klaim yang tidak didukung. Project dengan model sederhana tetapi argumentasi, validasi, dan policy translation kuat dapat lebih unggul daripada model kompleks yang tidak dipahami.
# Contoh artefak audit sederhana.
files_needed <- c(
"Sains_Data_Inovasi_Regional.Rmd",
"references.bib",
"data/simulasi_panel_regional.csv",
"R/00_setup.R"
)
tibble(file = files_needed, tersedia = file.exists(files_needed)) |>
knitr::kable(caption = "Contoh reproducibility checklist")| file | tersedia |
|---|---|
| Sains_Data_Inovasi_Regional.Rmd | TRUE |
| references.bib | TRUE |
| data/simulasi_panel_regional.csv | TRUE |
| R/00_setup.R | TRUE |
audit_plot <- tibble::tibble(file = files_needed, tersedia = file.exists(files_needed))
ggplot2::ggplot(audit_plot, ggplot2::aes(reorder(file, tersedia), as.integer(tersedia), fill = tersedia)) +
ggplot2::geom_col(show.legend = FALSE) +
ggplot2::coord_flip() +
ggplot2::scale_y_continuous(breaks = c(0,1), labels = c("Tidak", "Ya")) +
ggplot2::scale_fill_manual(values = c("TRUE" = "#145B8C", "FALSE" = "#C99A17")) +
ggplot2::labs(title = "Status artefak reproducibility", x = NULL, y = "Tersedia")Untuk data open data, tim menyimpan URL sumber dan metadata, bukan mengklaim kepemilikan data. Bila lisensi membatasi redistribusi, repository menyimpan script download dan checksum/versi, bukan file mentah.
Kartu dataset real untuk final project.
#> R version 4.5.1 (2025-06-13)
#> Platform: aarch64-apple-darwin20
#> Running under: macOS Sonoma 14.5
#>
#> Matrix products: default
#> BLAS: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRblas.0.dylib
#> LAPACK: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRlapack.dylib; LAPACK version 3.12.1
#>
#> locale:
#> [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
#>
#> time zone: Asia/Jakarta
#> tzcode source: internal
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] httr2_1.2.3 jsonlite_2.0.0 leaflet_2.2.2 tmap_4.1
#> [5] spdep_1.3-13 spData_2.3.4 sf_1.0-21 factoextra_1.0.7
#> [9] cluster_2.1.8.1 ranger_0.17.0 yardstick_1.3.2 workflowsets_1.1.1
#> [13] workflows_1.3.0 tune_2.0.1 tailor_0.1.0 rsample_1.3.1
#> [17] recipes_1.3.1 parsnip_1.4.1 modeldata_1.5.1 infer_1.1.0
#> [21] dials_1.4.2 scales_1.4.0 tidymodels_1.4.1 broom_1.0.12
#> [25] knitr_1.50 skimr_2.2.2 janitor_2.2.1 lubridate_1.9.5
#> [29] forcats_1.0.1 stringr_1.6.0 dplyr_1.2.1 purrr_1.2.0
#> [33] readr_2.2.0 tidyr_1.3.1 tibble_3.3.1 ggplot2_4.0.1
#> [37] tidyverse_2.0.0
#>
#> loaded via a namespace (and not attached):
#> [1] splines_4.5.1 leaflegend_1.2.1 hardhat_1.4.2
#> [4] XML_3.99-0.18 rpart_4.1.24 sparsevctrs_0.3.4
#> [7] lifecycle_1.0.5 rstatix_0.7.2 globals_0.18.0
#> [10] lattice_0.22-7 vroom_1.7.1 MASS_7.3-65
#> [13] crosstalk_1.2.1 backports_1.5.0 magrittr_2.0.4
#> [16] sass_0.4.10 rmarkdown_2.30 jquerylib_0.1.4
#> [19] yaml_2.3.10 otel_0.2.0 sp_2.2-0
#> [22] DBI_1.2.3 RColorBrewer_1.1-3 multcomp_1.4-28
#> [25] abind_1.4-8 spatialreg_1.3-6 nnet_7.3-20
#> [28] TH.data_1.1-3 rappdirs_0.3.3 sandwich_3.1-1
#> [31] ipred_0.9-15 lava_1.8.1 ggrepel_0.9.6
#> [34] listenv_0.10.0 terra_1.8-54 units_0.8-7
#> [37] parallelly_1.45.0 codetools_0.2-20 tidyselect_1.2.1
#> [40] raster_3.6-32 farver_2.1.2 base64enc_0.1-3
#> [43] cols4all_0.9 e1071_1.7-16 Formula_1.2-5
#> [46] survival_3.8-3 tools_4.5.1 Rcpp_1.1.0
#> [49] glue_1.8.0 prodlim_2025.04.28 xfun_0.54
#> [52] leaflet.providers_2.0.0 mgcv_1.9-3 withr_3.0.2
#> [55] fastmap_1.2.0 boot_1.3-31 digest_0.6.38
#> [58] timechange_0.4.0 R6_2.6.1 microbenchmark_1.5.0
#> [61] colorspace_2.1-2 wk_0.9.4 spacesXYZ_1.6-0
#> [64] LearnBayes_2.15.1 dichromat_2.0-0.1 utf8_1.2.6
#> [67] generics_0.1.4 data.table_1.18.2.1 class_7.3-23
#> [70] htmlwidgets_1.6.4 tmaptools_3.2 pkgconfig_2.0.3
#> [73] gtable_0.3.6 timeDate_4051.111 GPfit_1.0-9
#> [76] S7_0.2.1 furrr_0.3.1 htmltools_0.5.8.1
#> [79] carData_3.0-5 bookdown_0.43 png_0.1-8
#> [82] gower_1.0.2 snakecase_0.11.1 rstudioapi_0.17.1
#> [85] tzdb_0.5.0 coda_0.19-4.1 nlme_3.1-168
#> [88] repr_1.1.7 proxy_0.4-27 cachem_1.1.0
#> [91] zoo_1.8-15 KernSmooth_2.23-26 parallel_4.5.1
#> [94] s2_1.1.9 leafsync_0.1.0 pillar_1.11.1
#> [97] grid_4.5.1 logger_0.4.0 vctrs_0.7.3
#> [100] ggpubr_0.6.1 car_3.1-3 lhs_1.2.0
#> [103] evaluate_1.0.5 mvtnorm_1.3-3 cli_3.6.5
#> [106] compiler_4.5.1 rlang_1.3.0 crayon_1.5.3
#> [109] maptiles_0.10.0 future.apply_1.20.0 ggsignif_0.6.4
#> [112] labeling_0.4.3 classInt_0.4-11 stringi_1.8.7
#> [115] modelenv_0.2.0 viridisLite_0.4.2 deldir_2.0-4
#> [118] stars_0.6-8 Matrix_1.7-3 hms_1.1.4
#> [121] bit64_4.6.0-1 leafem_0.2.4 future_1.58.0
#> [124] igraph_2.1.4 bslib_0.11.0 lwgeom_0.2-14
#> [127] bit_4.6.0 DiceDesign_1.10
Checklist akhir repository:
README menjelaskan pertanyaan, data, cara menjalankan project.data/raw tidak berisi data sensitif.Presentasi final harus berakhir dengan opsi tindakan dan batas bukti, bukan dengan “akurasi model 87%”. Contoh penutup yang lebih substantif: “Model membantu menyaring 20% wilayah dengan risiko tertinggi, tetapi error lebih besar pada wilayah berdata jarang; karena itu rekomendasi kami adalah menggunakan model sebagai tahap screening yang diikuti verifikasi lapangan, bukan keputusan otomatis.”
UAS terdiri dari analytical synthesis individual dan oral defense. Mahasiswa tidak dinilai dari hafalan syntax R, tetapi dari kemampuan menjelaskan keputusan analitik, membaca output, menemukan risiko validitas, dan menghubungkan hasil dengan keputusan regional.
Milestone akhir: repository reproducible, dashboard/visual, policy memo, presentasi, dan defense. UAS individual menguji kemampuan menjelaskan metode serta mengkritik keterbatasan proyek.
Capstone yang baik dapat diaudit, direproduksi, dan dipertahankan secara substantif. Tujuan akhir bukan memamerkan algoritma, tetapi meningkatkan kualitas keputusan regional dengan bukti yang transparan.
Bagian ini berfungsi sebagai indeks cepat. Penjelasan, asumsi, dan contoh terdapat pada bab terkait.
| Topik | Rumus inti |
|---|---|
| Weighted index | |
| Rate | |
| Growth | |
| Z-score | |
| Mean/variance | , |
| Correlation | |
| Gini | |
| OLS | |
| VIF | |
| RMSE | |
| MAE | |
| Ridge | |
| Lasso | |
| Gini impurity | |
| RF regression | |
| Logistic | |
| Sensitivity | |
| Precision | |
| F1 | |
| K-means | |
| Silhouette | |
| PCA eigen | |
| PVE | |
| Moran’s I | |
| Bootstrap SE | |
| DID |
| Istilah | Definisi operasional dalam mata kuliah |
|---|---|
| Analytical question | pertanyaan yang dapat dijawab dengan data/metode dan diturunkan dari masalah keputusan |
| Outcome | variabel target yang dijelaskan, diprediksi, atau dievaluasi |
| Feature/predictor | informasi yang digunakan untuk menjelaskan/memprediksi outcome |
| Unit observasi | entitas satu baris data, misalnya kabupaten–tahun |
| Unit analisis | unit yang menjadi dasar inferensi/interpretasi; sering sama tetapi tidak selalu dengan unit observasi |
| Denominator | populasi dasar suatu rate/proportion |
| Provenance | jejak asal data, versi, transformasi, lisensi, dan tanggal akses |
| Metadata | informasi tentang definisi, satuan, periode, metode produksi, dan struktur data |
| Tidy data | struktur satu variabel per kolom, satu observasi per baris, satu jenis unit per tabel |
| Missingness | keadaan nilai tidak teramati; mekanismenya dapat memengaruhi bias |
| Outlier | observasi ekstrem; dapat berupa error atau fenomena substantif valid |
| Feature engineering | konstruksi fitur baru dari data mentah untuk merepresentasikan konsep yang lebih relevan |
| Leakage | informasi yang tidak seharusnya tersedia saat prediksi masuk ke training/preprocessing |
| EDA | exploratory data analysis: iterasi pertanyaan–visualisasi–pola–pertanyaan baru |
| Association | hubungan statistik, tidak otomatis kausal |
| Prediction | estimasi outcome pada observasi/waktu baru |
| Causal effect | perubahan outcome akibat intervensi/perlakuan di bawah definisi estimand dan asumsi identifikasi |
| Baseline model | model/rule sederhana sebagai pembanding wajib |
| Loss function | fungsi yang mengukur biaya kesalahan prediksi |
| Empirical risk | rata-rata loss pada sample training |
| Generalization | kemampuan perform pada data baru dari target deployment |
| Cross-validation | resampling untuk estimasi perform/tuning menggunakan training data |
| RMSE | akar mean squared error; menekankan error besar |
| MAE | mean absolute error; error absolut rata-rata |
| Calibration | kesesuaian predicted probability dengan observed frequency |
| Discrimination | kemampuan model membedakan/ranking kelas positif vs negatif |
| Threshold | batas probabilitas/score untuk mengubah prediksi menjadi tindakan/kelas |
| Random forest | ensemble randomized decision trees dengan agregasi prediksi |
| Boosting | ensemble sequential yang menambah weak learners untuk mengurangi loss |
| Regularization | penalti kompleksitas untuk mengontrol variance/overfitting |
| Clustering | pengelompokan unsupervised berdasarkan similarity yang didefinisikan |
| Centroid | pusat rata-rata cluster dalam K-means |
| Silhouette | ukuran compactness dan separation per observasi |
| PCA | rotasi linear yang mencari arah variance maksimum |
| Loading | coefficient/eigenvector yang membentuk principal component |
| Score PCA | koordinat observasi pada principal component |
| PVE | proportion of variance explained oleh komponen |
| CRS | coordinate reference system untuk menginterpretasi koordinat spasial |
| Spatial weights | definisi matematis siapa bertetangga/berinteraksi dengan siapa |
| Spatial lag | weighted combination nilai pada tetangga |
| Moran’s I | ukuran global spatial autocorrelation |
| LISA | local indicators of spatial association |
| MAUP | perubahan hasil akibat skala/zoning unit areal |
| Ecological fallacy | kesalahan menerapkan hubungan agregat kepada individu |
| Bootstrap | resampling dengan replacement untuk mengestimasi sampling variability |
| Robustness | kestabilan kesimpulan terhadap reasonable analytic alternatives |
| Sensitivity analysis | evaluasi bagaimana hasil berubah saat asumsi/parameter diubah |
| Fairness | evaluasi distribusi perform/keputusan di kelompok relevan; definisinya kontekstual |
| DID | difference-in-differences untuk evaluasi perubahan treated vs control dengan asumsi tertentu |
| Policy brief | dokumen ringkas yang menghubungkan bukti, opsi, rekomendasi, dan caveat |
| Dashboard | antarmuka monitoring/exploration; bukan pengganti analisis metodologis |
| Reproducibility | kemampuan pihak lain meregenerasi hasil dari data, kode, parameter, dan environment |
| AI-use declaration | catatan transparan tentang tujuan, bagian yang dibantu AI, dan metode verifikasi |
| Model card | dokumentasi intended use, data, metrics, limitations, dan risiko model |
| Datasheet | dokumentasi asal, komposisi, collection, preprocessing, penggunaan, limitations dataset |
Mulai dari objective Ekspansi: Turunkan terhadap : Set sama dengan nol: Jika invertibel: Ini menunjukkan OLS berasal langsung dari minimisasi SSE, bukan formula yang muncul tanpa alasan.
Untuk konstanta , minimalkan Turunan: Set nol memberi . Inilah alasan leaf prediction regression tree adalah mean pada node bila loss squared error.
Untuk fungsi tidak differentiable di data points, tetapi subgradient berubah tanda ketika jumlah observasi di bawah dan di atas seimbang. Solusi berada pada median. Ini menjelaskan hubungan natural MAE dengan median-type prediction.
Dari exponentiate: Maka sehingga
Variance projection adalah Cari dengan . Lagrangian: Turunan terhadap : Jadi arah principal component adalah eigenvector covariance/correlation matrix.
Misalkan , , . Untuk estimator : Cross-term dengan hilang karena mean nol dan independensi yang diasumsikan. Tambah-kurang menghasilkan Tiga komponen adalah irreducible noise, squared bias, dan variance.
Untuk satu cluster , minimalkan Turunan vector: sehingga Karena itu update centroid adalah mean anggota cluster.
Jika independen dengan variance : Maka , diestimasi dengan .
Odds . Sebaliknya Jika odds dikalikan OR, probability baru adalah Rumus ini menunjukkan perubahan probability bergantung pada baseline .
Pembilang besar positif jika neighbors memiliki deviasi dengan tanda sama; negatif jika tanda berlawanan. Penyebut menormalisasi overall variance dan menyesuaikan total bobot. Karena nilai ekspektasi null bergantung struktur W dan n, inference sebaiknya menggunakan teori/permutation yang tepat, bukan membandingkan sekadar dengan nol.
Sebelum menyerahkan tugas/project, pastikan:
Daftar pustaka berikut dihasilkan dari references.bib. URL sumber data dipertahankan agar mahasiswa dapat memeriksa metadata, tahun cakupan, versi, dan tanggal akses. Untuk dataset yang terus diperbarui, status data harus diverifikasi kembali pada saat project dikerjakan.