1 Konsep

Dalam berbagai bidang penelitian, terutama kesehatan, ekonomi, dan ilmu sosial, sering dijumpai variabel respon yang berbentuk kategori. Pada kondisi seperti ini, metode regresi linear tidak lagi sesuai digunakan karena asumsi normalitas dan sifat kontinu dari variabel respon tidak terpenuhi. Salah satu metode yang dapat digunakan untuk mengatasi permasalahan tersebut adalah regresi logistik.

Regresi logistik merupakan metode statistika yang digunakan untuk memodelkan hubungan antara satu atau lebih variabel prediktor dengan variabel respon kategorik. Metode ini mengestimasi peluang suatu kejadian berdasarkan karakteristik yang dimiliki objek pengamatan.

Jenis Variabel Respon Contoh
Regresi Logistik Biner Dua kategori (binary) Ya / Tidak, Lulus / Tidak Lulus
Regresi Logistik Multinomial Lebih dari dua kategori nominal Excellent / Incomplete / Indeterminate
Regresi Logistik Ordinal Lebih dari dua kategori ordinal Rendah < Sedang < Tinggi
Regresi Poisson Data cacahan (count data) Jumlah kunjungan, Jumlah kecelakaan

2 Jenis Regresi Logistik

2.1 Regresi Logistik Biner

2.1.1 Konsep

Regresi logistik biner digunakan ketika variabel respon hanya memiliki dua kategori. Model menggunakan fungsi logit:

\[\ln \left(\frac{p}{1-p}\right) = \beta_0+\beta_1X_1+\beta_2X_2+\cdots+\beta_kX_k\]

Notasi Keterangan
\(p\) Probabilitas terjadinya kejadian
\(\beta_0\) Intercept model
\(\beta_i\) Koefisien regresi untuk prediktor ke-\(i\)
\(X_i\) Variabel prediktor ke-\(i\)

2.1.2 Kasus: Prediksi Keputusan Nasabah Berlangganan Deposito

2.1.2.1 Variabel Penelitian

Variabel Tipe Keterangan
duration Numerik Durasi panggilan terakhir (detik)
balance Numerik Saldo rata-rata tahunan
campaign Numerik Jumlah kontak selama kampanye
housing Kategorik Kepemilikan kredit rumah
poutcome Kategorik Hasil kampanye pemasaran sebelumnya

2.1.2.2 Persiapan Data

library(readxl)
data <- read_excel("C:/Users/Lenovo/Downloads/bank.xlsx")
data2 <- data

data2$y        <- as.factor(data2$y)
data2$duration <- as.numeric(data2$duration)
data2$balance  <- as.numeric(data2$balance)
data2$campaign <- as.numeric(data2$campaign)
data2$housing  <- as.factor(data2$housing)
data2$poutcome <- as.factor(data2$poutcome)

str(data2)
## tibble [45,211 × 17] (S3: tbl_df/tbl/data.frame)
##  $ age      : num [1:45211] 58 44 33 47 33 35 28 42 58 43 ...
##  $ job      : chr [1:45211] "management" "technician" "entrepreneur" "blue-collar" ...
##  $ marital  : chr [1:45211] "married" "single" "married" "married" ...
##  $ education: chr [1:45211] "tertiary" "secondary" "secondary" "unknown" ...
##  $ default  : chr [1:45211] "no" "no" "no" "no" ...
##  $ balance  : num [1:45211] 2143 29 2 1506 1 ...
##  $ housing  : Factor w/ 2 levels "no","yes": 2 2 2 2 1 2 2 2 2 2 ...
##  $ loan     : chr [1:45211] "no" "no" "yes" "no" ...
##  $ contact  : chr [1:45211] "unknown" "unknown" "unknown" "unknown" ...
##  $ day      : num [1:45211] 5 5 5 5 5 5 5 5 5 5 ...
##  $ month    : chr [1:45211] "may" "may" "may" "may" ...
##  $ duration : num [1:45211] 261 151 76 92 198 139 217 380 50 55 ...
##  $ campaign : num [1:45211] 1 1 1 1 1 1 1 1 1 1 ...
##  $ pdays    : num [1:45211] -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 ...
##  $ previous : num [1:45211] 0 0 0 0 0 0 0 0 0 0 ...
##  $ poutcome : Factor w/ 4 levels "failure","other",..: 4 4 4 4 4 4 4 4 4 4 ...
##  $ y        : Factor w/ 2 levels "no","yes": 1 1 1 1 1 1 1 1 1 1 ...

Dataset terdiri dari 45211 observasi dengan 17 variabel.

Distribusi variabel respon: 5289 nasabah berlangganan deposito (yes) dan 39922 nasabah tidak berlangganan (no), sehingga proporsi nasabah yang berlangganan adalah 11.7%.

  • Pastikan tidak ada variabel yang bertipe chr — harus sudah Factor atau num sebelum masuk model.
  • Ketidakseimbangan kelas (proporsi yes vs no) yang sangat jauh (< 10% atau > 90%) perlu diperhatikan saat evaluasi akurasi.

2.1.2.3 Pembentukan Model

model_biner <- glm(
  y ~ duration + balance + campaign + housing + poutcome,
  data   = data2,
  family = binomial(link = "logit")
)

summary(model_biner)
## 
## Call:
## glm(formula = y ~ duration + balance + campaign + housing + poutcome, 
##     family = binomial(link = "logit"), data = data2)
## 
## Coefficients:
##                   Estimate Std. Error z value Pr(>|z|)    
## (Intercept)     -2.314e+00  5.752e-02 -40.227  < 2e-16 ***
## duration         3.922e-03  6.032e-05  65.021  < 2e-16 ***
## balance          2.489e-05  4.635e-06   5.370 7.86e-08 ***
## campaign        -1.101e-01  9.730e-03 -11.321  < 2e-16 ***
## housingyes      -1.053e+00  3.627e-02 -29.025  < 2e-16 ***
## poutcomeother    2.693e-01  8.532e-02   3.157   0.0016 ** 
## poutcomesuccess  2.315e+00  7.555e-02  30.642  < 2e-16 ***
## poutcomeunknown -6.512e-01  5.263e-02 -12.373  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 32631  on 45210  degrees of freedom
## Residual deviance: 23613  on 45203  degrees of freedom
## AIC: 23629
## 
## Number of Fisher Scoring iterations: 6

Model regresi logistik biner berhasil dibentuk dengan 8 parameter (termasuk intercept).

