DATA
Y <- "Jumlah golongan putih (Golput) dalam Pemilu Presiden dan Wakil Presiden per 1.000 Penduduk di Setiap Provinsi pada tahun 2024"
X1 <- "Daftar pemilih tetap"
X2 <- "Persentase penduduk miskin"
X3 <- "Persentase tingkat pengangguran terbuka"
X4 <- "Rata-rata lama sekolah penduduk usia 15 tahun ke atas"
X5 <- "Persentase angka melek aksara"
X6 <- "Persentase gini rasio"
X7 <- "Persentase Produk Domestik Bruto/Produk Domestik Regional Bruto Atas Dasar Harga Berlaku"
X8 <- "Persentase Inflasi"
X9 <- "Persentase tenaga kerja formal"
X10<- "Persentasa penyelesaian SMA"
X11<- "Persentase Indeks Demokrasi Indonesia (IDI)"
1. INPUT DATA
library(readxl)
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 3.5.1 ✔ tibble 3.2.1
## ✔ lubridate 1.9.4 ✔ tidyr 1.3.1
## ✔ purrr 1.0.4
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
# Baca data dari file Excel (sesuaikan path dan sheet)
dr <- read_xlsx("C:\\Semester 8 Bismillahirrohmanirrohim\\Data\\1sample.xlsx", sheet = 2)
# Ganti nama kolom
colnames(dr) <- c("Golput", "DPT", "Miskin", "TPT", "RLS", "AMA",
"GRO", "PDRB", "Infl", "TNF", "PPS", "IDI")
head(dr)
## # A tibble: 6 × 12
## Golput DPT Miskin TPT RLS AMA GRO PDRB Infl TNF PPS IDI
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 122 3742037 14.2 5.56 9.95 98.3 0.294 1.11 1.61 39.8 74.5 74.9
## 2 249 10853940 7.99 5.1 10.2 99.1 0.306 5.12 1.78 42.6 74.4 57.5
## 3 234 4088606 5.97 5.79 9.72 99.4 0.287 1.52 1.24 37.4 68.6 90.9
## 4 207 4732174 6.67 3.85 9.69 99.2 0.306 5 1.12 49.9 67.8 83.5
## 5 155 2676107 7.1 4.45 9.26 98.0 0.315 1.43 0.46 41.6 66.6 86.4
## 6 140 6326348 11.0 3.97 8.98 98.7 0.331 3.06 0.92 37.7 64.8 73.2
2. Normalisasi (Z-Score) Variabel Prediktor
# Buat salinan data untuk dinormalisasi
dr_scaled <- dr
# Lakukan normalisasi z-score pada kolom 2 sampai 13
dr_scaled[, 2:12] <- scale(dr[, 2:12])
str(dr_scaled)
## tibble [38 × 12] (S3: tbl_df/tbl/data.frame)
## $ Golput: num [1:38] 122 249 234 207 155 140 132 203 141 219 ...
## $ DPT : num [1:38] -0.1932 0.6648 -0.1514 -0.0738 -0.3218 ...
## $ Miskin: num [1:38] 0.457 -0.468 -0.767 -0.663 -0.6 ...
## $ TPT : num [1:38] 0.8498 0.5218 1.0138 -0.3695 0.0584 ...
## $ RLS : num [1:38] 0.5724 0.7726 0.3722 0.3461 -0.0282 ...
## $ AMA : num [1:38] 0.39 0.533 0.587 0.555 0.33 ...
## $ GRO : num [1:38] -0.976 -0.725 -1.123 -0.725 -0.537 ...
## $ PDRB : num [1:38] -0.382 0.624 -0.279 0.594 -0.302 ...
## $ Infl : num [1:38] 0.987 1.178 0.571 0.436 -0.307 ...
## $ TNF : num [1:38] -0.06 0.1772 -0.2602 0.7895 0.0931 ...
## $ PPS : num [1:38] 0.877 0.875 0.408 0.339 0.245 ...
## $ IDI : num [1:38] 0.202 -1.278 1.563 0.929 1.183 ...
Data telah dinormalisasi menggunakan metode Z-score untuk memastikan skala variabel seragam
Summary data
summary(dr)
## Golput DPT Miskin TPT
## Min. : 1.0 Min. : 367269 Min. : 4.00 Min. :1.180
## 1st Qu.:142.8 1st Qu.: 1173236 1st Qu.: 6.32 1st Qu.:3.255
## Median :166.0 Median : 2727376 Median :10.13 Median :4.140
## Mean :182.7 Mean : 5343598 Mean :11.15 Mean :4.368
## 3rd Qu.:196.2 3rd Qu.: 4571282 3rd Qu.:14.06 3rd Qu.:5.702
## Max. :987.0 Max. :35714901 Max. :32.97 Max. :7.020
## RLS AMA GRO PDRB
## Min. : 5.100 Min. :70.37 Min. :0.2350 Min. : 0.1200
## 1st Qu.: 8.785 1st Qu.:95.27 1st Qu.:0.3060 1st Qu.: 0.4775
## Median : 9.340 Median :98.11 Median :0.3445 Median : 1.0650
## Mean : 9.292 Mean :96.30 Mean :0.3406 Mean : 2.6321
## 3rd Qu.: 9.930 3rd Qu.:98.77 3rd Qu.:0.3640 3rd Qu.: 2.8425
## Max. :11.490 Max. :99.75 Max. :0.4310 Max. :16.7700
## Infl TNF PPS IDI
## Min. :0.0000 Min. : 4.24 Min. :39.50 Min. :53.09
## 1st Qu.:0.0925 1st Qu.:35.03 1st Qu.:58.64 1st Qu.:66.64
## Median :0.5300 Median :40.09 Median :65.64 Median :73.13
## Mean :0.7326 Mean :40.54 Mean :63.58 Mean :72.54
## 3rd Qu.:1.0275 3rd Qu.:46.77 3rd Qu.:68.88 3rd Qu.:80.39
## Max. :4.5500 Max. :68.45 Max. :89.69 Max. :92.97
3. Eksplorasi Data
# Summary data
summary(dr_scaled)
## Golput DPT Miskin TPT
## Min. : 1.0 Min. :-0.60038 Min. :-1.0592 Min. :-2.2732
## 1st Qu.:142.8 1st Qu.:-0.50314 1st Qu.:-0.7153 1st Qu.:-0.7937
## Median :166.0 Median :-0.31564 Median :-0.1506 Median :-0.1627
## Mean :182.7 Mean : 0.00000 Mean : 0.0000 Mean : 0.0000
## 3rd Qu.:196.2 3rd Qu.:-0.09318 3rd Qu.: 0.4323 3rd Qu.: 0.9514
## Max. :987.0 Max. : 3.66423 Max. : 3.2349 Max. : 1.8908
## RLS AMA GRO PDRB
## Min. :-3.64907 Min. :-4.9564 Min. :-2.2117 Min. :-0.6304
## 1st Qu.:-0.44162 1st Qu.:-0.1956 1st Qu.:-0.7251 1st Qu.:-0.5407
## Median : 0.04146 Median : 0.3471 Median : 0.0810 Median :-0.3933
## Mean : 0.00000 Mean : 0.0000 Mean : 0.0000 Mean : 0.0000
## 3rd Qu.: 0.55500 3rd Qu.: 0.4734 3rd Qu.: 0.4893 3rd Qu.: 0.0528
## Max. : 1.91283 Max. : 0.6592 Max. : 1.8921 Max. : 3.5478
## Infl TNF PPS IDI
## Min. :-0.8241 Min. :-3.05340 Min. :-1.9417 Min. :-1.65431
## 1st Qu.:-0.7201 1st Qu.:-0.46370 1st Qu.:-0.3987 1st Qu.:-0.50133
## Median :-0.2279 Median :-0.03769 Median : 0.1659 Median : 0.05027
## Mean : 0.0000 Mean : 0.00000 Mean : 0.0000 Mean : 0.00000
## 3rd Qu.: 0.3317 3rd Qu.: 0.52373 3rd Qu.: 0.4274 3rd Qu.: 0.66802
## Max. : 4.2942 Max. : 2.34720 Max. : 2.1051 Max. : 1.73785
# Boxplot variabel Golput
boxplot(dr_scaled$Golput, main = "Boxplot Golput", col = "lightblue")
# Identifikasi outlier pada Golput menggunakan data asli
outlier_values <- boxplot.stats(dr$Golput)$out
print(outlier_values)
## [1] 987 4 1
Eksplorasi statistik menunjukkan adanya variasi yang cukup besar dalam jumlah Golput antar provinsi.
multikol
library(MASS)
##
## Attaching package: 'MASS'
## The following object is masked from 'package:dplyr':
##
## select
library(car)
## Loading required package: carData
##
## Attaching package: 'car'
## The following object is masked from 'package:dplyr':
##
## recode
## The following object is masked from 'package:purrr':
##
## some
# Buat model Poisson dengan data ter-normalisasi
modellm <- lm(Golput ~ ., data = dr_scaled)
summary(modellm)
##
## Call:
## lm(formula = Golput ~ ., data = dr_scaled)
##
## Residuals:
## Min 1Q Median 3Q Max
## -207.77 -72.99 -31.73 42.02 438.98
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 182.658 21.711 8.413 6.79e-09 ***
## DPT -33.771 49.500 -0.682 0.5011
## Miskin 24.549 54.139 0.453 0.6540
## TPT -20.678 33.433 -0.618 0.5416
## RLS -57.431 70.423 -0.816 0.4222
## AMA 134.081 69.695 1.924 0.0654 .
## GRO 48.599 31.003 1.568 0.1291
## PDRB 2.503 47.938 0.052 0.9588
## Infl 62.291 34.591 1.801 0.0833 .
## TNF 21.629 53.912 0.401 0.6916
## PPS -58.566 41.112 -1.425 0.1662
## IDI 80.906 31.440 2.573 0.0161 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 133.8 on 26 degrees of freedom
## Multiple R-squared: 0.3975, Adjusted R-squared: 0.1425
## F-statistic: 1.559 on 11 and 26 DF, p-value: 0.1703
# Cek multikolinearitas (VIF)
vif(modellm)
## DPT Miskin TPT RLS AMA GRO PDRB Infl
## 5.061692 6.054780 2.308962 10.244900 10.034053 1.985569 4.747178 2.471776
## TNF PPS IDI
## 6.004165 3.491549 2.041985
4. Distribusi Variabel Respon (Golput)
# Histogram dan density plot untuk Golput (menggunakan data asli)
hist(dr$Golput, probability = TRUE, main = "Histogram Golput", col = "lightgray")
lines(density(dr$Golput), col = "red", lwd = 2)
# Hitung mean dan variance Golput
mean_golput <- mean(dr$Golput)
var_golput <- var(dr$Golput)
mean_golput
## [1] 182.6579
var_golput
## [1] 20888.83
Distribusi jumlah Golput menunjukkan adanya skewness dan variabilitas yang tinggi.
5. Uji Distribusi Poisson Misalnya, kita gunakan KS-test dengan parameter lambda sama dengan mean Golput.
ks.test(dr$Golput, "rpois", lambda = 182.6579)
## Warning in ks.test.default(dr$Golput, "rpois", lambda = 182.6579): ties should
## not be present for the one-sample Kolmogorov-Smirnov test
##
## Asymptotic one-sample Kolmogorov-Smirnov test
##
## data: dr$Golput
## D = 202.92, p-value < 2.2e-16
## alternative hypothesis: two-sided
Hasil uji distribusi Poisson menunjukkan bahwa jumlah Golput tidak sepenuhnya mengikuti distribusi Poisson karena adanya overdispersi.
6.Model Poisson
library(MASS)
library(car)
# Buat model Poisson dengan data ter-normalisasi
model.poisson <- glm(Golput ~ ., data = dr_scaled, family = "poisson")
summary(model.poisson)
##
## Call:
## glm(formula = Golput ~ ., family = "poisson", data = dr_scaled)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 5.12321 0.01287 397.922 < 2e-16 ***
## DPT -0.10971 0.02773 -3.957 7.59e-05 ***
## Miskin 0.02651 0.03291 0.806 0.42045
## TPT -0.09241 0.01830 -5.049 4.44e-07 ***
## RLS -0.16504 0.03996 -4.130 3.63e-05 ***
## AMA 0.50785 0.03831 13.255 < 2e-16 ***
## GRO 0.16585 0.01618 10.247 < 2e-16 ***
## PDRB 0.01638 0.02671 0.613 0.53978
## Infl 0.26831 0.01972 13.608 < 2e-16 ***
## TNF 0.07746 0.02974 2.605 0.00919 **
## PPS -0.27324 0.02337 -11.692 < 2e-16 ***
## IDI 0.34284 0.01700 20.170 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for poisson family taken to be 1)
##
## Null deviance: 2774.6 on 37 degrees of freedom
## Residual deviance: 1395.4 on 26 degrees of freedom
## AIC: 1676.4
##
## Number of Fisher Scoring iterations: 5
# Cek multikolinearitas (VIF)
vif(model.poisson)
## DPT Miskin TPT RLS AMA GRO PDRB Infl
## 4.912550 5.265727 2.108469 7.729377 5.758201 2.037250 4.772707 1.983699
## TNF PPS IDI
## 4.805985 3.728039 1.972989
7. Uji Overdispersi pada Model Poisson
library(AER)
## Loading required package: lmtest
## Loading required package: zoo
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
## Loading required package: sandwich
## Loading required package: survival
# Uji overdispersi dengan dispersion test
dispersiontest(model.poisson)
##
## Overdispersion test
##
## data: model.poisson
## z = 4.2519, p-value = 1.06e-05
## alternative hypothesis: true dispersion is greater than 1
## sample estimates:
## dispersion
## 33.59933
# Hitung rasio Pearson chi-square / df
pearson_chisq <- sum(residuals(model.poisson, type = "pearson")^2)
df_value <- df.residual(model.poisson)
pearson_ratio <- pearson_chisq / df_value
pearson_ratio
## [1] 49.15964
# Gunakan DHARMa untuk evaluasi residual
library(DHARMa)
## This is DHARMa 0.4.7. For overview type '?DHARMa'. For recent changes, type news(package = 'DHARMa')
sim.poisson <- simulateResiduals(model.poisson, refit = TRUE)
testOverdispersion(sim.poisson)
## testOverdispersion is deprecated, switch your code to using the testDispersion function
##
## DHARMa nonparametric dispersion test via mean deviance residual fitted
## vs. simulated-refitted
##
## data: simulationOutput
## dispersion = 49.983, p-value < 2.2e-16
## alternative hypothesis: two.sided
plotSimulatedResiduals(sim.poisson)
## plotSimulatedResiduals is deprecated, please switch your code to simply using the plot() function
Uji overdispersi menunjukkan bahwa model Poisson kurang cocok untuk data
ini karena nilai deviasi residual yang tinggi dan rasio Pearson
chi-square yang jauh di atas 1. Hal ini mengindikasikan bahwa model lain
yang dapat menangani overdispersi lebih sesuai
8. Model Negative Binomial
# Model Negative Binomial dengan semua prediktor
model.nb <- glm.nb(Golput ~ ., data = dr_scaled)
## Warning: glm.fit: algorithm did not converge
## Warning: glm.fit: algorithm did not converge
## Warning: glm.fit: algorithm did not converge
## Warning: glm.fit: algorithm did not converge
## Warning in glm.nb(Golput ~ ., data = dr_scaled): alternation limit reached
summary(model.nb)
##
## Call:
## glm.nb(formula = Golput ~ ., data = dr_scaled, init.theta = 2.941302832,
## link = log)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 5.139449 0.095455 53.841 <2e-16 ***
## DPT -0.022960 0.217525 -0.106 0.9159
## Miskin -0.155632 0.238411 -0.653 0.5139
## TPT -0.074688 0.146833 -0.509 0.6110
## RLS 0.187389 0.310017 0.604 0.5455
## AMA 0.204267 0.306368 0.667 0.5049
## GRO 0.034599 0.136168 0.254 0.7994
## PDRB -0.006996 0.210660 -0.033 0.9735
## Infl 0.282888 0.152013 1.861 0.0628 .
## TNF -0.050550 0.236799 -0.213 0.8310
## PPS -0.335167 0.180795 -1.854 0.0638 .
## IDI 0.329750 0.138156 2.387 0.0170 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for Negative Binomial(2.9413) family taken to be 1)
##
## Null deviance: 57.742 on 37 degrees of freedom
## Residual deviance: 42.746 on 26 degrees of freedom
## AIC: 476.27
##
## Number of Fisher Scoring iterations: 1
##
##
## Theta: 2.941
## Std. Err.: 0.705
## Warning while fitting theta: alternation limit reached
##
## 2 x log-likelihood: -450.272
# Bandingkan AIC antara model Poisson dan Negative Binomial
AIC_poisson <- AIC(model.poisson)
AIC_nb <- AIC(model.nb)
AIC_poisson
## [1] 1676.398
AIC_nb
## [1] 476.272
# Cek VIF (untuk gambaran multikolinearitas)
vif(model.nb)
## DPT Miskin TPT RLS AMA GRO PDRB Infl
## 5.061384 6.020907 2.300685 10.185176 9.931148 1.985374 4.749536 2.458874
## TNF PPS IDI
## 5.962683 3.484530 2.036343
9. Mengatasi Outlier Jika diidentifikasi outlier pada Golput, kita bisa menghapusnya dan refit model.
# Hapus outlier dari data (berdasarkan nilai pada data asli)
dr_clean <- dr_scaled[!dr$Golput %in% outlier_values, ]
dim(dr_clean)
## [1] 35 12
# Fitting model Negative Binomial dengan data yang telah dibersihkan
model.nb_clean <- glm.nb(Golput ~ ., data = dr_clean)
summary(model.nb_clean)
##
## Call:
## glm.nb(formula = Golput ~ ., data = dr_clean, init.theta = 38.02488043,
## link = log)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 5.09602 0.03230 157.791 < 2e-16 ***
## DPT -0.07994 0.07256 -1.102 0.27059
## Miskin -0.26134 0.08052 -3.245 0.00117 **
## TPT 0.06616 0.04605 1.437 0.15083
## RLS 0.11621 0.11671 0.996 0.31938
## AMA -0.09874 0.11191 -0.882 0.37761
## GRO -0.12257 0.05276 -2.323 0.02017 *
## PDRB 0.16679 0.06733 2.477 0.01325 *
## Infl 0.07195 0.04916 1.464 0.14327
## TNF -0.15106 0.07399 -2.042 0.04118 *
## PPS -0.12966 0.06193 -2.094 0.03629 *
## IDI -0.03326 0.04873 -0.682 0.49496
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for Negative Binomial(38.0249) family taken to be 1)
##
## Null deviance: 67.145 on 34 degrees of freedom
## Residual deviance: 35.875 on 23 degrees of freedom
## AIC: 363.77
##
## Number of Fisher Scoring iterations: 1
##
##
## Theta: 38.0
## Std. Err.: 11.4
##
## 2 x log-likelihood: -337.768
Outlier dalam data Golput telah diidentifikasi dan dihapus untuk meningkatkan stabilitas model. Setelah penghapusan outlier, model Negative Binomial menghasilkan estimasi yang lebih konsisten.
#**INTERPRETASI*
#**Intercept (5.09602)** - Saat semua variabel independen bernilai nol, log jumlah Golput adalah 5.096.
#**X2: Persentase Penduduk Miskin (-0.26134, p = 0.00117)**- Setiap kenaikan 1% dalam tingkat kemiskinan menurunkan log jumlah Golput sebesar **0.26134**.
#**X6: Gini Rasio (-0.12257, p = 0.02021)**- Setiap kenaikan 1% dalam gini rasio menurunkan log jumlah Golput sebesar **0.12257**.
#**X7: PDRB (0.16679, p = 0.01325)** - Setiap kenaikan 1% dalam PDRB meningkatkan log jumlah Golput sebesar **0.16679**.
#**X9: Tenaga Kerja Formal (-0.15106, p = 0.04118)** - Setiap kenaikan 1% dalam persentase tenaga kerja formal menurunkan log jumlah Golput sebesar **0.15106**.
#**X10: Penyelesaian SMA (-0.12966, p = 0.03629)** - Setiap kenaikan 1% dalam penyelesaian SMA menurunkan log jumlah Golput sebesar **0.12966**.
10. Evaluasi Goodness-of-Fit untuk Model Negative Binomial
# Rasio Pearson chi-square / df untuk model NB
pearson_chisq_nb <- sum(residuals(model.nb, type = "pearson")^2)
df_value_nb <- df.residual(model.nb)
pearson_ratio_nb <- pearson_chisq_nb / df_value_nb
pearson_ratio_nb
## [1] 0.9677106
# Rasio deviance / df
dispersion_ratio_nb <- deviance(model.nb) / df_value_nb
dispersion_ratio_nb
## [1] 1.644089
Evaluasi model menunjukkan bahwa model Negative Binomial lebih sesuai dibandingkan model Poisson. Rasio Pearson chi-square dan rasio deviance terhadap derajat kebebasan menunjukkan bahwa model ini mampu menangani variasi dalam data dengan lebih baik, mengurangi overdispersi yang ada pada model sebelumnya.