Laporan ini membangun model prediksi persentase penduduk miskin di 38 kabupaten/kota Jawa Timur tahun 2023 menggunakan Regresi Linear dan Random Forest. Karena data bersifat cross-sectional dan terbatas, model dievaluasi menggunakan repeated 5-fold cross-validation dengan 10 kali pengulangan.
Temuan utama:
Catatan etis: hasil ini bersifat prediktif dan asosiatif, bukan bukti kausal. Feature importance menunjukkan kontribusi variabel terhadap prediksi model, bukan bukti bahwa variabel tersebut menyebabkan kemiskinan.
Data yang digunakan berasal dari publikasi Badan Pusat Statistik (BPS) untuk Provinsi Jawa Timur tahun 2023.
Unit analisis adalah 38 kabupaten/kota di Jawa Timur. Baris agregat
Jawa Timur dikeluarkan agar model hanya belajar dari unit
kabupaten/kota.
Pipeline analisis dijalankan melalui scripts/run_all.R.
Script ini mengeksekusi seluruh tahapan secara berurutan:
dataset <- readr::read_csv("data/processed/dataset_final.csv", show_col_types = FALSE)
model_dataset <- readr::read_csv("data/processed/model_dataset.csv", show_col_types = FALSE)
missing_summary <- readr::read_csv("output/tables/missing_summary.csv", show_col_types = FALSE)
knitr::kable(head(dataset, 10), digits = 2, caption = "Cuplikan dataset final setelah penggabungan")| wilayah | persentase_miskin | ipm | tpt | pdrb_per_kapita_ribu | rata_lama_sekolah | sanitasi_layak | jumlah_penduduk_ribu | laju_pertumbuhan_penduduk | persentase_penduduk | kepadatan_penduduk | rasio_jenis_kelamin |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Bangkalan | 19.35 | 66.82 | 6.18 | 25408 | 6.57 | 50.30 | 1091.8 | 1.07 | 2.63 | 839 | 97.6 |
| Banyuwangi | 7.34 | 73.79 | 4.75 | 58086 | 8.17 | 82.63 | 1743.9 | 0.76 | 4.20 | 485 | 100.1 |
| Blitar | 8.69 | 72.84 | 4.91 | 35812 | 8.04 | 82.50 | 1253.6 | 0.88 | 3.02 | 718 | 101.2 |
| Bojonegoro | 12.18 | 71.80 | 4.63 | 74242 | 7.88 | 92.63 | 1319.6 | 0.50 | 3.18 | 571 | 100.7 |
| Bondowoso | 13.34 | 70.56 | 4.15 | 31432 | 6.95 | 57.41 | 788.2 | 0.56 | 1.90 | 507 | 97.2 |
| Gresik | 10.96 | 78.44 | 6.82 | 130527 | 10.30 | 95.00 | 1350.4 | 1.08 | 3.25 | 1075 | 101.4 |
| Jember | 9.51 | 70.42 | 4.01 | 36837 | 6.97 | 64.47 | 2586.8 | 0.71 | 6.23 | 781 | 99.3 |
| Jombang | 9.15 | 75.16 | 4.66 | 36991 | 9.06 | 94.06 | 1351.3 | 0.91 | 3.25 | 1218 | 101.6 |
| Kediri | 10.72 | 74.68 | 5.79 | 30193 | 8.62 | 92.13 | 1677.2 | 0.92 | 4.04 | 1101 | 101.9 |
| Kota Batu | 3.31 | 79.07 | 4.52 | 93214 | 10.11 | 95.06 | 220.2 | 3.38 | 0.53 | 1134 | 101.3 |
| variable | missing_count |
|---|---|
| wilayah | 0 |
| persentase_miskin | 0 |
| ipm | 0 |
| tpt | 0 |
| pdrb_per_kapita_ribu | 0 |
| rata_lama_sekolah | 0 |
| sanitasi_layak | 0 |
| jumlah_penduduk_ribu | 0 |
| laju_pertumbuhan_penduduk | 0 |
| persentase_penduduk | 0 |
| kepadatan_penduduk | 0 |
| rasio_jenis_kelamin | 0 |
Dataset final memiliki 38 observasi dan 12 kolom. Untuk modeling, PDRB per kapita diskalakan dari ribu rupiah menjadi juta rupiah agar koefisien Regresi Linear lebih mudah dibaca.
descriptive_stats <- readr::read_csv("output/tables/descriptive_stats.csv", show_col_types = FALSE)
knitr::kable(head(descriptive_stats, 24), digits = 2, caption = "Statistik deskriptif variabel numerik")| metric | value |
|---|---|
| persentase_miskin_mean | 10.29 |
| persentase_miskin_median | 9.66 |
| persentase_miskin_min | 3.31 |
| persentase_miskin_max | 21.76 |
| persentase_miskin_sd | 4.32 |
| ipm_mean | 74.68 |
| ipm_median | 73.90 |
| ipm_min | 66.19 |
| ipm_max | 84.00 |
| ipm_sd | 4.71 |
| tpt_mean | 4.66 |
| tpt_median | 4.66 |
| tpt_min | 1.71 |
| tpt_max | 8.05 |
| tpt_sd | 1.43 |
| pdrb_per_kapita_ribu_mean | 70659.47 |
| pdrb_per_kapita_ribu_median | 37232.50 |
| pdrb_per_kapita_ribu_min | 23842.00 |
| pdrb_per_kapita_ribu_max | 541068.00 |
| pdrb_per_kapita_ribu_sd | 89451.38 |
| rata_lama_sekolah_mean | 8.71 |
| rata_lama_sekolah_median | 8.20 |
| rata_lama_sekolah_min | 5.96 |
| rata_lama_sekolah_max | 11.63 |
Distribusi target, wilayah dengan kemiskinan tertinggi, dan korelasi antarvariabel
Distribusi target, wilayah dengan kemiskinan tertinggi, dan korelasi antarvariabel
Distribusi target, wilayah dengan kemiskinan tertinggi, dan korelasi antarvariabel
Distribusi kemiskinan menunjukkan variasi antardaerah yang cukup jelas. Beberapa kabupaten memiliki persentase kemiskinan jauh lebih tinggi dibanding kota-kota besar. Pola ini memperlihatkan bahwa kemiskinan di Jawa Timur tidak merata secara spasial maupun sosial-ekonomi. Matriks korelasi membantu membaca asosiasi awal, terutama hubungan antara kemiskinan dengan indikator pembangunan manusia dan pendidikan, tetapi korelasi tersebut tidak ditafsirkan sebagai sebab-akibat.
Regresi Linear digunakan sebagai baseline karena hasilnya mudah diinterpretasikan. Model ini berguna untuk membaca arah hubungan linear, tetapi asumsi model tetap perlu diperiksa.
lm_coefficients <- readr::read_csv("output/tables/lm_coefficients.csv", show_col_types = FALSE)
lm_vif <- readr::read_csv("output/tables/lm_vif.csv", show_col_types = FALSE)
knitr::kable(lm_coefficients, digits = 3, caption = "Koefisien Regresi Linear")| variable | estimate | std_error | statistic | p_value |
|---|---|---|---|---|
| (Intercept) | 55.259 | 22.522 | 2.454 | 0.020 |
| ipm | -0.460 | 0.446 | -1.031 | 0.310 |
| tpt | -0.326 | 0.387 | -0.842 | 0.406 |
| pdrb_per_kapita_juta | 0.003 | 0.006 | 0.597 | 0.555 |
| rata_lama_sekolah | -1.336 | 1.272 | -1.050 | 0.302 |
| sanitasi_layak | 0.020 | 0.056 | 0.362 | 0.720 |
| kepadatan_penduduk | 0.000 | 0.000 | 0.889 | 0.381 |
knitr::kable(lm_vif, digits = 2, caption = "Variance Inflation Factor (VIF) untuk pemeriksaan multikolinearitas")| variable | vif |
|---|---|
| ipm | 23.72 |
| tpt | 1.64 |
| pdrb_per_kapita_juta | 1.37 |
| rata_lama_sekolah | 19.47 |
| sanitasi_layak | 2.50 |
| kepadatan_penduduk | 3.24 |
VIF digunakan untuk melihat potensi multikolinearitas. Sebagai aturan praktis, VIF di atas 5 perlu diperhatikan dan VIF di atas 10 biasanya menunjukkan masalah serius. Karena beberapa indikator sosial-ekonomi saling berkaitan, hasil Regresi Linear sebaiknya digunakan sebagai interpretasi pendukung, bukan satu-satunya dasar keputusan.
Diagnostik asumsi Regresi Linear: normalitas residual dan homoskedastisitas
Diagnostik asumsi Regresi Linear: normalitas residual dan homoskedastisitas
Q-Q plot membantu menilai apakah residual mendekati distribusi normal, sedangkan scale-location plot membantu melihat apakah variasi residual relatif stabil pada berbagai nilai fitted. Dengan jumlah observasi hanya 38, diagnostik ini dibaca secara hati-hati.
Random Forest digunakan untuk menangkap hubungan non-linear dan
interaksi antarvariabel yang mungkin tidak tertangkap oleh Regresi
Linear. Tuning dilakukan pada parameter mtry, sedangkan
jumlah pohon ditetapkan 500.
rf_importance <- readr::read_csv("output/tables/rf_feature_importance.csv", show_col_types = FALSE)
rf_importance <- rf_importance |>
dplyr::mutate(share = importance / sum(importance))
top3_share <- sum(head(rf_importance$share, 3))
knitr::kable(rf_importance, digits = 3, caption = "Feature importance Random Forest berbasis permutation importance")| variable | importance | share |
|---|---|---|
| rata_lama_sekolah | 14.669 | 0.279 |
| ipm | 12.277 | 0.234 |
| kepadatan_penduduk | 10.221 | 0.194 |
| tpt | 8.120 | 0.154 |
| pdrb_per_kapita_juta | 5.521 | 0.105 |
| sanitasi_layak | 1.765 | 0.034 |
Feature importance Random Forest
Rata-rata lama sekolah muncul sebagai prediktor paling informatif, diikuti oleh IPM dan kepadatan penduduk. Tiga variabel teratas menyumbang sekitar 70.7% dari total importance relatif pada model ini. Secara substantif, temuan ini menunjukkan bahwa dimensi pendidikan, pembangunan manusia, dan karakteristik kepadatan wilayah sangat membantu model dalam memprediksi tingkat kemiskinan. Namun, importance ini tetap bukan bukti kausal.
model_comparison <- readr::read_csv("output/tables/model_comparison.csv", show_col_types = FALSE)
comparison_wide <- model_comparison |>
dplyr::select(model, rmse, mae, r2) |>
tidyr::pivot_longer(-model, names_to = "metric", values_to = "value") |>
tidyr::pivot_wider(names_from = model, values_from = value) |>
dplyr::mutate(metric = toupper(metric))
knitr::kable(comparison_wide, digits = 3, caption = "Perbandingan performa model berdasarkan repeated 5-fold cross-validation")| metric | Regresi Linear | Random Forest |
|---|---|---|
| RMSE | 3.068 | 2.713 |
| MAE | 2.452 | 2.145 |
| R2 | 0.539 | 0.640 |
Perbandingan RMSE, MAE, dan R<U+00B2> antar model
Model dengan RMSE dan MAE lebih kecil memiliki error prediksi yang lebih rendah. Pada eksperimen ini, Random Forest memiliki RMSE dan MAE lebih kecil serta R² lebih tinggi dibanding Regresi Linear.
cv_metric_summary <- readr::read_csv("output/tables/cv_metric_summary.csv", show_col_types = FALSE)
knitr::kable(cv_metric_summary, digits = 3, caption = "Ringkasan metrik cross-validation per resample")| model | rmse_mean | rmse_sd | rmse_ci_low | rmse_ci_high | mae_mean | mae_sd | mae_ci_low | mae_ci_high | r2_mean | r2_sd |
|---|---|---|---|---|---|---|---|---|---|---|
| Random Forest | 2.713 | 0.635 | 2.533 | 2.894 | 2.145 | 0.541 | 1.991 | 2.299 | 0.544 | 0.177 |
| Regresi Linear | 3.068 | 0.881 | 2.818 | 3.319 | 2.452 | 0.650 | 2.267 | 2.637 | 0.404 | 0.352 |
Tabel di atas menunjukkan rata-rata, standar deviasi, dan confidence interval sederhana untuk RMSE dan MAE berdasarkan resample cross-validation. Nilai ini memberi gambaran stabilitas performa, meskipun confidence interval tetap harus dibaca hati-hati karena resample cross-validation tidak sepenuhnya independen.
Prediksi vs aktual dan residual out-of-fold
Prediksi vs aktual dan residual out-of-fold
Scatter plot prediksi vs aktual memperlihatkan seberapa dekat prediksi model terhadap nilai sebenarnya. Residual plot membantu melihat apakah terdapat pola error sistematis. Titik yang jauh dari garis ideal atau memiliki residual besar perlu diperiksa sebagai wilayah yang sulit diprediksi oleh model.
model_outliers <- readr::read_csv("output/tables/model_outliers.csv", show_col_types = FALSE)
knitr::kable(model_outliers, digits = 3, caption = "Lima wilayah dengan residual cross-validation terbesar per model")| model | wilayah | actual | predicted | residual | abs_residual |
|---|---|---|---|---|---|
| Random Forest | Sampang | 21.76 | 15.585 | 6.175 | 6.175 |
| Random Forest | Kota Batu | 3.31 | 8.895 | -5.585 | 5.585 |
| Random Forest | Probolinggo | 17.19 | 12.141 | 5.049 | 5.049 |
| Random Forest | Lumajang | 8.93 | 13.969 | -5.039 | 5.039 |
| Random Forest | Tuban | 14.91 | 10.154 | 4.756 | 4.756 |
| Regresi Linear | Bangkalan | 19.35 | 10.020 | 9.330 | 9.330 |
| Regresi Linear | Gresik | 10.96 | 4.478 | 6.482 | 6.482 |
| Regresi Linear | Sampang | 21.76 | 15.831 | 5.929 | 5.929 |
| Regresi Linear | Lumajang | 8.93 | 14.496 | -5.566 | 5.566 |
| Regresi Linear | Jember | 9.51 | 14.409 | -4.899 | 4.899 |
Wilayah dengan residual besar menunjukkan kasus yang tidak sepenuhnya dijelaskan oleh variabel yang tersedia. Ini dapat menjadi titik awal analisis lanjutan, misalnya dengan menambahkan variabel struktur ekonomi lokal, belanja sosial, harga pangan, atau indikator spasial.
Berdasarkan repeated 5-fold cross-validation, model terbaik pada eksperimen ini adalah Random Forest dengan RMSE 2.713, MAE 2.145, dan R² 0.64.
Untuk tujuan prediksi, Random Forest lebih direkomendasikan karena menangkap hubungan non-linear dan menghasilkan performa lebih baik. Untuk tujuan interpretasi arah hubungan, Regresi Linear tetap berguna sebagai model pendamping karena koefisiennya lebih mudah dijelaskan. Dengan kata lain, Random Forest digunakan untuk prioritas prediktif, sedangkan Regresi Linear digunakan untuk pemahaman awal yang lebih transparan.
Rekomendasi berikut disusun dari variabel yang paling informatif dalam model dan tetap dibaca sebagai prioritas eksploratif.
Pipeline berhasil menggabungkan tujuh sumber data BPS, membersihkan dataset, melakukan EDA, membangun Regresi Linear dan Random Forest, mengevaluasi model dengan repeated cross-validation, serta menghasilkan interpretasi feature importance dan rekomendasi kebijakan. Hasil terbaik diperoleh Random Forest, tetapi seluruh temuan tetap ditempatkan secara etis sebagai bukti prediktif, bukan klaim kausal.