Null Deviance sebesar 3.263095^{4} menunjukkan deviasi model tanpa prediktor, sedangkan Residual Deviance sebesar 2.361339^{4} menunjukkan deviasi setelah prediktor dimasukkan. Penurunan deviance sebesar 9017.57 mengindikasikan bahwa prediktor yang digunakan mampu meningkatkan kemampuan model dalam menjelaskan data.

  • Estimate: koefisien log-odds. Positif artinya menaikkan peluang yes, negatif menurunkan.
  • Std. Error: semakin kecil semakin presisi estimasinya.
  • z value: rasio koefisien terhadap Std. Error. Makin besar (absolut), makin signifikan.
  • Pr(>|z|): p-value uji Wald. Variabel signifikan jika p-value < 0,05 (tanda *).
  • Tanda = sangat signifikan (p < 0,001), = p < 0,01, = p < 0,05.

2.1.2.4 Uji Kelayakan Model (Hosmer-Lemeshow)

H₀ : Model sesuai dengan data (tidak ada perbedaan signifikan antara nilai observasi dan prediksi).
H₁ : Model tidak sesuai dengan data.
Tolak H₀ jika p-value < 0,05.

hl_test <- hoslem.test(as.numeric(data2$y)-1, fitted(model_biner), g=10)
hl_test
## 
##  Hosmer and Lemeshow goodness of fit (GOF) test
## 
## data:  as.numeric(data2$y) - 1, fitted(model_biner)
## X-squared = 466.27, df = 8, p-value < 2.2e-16

Hasil Hosmer-Lemeshow Test menghasilkan statistik uji χ² = 466.2675 dengan derajat bebas 8 dan p-value = 0.

Karena p-value < 0,05, maka H₀ ditolak — model tidak sesuai dengan data, perlu dilakukan perbaikan model.

  • Uji ini membagi data menjadi 10 kelompok (g=10) berdasarkan nilai prediksi, lalu membandingkan frekuensi observasi vs ekspektasi per kelompok.
  • p-value yang besar (> 0,05) justru diinginkan — artinya tidak ada bukti ketidaksesuaian model.

2.1.2.5 Uji Signifikansi Simultan (Likelihood Ratio Test)

H₀ : Semua koefisien regresi = 0 (prediktor tidak berpengaruh).
H₁ : Minimal satu koefisien ≠ 0.
Tolak H₀ jika p-value < 0,05.

anova_biner <- anova(model_biner, test="Chisq")
anova_biner
## Analysis of Deviance Table
## 
## Model: binomial, link: logit
## 
## Response: y
## 
## Terms added sequentially (first to last)
## 
## 
##          Df Deviance Resid. Df Resid. Dev  Pr(>Chi)    
## NULL                     45210      32631              
## duration  1   5129.3     45209      27502 < 2.2e-16 ***
## balance   1     84.7     45208      27417 < 2.2e-16 ***
## campaign  1    285.6     45207      27131 < 2.2e-16 ***
## housing   1   1107.2     45206      26024 < 2.2e-16 ***
## poutcome  3   2410.8     45203      23613 < 2.2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Berdasarkan Likelihood Ratio Test secara simultan, variabel yang memberikan kontribusi signifikan terhadap model adalah: duration, balance, campaign, housing, poutcome.

Penambahan setiap variabel ke dalam model dievaluasi secara bertahap. Variabel yang menghasilkan penurunan deviance dengan p-value < 0,05 terbukti meningkatkan kemampuan prediksi model secara signifikan.

  • Deviance: penurunan deviance saat variabel ditambahkan — semakin besar semakin penting.
  • Pr(>Chi): p-value LRT per variabel. Signifikan jika < 0,05.
  • Berbeda dengan uji Wald (parsial), LRT mengevaluasi kontribusi tambahan tiap variabel secara sekuensial.

2.1.2.6 Odds Ratio

OR_b  <- exp(coef(model_biner))
CI_b  <- exp(confint(model_biner))

hasil_or <- data.frame(
  Variabel   = names(OR_b),
  Odds_Ratio = round(OR_b, 4),
  Lower_CI   = round(CI_b[,1], 4),
  Upper_CI   = round(CI_b[,2], 4)
)

kable(hasil_or, col.names=c("Variabel","Odds Ratio","Lower CI (95%)","Upper CI (95%)"),
      align=c("l","c","c","c")) |>
  kable_styling(bootstrap_options=c("striped","hover","condensed"), full_width=TRUE) |>
  column_spec(1, bold=TRUE, monospace=TRUE, color="#2F6B3E") |>
  column_spec(2, bold=TRUE) |>
  row_spec(0, background="#1A3220", color="white")
Variabel Odds Ratio Lower CI (95%) Upper CI (95%)
(Intercept) (Intercept) 0.0989 0.0883 0.1106
duration duration 1.0039 1.0038 1.0040
balance balance 1.0000 1.0000 1.0000
campaign campaign 0.8957 0.8785 0.9127
housingyes housingyes 0.3490 0.3250 0.3746
poutcomeother poutcomeother 1.3091 1.1065 1.5460
poutcomesuccess poutcomesuccess 10.1262 8.7377 11.7499
poutcomeunknown poutcomeunknown 0.5214 0.4706 0.5784

Interpretasi Odds Ratio (OR) menunjukkan perubahan peluang (odds) seorang nasabah berlangganan deposito (yes) dibandingkan tidak berlangganan (no) untuk setiap satu satuan kenaikan prediktor, dengan asumsi variabel lain tetap.

Variabel dengan OR tertinggi adalah poutcomesuccess (OR = 10.1262), artinya setiap kenaikan satu satuan poutcomesuccess meningkatkan odds berlangganan sebesar 912.6%.

Variabel dengan OR terendah adalah housingyes (OR = 0.349), yang artinya setiap kenaikan satu satuan menurunkan odds berlangganan sebesar 65.1%.

  • OR > 1: variabel meningkatkan peluang kejadian (yes).
  • OR < 1: variabel menurunkan peluang kejadian.
  • OR = 1: variabel tidak berpengaruh terhadap peluang.
  • CI yang tidak memuat angka 1 mengindikasikan OR signifikan secara statistik.
  • Untuk variabel kategorik, OR dibandingkan terhadap kategori referensi.

2.1.2.7 Evaluasi Model

2.1.2.7.1 Pseudo R-Square
pr2_biner <- pR2(model_biner)
## fitting null model for pseudo-r2
pr2_biner
##           llh       llhNull            G2      McFadden          r2ML 
## -1.180669e+04 -1.631548e+04  9.017569e+03  2.763502e-01  1.808231e-01 
##          r2CU 
##  3.517289e-01

Nilai McFadden Pseudo R² = 0.2764, yang berarti model mampu menjelaskan sekitar 27.6% variasi pada log-likelihood dibandingkan model tanpa prediktor.

