File ini merupakan contoh penggunaan R markdown untuk melakukan simulasi data dan fitting model dengan Generalized Linear Model (GLM)
Data yang disimulasikan terdiri dari usia, status merokok, jenis kelamin, dan jumlah klaim.
set.seed(73)
n <- 1000
beta0 <- 1.5
beta1 <- 0.02
beta2 <- 0.3
beta3 <- 0.1
usia <- round(rnorm(n, mean = 40, sd = 12))
status_merokok <- rbinom(n, size = 1, prob = 0.5)
jenis_kelamin <- rbinom(n, size = 1, prob = 0.5)
log_miu <- beta0 + beta1 * usia + beta2 * status_merokok + beta3 * jenis_kelamin
miu <- exp(log_miu)
y <- rpois(n, lambda = miu)
data <- data.frame(y, usia, status_merokok, jenis_kelamin)
summary(data)
## y usia status_merokok jenis_kelamin
## Min. : 2.00 Min. : 3.00 Min. :0.000 Min. :0.000
## 1st Qu.: 9.00 1st Qu.:32.00 1st Qu.:0.000 1st Qu.:0.000
## Median :12.00 Median :40.00 Median :0.000 Median :0.000
## Mean :12.38 Mean :39.65 Mean :0.497 Mean :0.475
## 3rd Qu.:15.00 3rd Qu.:48.00 3rd Qu.:1.000 3rd Qu.:1.000
## Max. :43.00 Max. :81.00 Max. :1.000 Max. :1.000
Hasil di atas menunjukkan ringkasan statistik dari data simulasi. Nilai usia memiliki rata-rata sekitar 40 tahun dengan sebaran yang cukup besar. Sementara itu, status merokok dan jenis kelamin bersifat biner (0 atau 1), sehingga nilai minimumnya 0 dan maksimumnya 1.
model <- glm(y ~ usia + status_merokok + jenis_kelamin, family = poisson(link = "log"), data = data)
summary(model)
##
## Call:
## glm(formula = y ~ usia + status_merokok + jenis_kelamin, family = poisson(link = "log"),
## data = data)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 1.5184565 0.0361616 41.991 < 2e-16 ***
## usia 0.0196794 0.0007517 26.179 < 2e-16 ***
## status_merokok 0.2848016 0.0181416 15.699 < 2e-16 ***
## jenis_kelamin 0.0809338 0.0179907 4.499 6.84e-06 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for poisson family taken to be 1)
##
## Null deviance: 1892.5 on 999 degrees of freedom
## Residual deviance: 970.4 on 996 degrees of freedom
## AIC: 5267.3
##
## Number of Fisher Scoring iterations: 4
Berdasarkan hasil model GLM di atas:
Intersep ((Intercept)) bernilai sekitar 1.5 yang menunjukkan log-rata-rata klaim saat semua variabel prediktor bernilai nol.
Koefisien usia positif (misalnya 0.02), artinya semakin tua usia peserta, rata-rata jumlah klaim cenderung meningkat.
Koefisien status_merokok positif, menunjukkan bahwa perokok cenderung memiliki jumlah klaim lebih tinggi dibanding non-perokok.
Koefisien jenis_kelamin positif juga, artinya jenis kelamin tertentu (misal 1 = laki-laki) berkaitan dengan peningkatan rata-rata klaim.
Untuk mengevaluasi ketidakpastian dari estimasi koefisien
usia, kita gunakan metode bootstrap
sebanyak 1000 kali. Tujuannya untuk memperoleh distribusi sampling dari
estimasi β1.
set.seed(73)
n_boot <- 1000
beta1_boot <- numeric(n_boot)
for (i in 1:n_boot) {
boot_sample <- data[sample(1:nrow(data), replace = TRUE), ]
model_boot <- glm(y ~ usia + status_merokok + jenis_kelamin,
family = poisson(link = "log"),
data = boot_sample)
beta1_boot[i] <- coef(model_boot)["usia"]
}
hist(beta1_boot, breaks = 30, col = "skyblue", main = "Distribusi Bootstrap untuk Koefisien Usia (β1)",
xlab = "Estimasi β1", border = "white")
ci_beta1 <- quantile(beta1_boot, probs = c(0.025, 0.975))
abline(v = ci_beta1, col = "red", lwd = 2, lty = 2)
#### Interpretasi Hasil Berdasarkan hasil histogram di atas, menunjukkan
bahwa hasil estimasi bootstrap dari koefisien beta 1 variabel usia
mendekati distribusi normal karna membentuk pola lonceng. Garis merah
menandakan batas atas dan batas bawah dari confidance interval 95% yang
diperoleh dari metode persentil bootstrap. Nilai estimasi yang diperoleh
sebesar 0.01823078 – 0.02111189, merupakan nilai yang cukup
konsisten.
Resampling dengan metode bootstrap penting digunakan ketika asumsi normalitas tidak terpenuhi, karena metode ini tidak memerlukan asumsi tersebut.
Pada bagian ini, kita akan menambahkan variabel target Y
yang bersifat biner:
- 1 = peserta melakukan klaim besar (10% kasus)
- 0 = peserta tidak melakukan klaim besar (90% kasus)
library(ROSE)
## Warning: package 'ROSE' was built under R version 4.4.3
library(DMwR)
set.seed(73)
data$Y <- rbinom(nrow(data), size = 1, prob = 0.1)
# Lihat distribusi awal
table(data$Y)
##
## 0 1
## 904 96
prop.table(table(data$Y))
##
## 0 1
## 0.904 0.096
data_under <- ovun.sample(Y ~ usia + status_merokok + jenis_kelamin,
data = data,
method = "under",
N = 2 * sum(data$Y == 1))$data
table(data_under$Y)
##
## 0 1
## 96 96
data$Y <- as.factor(data$Y) # ubah Y jadi faktor
data_smote <- SMOTE(Y ~ usia + status_merokok + jenis_kelamin, data,
perc.over = 900, perc.under = 100)
table(data_smote$Y)
##
## 0 1
## 864 960
par(mfrow = c(1, 3))
barplot(table(data$Y), main = "Sebelum Balancing", col = "lightblue")
barplot(table(data_under$Y), main = "Setelah Undersampling", col = "pink")
barplot(table(data_smote$Y), main = "Setelah SMOTE", col = "salmon")
#### Interpretasi Resampling Berdasarkan hasil grafik diatas menunjukkan
bahwa: 1. Sebelum balancing, distribusi awal sangat tidak seimbang,
karna peserta yang mengajukan klaim besar hanya sekitar 10% dari data.
2. Setelah undersampling, kelas mayoritas (0) dikurangi jumlahnya agar
seimbang dengan kelas minoritas (1) 3. Setelah SMOTE, jumlah data hampir
sama.
Untuk melihat apakah terdapat perbedaan usia antara kelompok klaim tinggi dan rendah, dilakukan uji ANOVA satu arah. Kemudian dilanjutkan ANCOVA untuk melihat pengaruh usia terhadap jumlah klaim dengan mempertimbangkan status merokok.
q75 <- quantile(data$y, 0.75)
data$Kelompok_Klaim <- ifelse(data$y > q75, 1, 0)
table(data$Kelompok_Klaim)
##
## 0 1
## 772 228
anova_result <- aov(usia ~ as.factor(Kelompok_Klaim), data = data)
summary(anova_result)
## Df Sum Sq Mean Sq F value Pr(>F)
## as.factor(Kelompok_Klaim) 1 27515 27515 238.8 <2e-16 ***
## Residuals 998 114995 115
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
ancova_model <- aov(y ~ status_merokok + usia, data = data)
summary(ancova_model)
## Df Sum Sq Mean Sq F value Pr(>F)
## status_merokok 1 2737 2737 211.1 <2e-16 ***
## usia 1 8481 8481 654.2 <2e-16 ***
## Residuals 997 12925 13
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
ancova_interaction <- aov(y ~ status_merokok * usia, data = data)
summary(ancova_interaction)
## Df Sum Sq Mean Sq F value Pr(>F)
## status_merokok 1 2737 2737 213.19 <2e-16 ***
## usia 1 8481 8481 660.70 <2e-16 ***
## status_merokok:usia 1 140 140 10.88 0.001 **
## Residuals 996 12785 13
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1