Interpretasi: nilai McFadden 0,20–0,40 umumnya dianggap sebagai model dengan fit yang baik. Nilai saat ini menunjukkan model memiliki fit yang baik (0,20–0,40).

  • McFadden R²: 0,20–0,40 = fit baik; > 0,40 = fit sangat baik.
  • ML R² (Cox & Snell) dan Cragg-Uhler R²: analoginya seperti R² pada regresi linear.
  • Pseudo R² tidak identik dengan R² pada regresi linear — jangan diartikan sebagai “proporsi variansi yang dijelaskan” secara langsung.
2.1.2.7.2 AIC
aic_biner <- AIC(model_biner)
aic_biner
## [1] 23629.39

Nilai AIC model regresi logistik biner adalah 2.362939^{4}. AIC digunakan untuk membandingkan beberapa model — semakin kecil AIC, semakin baik model. Nilai ini menjadi acuan jika dilakukan seleksi atau perbandingan model alternatif.

  • AIC berguna untuk perbandingan antar model, bukan interpretasi tunggal.
  • Selisih ΔAIC > 2 sudah cukup untuk memilih model yang lebih baik.
2.1.2.7.3 Confusion Matrix & Accuracy
prob_b <- predict(model_biner, type="response")
pred_b <- ifelse(prob_b > 0.5, "yes", "no")

cm_b <- table(Aktual=data2$y, Prediksi=pred_b)
kable(as.data.frame.matrix(cm_b), caption="Confusion Matrix — Regresi Logistik Biner") |>
  kable_styling(bootstrap_options=c("striped","hover","condensed"), full_width=FALSE) |>
  row_spec(0, background="#1A3220", color="white")
Confusion Matrix — Regresi Logistik Biner
no yes
no 38994 928
yes 3656 1633
accuracy_b <- mean(pred_b == data2$y)
cat("Accuracy:", round(accuracy_b, 4))
## Accuracy: 0.8986

Model mengklasifikasikan dengan benar sebanyak 40627 dari 45211 observasi.

True Positive (TP): 1633 nasabah diprediksi yes dan memang yes.
True Negative (TN): 38994 nasabah diprediksi no dan memang no.
False Positive (FP): 928 nasabah diprediksi yes padahal no (kesalahan tipe I).
False Negative (FN): 3656 nasabah diprediksi no padahal yes (kesalahan tipe II).

Accuracy = 89.86% — model benar dalam 89.86% kasus.
Sensitivity = 30.88% — kemampuan mendeteksi nasabah yang benar-benar berlangganan.
Specificity = 97.68% — kemampuan mendeteksi nasabah yang tidak berlangganan.

  • Cutoff default 0,5 bisa disesuaikan jika kelas tidak seimbang.
  • Pada data tidak seimbang, perhatikan Sensitivity dan Specificity, bukan hanya Accuracy.
  • False Negative (nasabah potensial yang terlewat) bisa jadi lebih merugikan bisnis daripada False Positive.
2.1.2.7.4 ROC Curve dan AUC
roc_obj <- roc(response=data2$y, predictor=prob_b, levels=c("no","yes"))

plot(roc_obj,
     main="ROC Curve — Regresi Logistik Biner",
     col="#2F6B3E", lwd=2.5)
abline(a=0, b=1, lty=2, col="gray60")

auc_val <- auc(roc_obj)
auc_val
## Area under the curve: 0.8756

Nilai AUC (Area Under Curve) = 0.8756.

AUC sebesar 0.8756 berarti model memiliki probabilitas 87.6% untuk memberikan skor lebih tinggi pada nasabah yang benar-benar berlangganan dibandingkan yang tidak. Model ini tergolong baik (Good, AUC 0,80–0,90).

  • AUC = 0,5: model tidak lebih baik dari tebakan acak (garis diagonal).
  • AUC 0,70–0,80: cukup baik (Fair).
  • AUC 0,80–0,90: baik (Good).
  • AUC ≥ 0,90: sangat baik (Excellent).
  • Kurva ROC yang mendekati sudut kiri atas menunjukkan performa klasifikasi yang lebih baik.

2.2 Regresi Logistik Multinomial

2.2.1 Konsep

Regresi logistik multinomial memodelkan variabel respon dengan lebih dari dua kategori nominal. Model membentuk \((k-1)\) persamaan logit dibandingkan kategori referensi:

\[\ln \left(\frac{P(Y=j)}{P(Y=ref)}\right) = \beta_{0j}+\beta_{1j}X_1+\cdots+\beta_{pj}X_p, \quad j=1,\ldots,k-1\]


2.2.2 Kasus: Respons Terapi Kanker Tiroid

2.2.2.1 Persiapan Data

library(nnet)
data_t <- read.csv("C:/Users/Lenovo/Downloads/Thyroid_Diff.csv")

data_t$Response <- as.factor(data_t$Response)
data_t$Gender   <- as.factor(data_t$Gender)
data_t$N        <- as.factor(data_t$N)
data_t$Smoking  <- as.factor(data_t$Smoking)
data_t$Response <- relevel(data_t$Response, ref="Excellent")

kable(as.data.frame(table(data_t$Response)),
      col.names=c("Kategori Respon","Frekuensi"), align=c("l","c")) |>
  kable_styling(bootstrap_options=c("striped","hover","condensed"), full_width=FALSE) |>
  column_spec(1, bold=TRUE, color="#2F6B3E") |>
  row_spec(0, background="#1A3220", color="white")
Kategori Respon Frekuensi
Excellent 208
Biochemical Incomplete 23
Indeterminate 61
Structural Incomplete 91

Dataset terdiri dari 383 observasi. Kategori respon terbanyak adalah Excellent dengan 208 pasien (54.3%), yang menjadi dasar pemilihan kategori ini sebagai referensi. Model akan membentuk 3 persamaan logit yang masing-masing membandingkan kategori lain terhadap Excellent.

  • Kategori referensi sebaiknya dipilih yang paling umum atau paling bermakna secara substantif.
  • Semua interpretasi koefisien dan OR akan dibandingkan relatif terhadap kategori referensi ini.

2.2.2.2 Statistik Deskriptif

barplot(table(data_t$Response),
        main="Distribusi Kategori Respons Terapi",
        ylab="Frekuensi",
        col=c("#1A3220","#3D8B52","#6AAF7A","#A8D5B5"),
        border=NA, las=2)

Grafik di atas menunjukkan distribusi frekuensi kategori respons terapi pasien. Ketimpangan distribusi antar kategori perlu diperhatikan karena dapat memengaruhi stabilitas estimasi koefisien pada kategori dengan observasi sedikit.

2.2.2.3 Pembentukan Model

model_multi <- multinom(
  Response ~ Age + Gender + N + Smoking,
  data = data_t
)
## # weights:  28 (18 variable)
## initial  value 530.950740 
## iter  10 value 331.467129
## iter  20 value 327.807321
## final  value 327.806194 
## converged
summary(model_multi)
## Call:
## multinom(formula = Response ~ Age + Gender + N + Smoking, data = data_t)
## 
## Coefficients:
##                        (Intercept)        Age   GenderM     NN1a     NN1b
## Biochemical Incomplete   -4.568000 0.04587630 0.1388960 2.316448 1.221233
## Indeterminate            -3.030102 0.03419525 0.4967793 2.218744 1.627351
## Structural Incomplete    -4.709110 0.04809395 0.7506216 2.971610 4.110625
##                        SmokingYes
## Biochemical Incomplete  1.4793534
## Indeterminate           0.4083896
## Structural Incomplete   1.5348387
## 
## Std. Errors:
##                        (Intercept)        Age   GenderM      NN1a      NN1b
## Biochemical Incomplete   0.7525488 0.01526594 0.7474279 0.8000636 0.7088506
## Indeterminate            0.4992522 0.01090909 0.5094144 0.6102069 0.4502097
## Structural Incomplete    0.6275635 0.01235733 0.5226747 0.6862816 0.4365898
##                        SmokingYes
## Biochemical Incomplete  0.8073093
## Indeterminate           0.6715223
## Structural Incomplete   0.6425248
## 
## Residual Deviance: 655.6124 
## AIC: 691.6124

Model regresi logistik multinomial menghasilkan 3 set koefisien, masing-masing untuk perbandingan:

  • Biochemical Incomplete vs Excellent
  • Indeterminate vs Excellent
  • Structural Incomplete vs Excellent

Nilai Residual Deviance = 655.61 dan AIC = 691.61.

  • Setiap baris koefisien mewakili satu persamaan logit (satu perbandingan kategori vs referensi).
  • Tanda positif = meningkatkan log-odds berada di kategori tersebut vs referensi.
  • Std. errors digunakan untuk menghitung statistik z pada uji Wald parsial.

2.2.2.4 Uji Kelayakan Model & Simultan (LRT)

H₀ : Model tanpa prediktor sudah cukup (semua koefisien = 0).
H₁ : Model dengan prediktor lebih baik.
Tolak H₀ jika p-value < 0,05.

model_null_m <- multinom(Response~1, data=data_t, trace=FALSE)
LR_m  <- -2*(as.numeric(logLik(model_null_m))-as.numeric(logLik(model_multi)))
df_m  <- attr(logLik(model_multi),"df") - attr(logLik(model_null_m),"df")
pv_m  <- pchisq(LR_m, df=df_m, lower.tail=FALSE)

hasil_lrt_m <- data.frame(
  Statistik=c("Chi-Square","Derajat Bebas","P-Value"),
  Nilai=c(round(LR_m,4), df_m, round(pv_m,6))
)
kable(hasil_lrt_m, col.names=c("Statistik","Nilai"), align=c("l","c")) |>
  kable_styling(bootstrap_options=c("striped","hover","condensed"), full_width=FALSE) |>
  column_spec(1, bold=TRUE, color="#2F6B3E") |>
  row_spec(0, background="#1A3220", color="white")
Statistik Nilai
Chi-Square 213.4308
Derajat Bebas 15.0000
P-Value 0.0000

Likelihood Ratio Test menghasilkan statistik χ² = 213.4308 dengan derajat bebas 15 dan p-value = 0.

Karena p-value < 0,05, maka H₀ ditolak — minimal satu prediktor berpengaruh signifikan terhadap kategori respons terapi. Model dengan prediktor terbukti lebih baik dari model tanpa prediktor.

2.2.2.5 Uji Signifikansi Parsial (Wald Test)

H₀ : βij = 0  |  H₁ : βij ≠ 0
Variabel dengan p-value < 0,05 berpengaruh signifikan.

z_m <- summary(model_multi)$coefficients / summary(model_multi)$standard.errors
p_m <- 2*(1-pnorm(abs(z_m)))

kable(round(p_m,4), caption="P-Value Uji Wald Parsial") |>
  kable_styling(bootstrap_options=c("striped","hover","condensed"), full_width=TRUE) |>
  row_spec(0, background="#1A3220", color="white")
P-Value Uji Wald Parsial
(Intercept) Age GenderM NN1a NN1b SmokingYes
Biochemical Incomplete 0 0.0027 0.8526 0.0038 0.0849 0.0669
Indeterminate 0 0.0017 0.3295 0.0003 0.0003 0.5431
Structural Incomplete 0 0.0001 0.1510 0.0000 0.0000 0.0169

Berdasarkan uji Wald parsial, kombinasi persamaan-variabel yang berpengaruh signifikan (p-value < 0,05) adalah: Biochemical Incomplete ~ (Intercept); Indeterminate ~ (Intercept); Structural Incomplete ~ (Intercept); Biochemical Incomplete ~ Age; Indeterminate ~ Age; Structural Incomplete ~ Age; Biochemical Incomplete ~ NN1a; Indeterminate ~ NN1a; Structural Incomplete ~ NN1a; Indeterminate ~ NN1b; Structural Incomplete ~ NN1b; Structural Incomplete ~ SmokingYes.

Setiap sel pada tabel di atas menunjukkan p-value untuk koefisien prediktor tertentu pada persamaan logit tertentu (kategori vs referensi). Nilai p-value < 0,05 berarti variabel tersebut secara statistik berpengaruh signifikan terhadap log-odds berada di kategori tersebut dibandingkan Excellent.

  • Baris = kategori respon (vs referensi); Kolom = nama prediktor.
  • Setiap sel adalah p-value Wald independen — satu variabel bisa signifikan di satu kategori tapi tidak di kategori lain.

2.2.2.6 Odds Ratio

OR_m <- exp(coef(model_multi))
kable(round(OR_m,4), caption="Odds Ratio Regresi Logistik Multinomial") |>
  kable_styling(bootstrap_options=c("striped","hover","condensed"), full_width=TRUE) |>
  row_spec(0, background="#1A3220", color="white")
Odds Ratio Regresi Logistik Multinomial
(Intercept) Age GenderM NN1a NN1b SmokingYes
Biochemical Incomplete 0.0104 1.0469 1.1490 10.1396 3.3914 4.3901
Indeterminate 0.0483 1.0348 1.6434 9.1958 5.0904 1.5044
Structural Incomplete 0.0090 1.0493 2.1183 19.5233 60.9848 4.6406

Tabel Odds Ratio di atas menunjukkan perubahan peluang relatif berada di kategori respons tertentu dibandingkan kategori Excellent untuk setiap satu satuan perubahan prediktor.

OR > 1: prediktor meningkatkan peluang berada di kategori tersebut vs Excellent.
OR < 1: prediktor menurunkan peluang berada di kategori tersebut vs Excellent.
OR = 1: prediktor tidak berpengaruh terhadap perbandingan kategori tersebut vs Excellent.

  • Baris = kategori respon; Kolom = prediktor.
  • OR hanya bermakna jika koefisien yang bersangkutan signifikan secara parsial (p-value < 0,05).
  • Untuk variabel kategorik, OR dibandingkan terhadap level referensi variabel tersebut.

2.2.2.7 Evaluasi Model

2.2.2.7.1 Pseudo R-Square & AIC
pR2(model_multi)
## fitting null model for pseudo-r2
## # weights:  8 (3 variable)
## initial  value 530.950740 
## final  value 434.521594 
## converged
##          llh      llhNull           G2     McFadden         r2ML         r2CU 
## -327.8061944 -434.5215938  213.4307989    0.2455929    0.4272240    0.4764994
cat("AIC:", AIC(model_multi))
## AIC: 691.6124
## fitting null model for pseudo-r2
## # weights:  8 (3 variable)
## initial  value 530.950740 
## final  value 434.521594 
## converged

Nilai McFadden Pseudo R² = 0.2456, menunjukkan model menjelaskan sekitar 24.6% variasi log-likelihood. Model tergolong baik.

Nilai AIC = 691.61 digunakan sebagai tolok ukur perbandingan jika ada model alternatif — semakin kecil semakin baik.

2.2.2.7.2 Confusion Matrix & Accuracy
pred_m   <- predict(model_multi)
cm_m     <- table(Aktual=data_t$Response, Prediksi=pred_m)
acc_m    <- mean(pred_m == data_t$Response)

kable(as.data.frame.matrix(cm_m), caption="Confusion Matrix — Regresi Logistik Multinomial") |>
  kable_styling(bootstrap_options=c("striped","hover","condensed"), full_width=TRUE) |>
  row_spec(0, background="#1A3220", color="white")
Confusion Matrix — Regresi Logistik Multinomial
Excellent Biochemical Incomplete Indeterminate Structural Incomplete
Excellent 189 0 4 15
Biochemical Incomplete 14 0 3 6
Indeterminate 39 0 7 15
Structural Incomplete 17 0 3 71
cat("Accuracy:", round(acc_m,4))
## Accuracy: 0.6971

Model mengklasifikasikan dengan benar 69.71% dari seluruh observasi. Diagonal utama confusion matrix menunjukkan prediksi yang benar untuk setiap kategori. Sel di luar diagonal menunjukkan kesalahan klasifikasi antar kategori.

Perhatikan kategori dengan observasi sedikit — model cenderung lebih sulit mengklasifikasikan kategori minoritas dengan tepat.

  • Baris = kelas aktual; Kolom = kelas prediksi.
  • Diagonal = prediksi benar; off-diagonal = kesalahan klasifikasi.
  • Untuk data tidak seimbang, pertimbangkan juga per-class accuracy selain overall accuracy.

2.3 Regresi Logistik Ordinal

2.3.1 Konsep

Regresi logistik ordinal (Proportional Odds Model) digunakan untuk variabel respon dengan kategori berurutan:

\[\log \left(\frac{P(Y \le j)}{P(Y > j)}\right) = \alpha_j - (\beta_1X_1+\cdots+\beta_kX_k)\]


2.3.2 Kasus: Tingkat Obesitas

2.3.2.1 Persiapan Data

data_o  <- read.csv("C:/Users/Lenovo/Downloads/ObesityDataSet_raw_and_data_sinthetic.csv")
data2_o <- data_o
data2_o$NObeyesdad <- factor(data2_o$NObeyesdad, ordered=TRUE)
str(data2_o)
## 'data.frame':    2111 obs. of  17 variables:
##  $ Gender                        : chr  "Female" "Female" "Male" "Male" ...
##  $ Age                           : num  21 21 23 27 22 29 23 22 24 22 ...
##  $ Height                        : num  1.62 1.52 1.8 1.8 1.78 1.62 1.5 1.64 1.78 1.72 ...
##  $ Weight                        : num  64 56 77 87 89.8 53 55 53 64 68 ...
##  $ family_history_with_overweight: chr  "yes" "yes" "yes" "no" ...
##  $ FAVC                          : chr  "no" "no" "no" "no" ...
##  $ FCVC                          : num  2 3 2 3 2 2 3 2 3 2 ...
##  $ NCP                           : num  3 3 3 3 1 3 3 3 3 3 ...
##  $ CAEC                          : chr  "Sometimes" "Sometimes" "Sometimes" "Sometimes" ...
##  $ SMOKE                         : chr  "no" "yes" "no" "no" ...
##  $ CH2O                          : num  2 3 2 2 2 2 2 2 2 2 ...
##  $ SCC                           : chr  "no" "yes" "no" "no" ...
##  $ FAF                           : num  0 3 2 2 0 0 1 3 1 1 ...
##  $ TUE                           : num  1 0 1 0 0 0 0 0 1 1 ...
##  $ CALC                          : chr  "no" "Sometimes" "Frequently" "Frequently" ...
##  $ MTRANS                        : chr  "Public_Transportation" "Public_Transportation" "Public_Transportation" "Walking" ...
##  $ NObeyesdad                    : Ord.factor w/ 7 levels "Insufficient_Weight"<..: 2 2 2 6 7 2 2 2 2 2 ...

Dataset terdiri dari 2111 observasi. Variabel respon NObeyesdad bersifat ordinal dengan 7 kategori berurutan: Insufficient_Weight < Normal_Weight < Obesity_Type_I < Obesity_Type_II < Obesity_Type_III < Overweight_Level_I < Overweight_Level_II.

2.3.2.2 Pembentukan Model

library(MASS)
model_ord <- polr(
  NObeyesdad ~ Age + Height + Weight + FCVC + FAF,
  data=data2_o, Hess=TRUE
)
summary(model_ord)
## Call:
## polr(formula = NObeyesdad ~ Age + Height + Weight + FCVC + FAF, 
##     data = data2_o, Hess = TRUE)
## 
## Coefficients:
##           Value Std. Error t value
## Age     0.05349   0.006878   7.776
## Height -4.15456   0.539889  -7.695
## Weight  0.04063   0.002072  19.614
## FCVC   -0.44440   0.078116  -5.689
## FAF    -0.10139   0.049621  -2.043
## 
## Intercepts:
##                                        Value   Std. Error t value
## Insufficient_Weight|Normal_Weight      -5.7227  0.9081    -6.3016
## Normal_Weight|Obesity_Type_I           -4.4169  0.9004    -4.9055
## Obesity_Type_I|Obesity_Type_II         -3.3316  0.8990    -3.7058
## Obesity_Type_II|Obesity_Type_III       -2.6502  0.8983    -2.9502
## Obesity_Type_III|Overweight_Level_I    -1.9887  0.8976    -2.2157
## Overweight_Level_I|Overweight_Level_II -1.1927  0.8993    -1.3262
## 
## Residual Deviance: 7624.358 
## AIC: 7646.358

Model ordinal menghasilkan 5 koefisien regresi dan 6 threshold (intercept) yang memisahkan antar kategori. Nilai Residual Deviance = 7624.36.

  • Coefficients: koefisien prediktor — interpretasi relatif terhadap arah kenaikan kategori ordinal.
  • Intercepts (|): threshold pemisah antar kategori (misal: Normal|Overweight I).
  • t value: digunakan sebagai statistik z untuk uji Wald (distribusi normal besar).

2.3.2.3 Uji Kelayakan Model & Simultan (LRT)

H₀ : Model tanpa prediktor sudah cukup.
H₁ : Model dengan prediktor lebih baik.
Tolak H₀ jika p-value < 0,05.

model_null_o <- polr(NObeyesdad~1, data=data2_o, Hess=TRUE)
LR_o  <- 2*(as.numeric(logLik(model_ord))-as.numeric(logLik(model_null_o)))
df_o  <- attr(logLik(model_ord),"df")-attr(logLik(model_null_o),"df")
pv_o  <- pchisq(LR_o, df=df_o, lower.tail=FALSE)

hasil_lrt_o <- data.frame(
  Statistik=c("Chi-Square","Derajat Bebas","P-Value"),
  Nilai=c(round(LR_o,4), df_o, round(pv_o,6))
)
kable(hasil_lrt_o, col.names=c("Statistik","Nilai"), align=c("l","c")) |>
  kable_styling(bootstrap_options=c("striped","hover","condensed"), full_width=FALSE) |>
  column_spec(1, bold=TRUE, color="#2F6B3E") |>
  row_spec(0, background="#1A3220", color="white")
Statistik Nilai
Chi-Square 577.2705
Derajat Bebas 5.0000
P-Value 0.0000

Likelihood Ratio Test menghasilkan χ² = 577.2705, df = 5, p-value = 0.

Karena p-value < 0,05, H₀ ditolak — prediktor secara simultan berpengaruh signifikan terhadap tingkat obesitas. Model dengan prediktor jauh lebih baik dari model tanpa prediktor.

2.3.2.4 Uji Signifikansi Parsial (Wald)

H₀ : βi = 0  |  H₁ : βi ≠ 0

ctable_o <- coef(summary(model_ord))
p_o      <- 2*pnorm(abs(ctable_o[,"t value"]), lower.tail=FALSE)
hasil_w  <- cbind(ctable_o, "p value"=round(p_o,4))

kable(round(hasil_w,4), caption="Hasil Uji Wald Parsial") |>
  kable_styling(bootstrap_options=c("striped","hover","condensed"), full_width=TRUE) |>
  row_spec(0, background="#1A3220", color="white")
Hasil Uji Wald Parsial
Value Std. Error t value p value
Age 0.0535 0.0069 7.7759 0.0000
Height -4.1546 0.5399 -7.6952 0.0000
Weight 0.0406 0.0021 19.6144 0.0000
FCVC -0.4444 0.0781 -5.6889 0.0000
FAF -0.1014 0.0496 -2.0433 0.0410
Insufficient_Weight&#124;Normal_Weight -5.7227 0.9081 -6.3016 0.0000
Normal_Weight&#124;Obesity_Type_I -4.4169 0.9004 -4.9055 0.0000
Obesity_Type_I&#124;Obesity_Type_II -3.3316 0.8990 -3.7058 0.0002
Obesity_Type_II&#124;Obesity_Type_III -2.6502 0.8983 -2.9502 0.0032
Obesity_Type_III&#124;Overweight_Level_I -1.9887 0.8976 -2.2157 0.0267
Overweight_Level_I&#124;Overweight_Level_II -1.1927 0.8993 -1.3262 0.1848

Variabel yang berpengaruh signifikan terhadap tingkat obesitas (p-value < 0,05): Age, Height, Weight, FCVC, FAF.

Variabel yang tidak berpengaruh signifikan: tidak ada.

Baris dengan pemisah | (misal Normal Weight|Overweight Level I) adalah threshold antar kategori, bukan koefisien prediktor.

  • Value: estimasi koefisien. Positif = meningkatkan peluang berada di kategori lebih tinggi.
  • Std. Error: ketidakpastian estimasi.
  • t value: digunakan sebagai z-score untuk uji Wald (n besar).
  • p value: < 0,05 → variabel berpengaruh signifikan.

2.3.2.5 Odds Ratio

OR_o <- exp(coef(model_ord))
kable(data.frame(Variabel=names(OR_o), Odds_Ratio=round(OR_o,4)),
      col.names=c("Variabel","Odds Ratio"), align=c("l","c")) |>
  kable_styling(bootstrap_options=c("striped","hover","condensed"), full_width=FALSE) |>
  column_spec(1, bold=TRUE, monospace=TRUE, color="#2F6B3E") |>
  column_spec(2, bold=TRUE) |>
  row_spec(0, background="#1A3220", color="white")
Variabel Odds Ratio
Age Age 1.0549
Height Height 0.0157
Weight Weight 1.0415
FCVC FCVC 0.6412
FAF FAF 0.9036

Odds Ratio pada regresi ordinal mengukur perubahan cumulative odds berada pada kategori yang lebih tinggi (obesitas lebih berat).

Variabel Age memiliki OR tertinggi sebesar 1.0549 — setiap kenaikan satu satuan meningkatkan odds berada di tingkat obesitas lebih tinggi sebesar 5.5%.

Variabel Height memiliki OR terendah sebesar 0.0157 — setiap kenaikan satu satuan menurunkan odds berada di tingkat obesitas lebih tinggi sebesar 98.4%.

  • OR pada model ordinal berlaku untuk semua perbandingan kumulatif (asumsi proportional odds).
  • OR > 1: meningkatkan peluang berada di kategori obesitas lebih tinggi.
  • OR < 1: menurunkan peluang berada di kategori obesitas lebih tinggi.

2.3.2.6 Evaluasi Model

2.3.2.6.1 Pseudo R-Square & AIC
library(pscl)
pR2(model_ord)
## fitting null model for pseudo-r2
##           llh       llhNull            G2      McFadden          r2ML 
## -3.812179e+03 -4.100814e+03  5.772705e+02  7.038487e-02  2.392560e-01 
##          r2CU 
##  2.442743e-01
cat("AIC:", AIC(model_ord))
## AIC: 7646.358
## fitting null model for pseudo-r2

McFadden Pseudo R² = 0.0704 — model menjelaskan 7% variasi log-likelihood. Tergolong model perlu ditingkatkan.

AIC = 7646.36 — digunakan sebagai pembanding jika ada model alternatif (mis. dengan penambahan/pengurangan prediktor).

2.3.2.6.2 Confusion Matrix & Accuracy
pred_o <- predict(model_ord)
cm_o   <- table(Aktual=as.character(data2_o$NObeyesdad),
                Prediksi=as.character(pred_o))
acc_o  <- mean(as.character(pred_o)==as.character(data2_o$NObeyesdad))

kable(as.data.frame.matrix(cm_o), caption="Confusion Matrix — Regresi Logistik Ordinal") |>
  kable_styling(bootstrap_options=c("striped","hover","condensed"), full_width=TRUE) |>
  row_spec(0, background="#1A3220", color="white")
Confusion Matrix — Regresi Logistik Ordinal
Insufficient_Weight Normal_Weight Obesity_Type_I Overweight_Level_II
Insufficient_Weight 191 79 2 0
Normal_Weight 37 180 69 1
Obesity_Type_I 0 1 271 79
Obesity_Type_II 0 0 69 228
Obesity_Type_III 0 0 15 309
Overweight_Level_I 0 68 221 1
Overweight_Level_II 0 15 254 21
cat("Accuracy:", round(acc_o,4))
## Accuracy: 0.3141

Model ordinal mengklasifikasikan dengan benar 31.41% dari seluruh observasi. Pada model ordinal, kesalahan klasifikasi ke kategori yang berdekatan (misal prediksi Obesity Type I padahal Obesity Type II) umumnya lebih dapat diterima dibandingkan kesalahan ke kategori yang sangat jauh.

  • Pada model ordinal, perhatikan apakah kesalahan klasifikasi cenderung ke kategori yang berdekatan (acceptable) atau jauh (problematic).
  • Accuracy keseluruhan bisa rendah meski model baik jika jumlah kategori banyak dan distribusinya merata.

2.4 Regresi Poisson

2.4.1 Konsep

Regresi Poisson digunakan untuk data cacah (count data). Model:

\[\log(\mu_i) = \beta_0+\beta_1X_1+\cdots+\beta_kX_k\]

Interpretasi koefisien menggunakan Incidence Rate Ratio (IRR).


2.4.2 Kasus: Jumlah Penyewaan Sepeda

2.4.2.1 Persiapan Data

data_p  <- read.csv("C:/Users/Lenovo/Downloads/hour.csv")
data2_p <- data_p
data2_p$season     <- factor(data2_p$season)
data2_p$workingday <- factor(data2_p$workingday)
str(data2_p)
## 'data.frame':    17379 obs. of  17 variables:
##  $ instant   : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ dteday    : chr  "2011-01-01" "2011-01-01" "2011-01-01" "2011-01-01" ...
##  $ season    : Factor w/ 4 levels "1","2","3","4": 1 1 1 1 1 1 1 1 1 1 ...
##  $ yr        : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ mnth      : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ hr        : int  0 1 2 3 4 5 6 7 8 9 ...
##  $ holiday   : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ weekday   : int  6 6 6 6 6 6 6 6 6 6 ...
##  $ workingday: Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ...
##  $ weathersit: int  1 1 1 1 1 2 1 1 1 1 ...
##  $ temp      : num  0.24 0.22 0.22 0.24 0.24 0.24 0.22 0.2 0.24 0.32 ...
##  $ atemp     : num  0.288 0.273 0.273 0.288 0.288 ...
##  $ hum       : num  0.81 0.8 0.8 0.75 0.75 0.75 0.8 0.86 0.75 0.76 ...
##  $ windspeed : num  0 0 0 0 0 0.0896 0 0 0 0 ...
##  $ casual    : int  3 8 5 3 0 0 2 1 1 8 ...
##  $ registered: int  13 32 27 10 1 1 0 2 7 6 ...
##  $ cnt       : int  16 40 32 13 1 1 2 3 8 14 ...

Dataset terdiri dari 17379 observasi. Variabel respon cnt menunjukkan total penyewaan sepeda per jam, berkisar antara 1 hingga 977 dengan rata-rata 189.5 dan standar deviasi 181.4.

2.4.2.2 Pembentukan Model

model_pois <- glm(
  cnt ~ temp + hum + windspeed + season + workingday,
  data   = data2_p,
  family = poisson(link="log")
)
summary(model_pois)
## 
## Call:
## glm(formula = cnt ~ temp + hum + windspeed + season + workingday, 
##     family = poisson(link = "log"), data = data2_p)
## 
## Coefficients:
##              Estimate Std. Error z value Pr(>|z|)    
## (Intercept)  4.699984   0.003356 1400.37   <2e-16 ***
## temp         2.251489   0.004690  480.01   <2e-16 ***
## hum         -1.418151   0.003139 -451.78   <2e-16 ***
## windspeed    0.232609   0.004708   49.41   <2e-16 ***
## season2      0.123903   0.002178   56.88   <2e-16 ***
## season3     -0.081849   0.002616  -31.29   <2e-16 ***
## season4      0.451716   0.001959  230.55   <2e-16 ***
## workingday1  0.028958   0.001200   24.13   <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: 2891591  on 17378  degrees of freedom
## Residual deviance: 2046114  on 17371  degrees of freedom
## AIC: 2157031
## 
## Number of Fisher Scoring iterations: 5

Model regresi Poisson berhasil dibentuk dengan 8 parameter. Nilai Null Deviance = 2.8915914^{6} dan Residual Deviance = 2.046114^{6}. Penurunan deviance sebesar 8.4547739^{5} mengindikasikan prediktor mampu meningkatkan kemampuan model.

  • Estimate: koefisien log-rate. Positif = meningkatkan rata-rata jumlah kejadian.
  • Pr(>|z|): p-value Wald. Variabel signifikan jika < 0,05.
  • Perhatikan selisih Null Deviance vs Residual Deviance — semakin besar selisihnya, semakin besar kontribusi prediktor.

2.4.2.3 Uji Kelayakan Model

H₀ : Model sesuai dengan data.
H₁ : Model tidak sesuai dengan data.
Tolak H₀ jika p-value < 0,05.

pv_gof <- pchisq(model_pois$deviance, df=model_pois$df.residual, lower.tail=FALSE)

kable(data.frame(
  Statistik=c("Deviance","Derajat Bebas","P-Value"),
  Nilai=c(round(model_pois$deviance,4), model_pois$df.residual, round(pv_gof,6))
), col.names=c("Statistik","Nilai"), align=c("l","c")) |>
  kable_styling(bootstrap_options=c("striped","hover","condensed"), full_width=FALSE) |>
  column_spec(1, bold=TRUE, color="#2F6B3E") |>
  row_spec(0, background="#1A3220", color="white")
Statistik Nilai
Deviance 2046114
Derajat Bebas 17371
P-Value 0

Statistik deviance = 2.046114^{6} dengan df = 17371, menghasilkan p-value = 0.

Karena p-value < 0,05, H₀ ditolak — model tidak sesuai dengan data; kemungkinan terdapat overdispersi atau prediktor penting yang belum dimasukkan.

2.4.2.4 Uji Signifikansi Simultan

H₀ : Semua koefisien = 0.
H₁ : Minimal satu koefisien ≠ 0.

model_null_p <- glm(cnt~1, data=data2_p, family=poisson(link="log"))
anova(model_null_p, model_pois, test="Chisq")
## Analysis of Deviance Table
## 
## Model 1: cnt ~ 1
## Model 2: cnt ~ temp + hum + windspeed + season + workingday
##   Resid. Df Resid. Dev Df Deviance  Pr(>Chi)    
## 1     17378    2891591                          
## 2     17371    2046114  7   845477 < 2.2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Likelihood Ratio Test menghasilkan penurunan deviance sebesar 8.4547739^{5} dengan p-value = 0. Karena p-value < 0,05, H₀ ditolak — secara simultan minimal satu prediktor berpengaruh signifikan terhadap jumlah penyewaan sepeda.

2.4.2.5 Incidence Rate Ratio (IRR)

IRR_p  <- exp(coef(model_pois))
CI_p   <- exp(confint(model_pois))

hasil_IRR <- data.frame(
  Variabel = names(IRR_p),
  IRR      = round(IRR_p,4),
  Lower_CI = round(CI_p[,1],4),
  Upper_CI = round(CI_p[,2],4)
)

kable(hasil_IRR, col.names=c("Variabel","IRR","Lower CI (95%)","Upper CI (95%)"),
      align=c("l","c","c","c")) |>
  kable_styling(bootstrap_options=c("striped","hover","condensed"), full_width=TRUE) |>
  column_spec(1, bold=TRUE, monospace=TRUE, color="#2F6B3E") |>
  column_spec(2, bold=TRUE) |>
  row_spec(0, background="#1A3220", color="white")
Variabel IRR Lower CI (95%) Upper CI (95%)
(Intercept) (Intercept) 109.9454 109.2244 110.6709
temp temp 9.5019 9.4149 9.5896
hum hum 0.2422 0.2407 0.2437
windspeed windspeed 1.2619 1.2503 1.2736
season2 season2 1.1319 1.1271 1.1367
season3 season3 0.9214 0.9167 0.9261
season4 season4 1.5710 1.5650 1.5771
workingday1 workingday1 1.0294 1.0270 1.0318

IRR mengukur perubahan rata-rata jumlah penyewaan sepeda untuk setiap kenaikan satu satuan prediktor, dengan variabel lain dianggap konstan.

Variabel dengan IRR tertinggi adalah temp (IRR = 9.5019) — setiap kenaikan satu satuan meningkatkan rata-rata penyewaan sebesar 850.2%.

Variabel hum memiliki IRR terendah = 0.2422 — setiap kenaikan satu satuan menurunkan rata-rata penyewaan sebesar 75.8%.

Semua CI yang tidak mencakup angka 1 menunjukkan IRR yang signifikan secara statistik.

  • IRR > 1: prediktor meningkatkan rata-rata jumlah kejadian.
  • IRR < 1: prediktor menurunkan rata-rata jumlah kejadian.
  • IRR = 1: prediktor tidak berpengaruh terhadap rata-rata jumlah kejadian.
  • CI yang tidak memuat angka 1 → IRR signifikan secara statistik pada α = 0,05.
  • Untuk variabel kategorik, IRR dibandingkan terhadap kategori referensi.

2.4.2.6 Evaluasi Model

2.4.2.6.1 Pseudo R-Square & AIC
ll_f   <- as.numeric(logLik(model_pois))
ll_n   <- as.numeric(logLik(model_null_p))
pr2_p  <- 1-(ll_f/ll_n)
aic_p  <- AIC(model_pois)

cat("McFadden Pseudo R-Square:", round(pr2_p,4))
## McFadden Pseudo R-Square: 0.2816
cat("\nAIC:", round(aic_p,2))
## 
## AIC: 2157031

McFadden Pseudo R² = 0.2816 — model menjelaskan 28.2% variasi log-likelihood. AIC = 2.1570308^{6}.

2.4.2.6.2 Uji Overdispersi
dispersion_p <- sum(residuals(model_pois, type="pearson")^2) / model_pois$df.residual

kable(data.frame(
  Ukuran="Nilai Dispersi",
  Nilai=round(dispersion_p,4),
  Interpretasi=ifelse(abs(dispersion_p-1)<0.1,"Tidak ada overdispersi (≈ 1)",
               ifelse(dispersion_p>1,"Terdapat overdispersi (> 1)","Terdapat underdispersi (< 1)"))
), align=c("l","c","l")) |>
  kable_styling(bootstrap_options=c("striped","hover","condensed"), full_width=FALSE) |>
  column_spec(1, bold=TRUE, color="#2F6B3E") |>
  row_spec(0, background="#1A3220", color="white")
Ukuran Nilai Interpretasi
Nilai Dispersi 127.8894 Terdapat overdispersi (> 1)

Nilai dispersi Pearson = 127.8894.

Nilai jauh di atas 1 (127.89) — terdapat overdispersi. Varians data lebih besar dari rata-rata, melanggar asumsi Poisson. Disarankan untuk mempertimbangkan model Negative Binomial sebagai alternatif yang lebih robust.

  • Dispersi ≈ 1: asumsi Poisson terpenuhi — model valid.
  • Dispersi > 1 (overdispersi): varians > rata-rata → SE koefisien underestimated → p-value terlalu kecil. Solusi: Negative Binomial atau Quasi-Poisson.
  • Dispersi < 1 (underdispersi): varians < rata-rata → jarang terjadi, pertimbangkan Generalized Poisson.
  • Batas aman praktis: dispersi antara 0,9–1,1.

Analisis Data Kategorik — Shabrina Humairoh  ·  2026-06-02