Dokumen ini disusun sebagai modul praktikum dan e-book pembelajaran Regresi Logistik Biner, Multinomial, Ordinal, dan Poisson.
Setelah mempelajari modul ini mahasiswa mampu:
| Metode | Jenis Y |
|---|---|
| Logistik Biner | 2 kategori |
| Logistik Multinomial | >2 kategori nominal |
| Logistik Ordinal | >2 kategori berurutan |
| Poisson | Data cacahan |
Regresi logistik biner digunakan ketika variabel respon hanya memiliki dua kategori.
Status Kemiskinan Provinsi Indonesia Tahun 2025.
| Variabel | Keterangan |
|---|---|
| Y | Status Kemiskinan |
| X1 | IPM |
| X2 | TPT |
| X3 | RLS |
\[ p(x)=\frac{e^{\beta_0+\beta_1X_1+\beta_2X_2+\beta_3X_3}} {1+e^{\beta_0+\beta_1X_1+\beta_2X_2+\beta_3X_3}} \]
\[ \log\left(\frac{p}{1-p}\right)= \beta_0+\beta_1X_1+\beta_2X_2+\beta_3X_3 \]
# REGRESI LOGISTIK BINER
# Status Kemiskinan Provinsi di Indonesia
#======================================================
# Install package (jalankan sekali saja jika belum ada)
install.packages(c("car","ResourceSelection","pscl"))
# Memanggil package
library(car)
library(ResourceSelection)
library(pscl)
#======================================================
# 1. IMPORT DATA
#======================================================
data = read.csv(file.choose(), sep = ",", dec = ".", header = TRUE)
data
# Struktur data
str(data)
# Ringkasan data
summary(data)
#======================================================
# 2. UBAH VARIABEL RESPON MENJADI FAKTOR
#======================================================
data$Status.Kemiskinan..Y. <- factor(
data$Status.Kemiskinan..Y.,
levels = c(0,1),
labels = c("Rendah","Tinggi")
)
# Distribusi kategori
table(data$Status.Kemiskinan..Y.)
prop.table(table(data$Status.Kemiskinan..Y.))*100
#======================================================
# 3. STATISTIK DESKRIPTIF
#======================================================
summary(data[, c("IPM..X1.","TPT..X2.","RLS..X3.")])
sapply(data[,c("IPM..X1.","TPT..X2.","RLS..X3.")], sd)
#======================================================
# 4. VISUALISASI
#======================================================
boxplot(data$IPM..X1. ~ data$Status.Kemiskinan..Y.,
data = data,
main = "IPM vs Status Kemiskinan")
boxplot(data$TPT..X2. ~ data$Status.Kemiskinan..Y.,
data = data,
main = "TPT vs Status Kemiskinan")
boxplot(data$RLS..X3. ~ data$Status.Kemiskinan..Y.,
data = data,
main = "RLS vs Status Kemiskinan")
#======================================================
# 5. UJI MULTIKOLINEARITAS
#======================================================
model_vif <- lm(
as.numeric(data$Status.Kemiskinan..Y.) ~ data$IPM..X1. + data$TPT..X2. + data$RLS..X3.,
data = data
)
vif(model_vif)
#======================================================
# 6. PEMODELAN REGRESI LOGISTIK BINER
#======================================================
model <- glm(
data$Status.Kemiskinan..Y. ~ data$IPM..X1. + data$TPT..X2. + data$RLS..X3.,
family = binomial(link = "logit"),
data = data
)
summary(model)
#======================================================
# 7. UJI SIMULTAN
# (LIKELIHOOD RATIO TEST)
#======================================================
model_null <- glm(
data$Status.Kemiskinan..Y. ~ 1,
family = binomial,
data = data
)
anova(
model_null,
model,
test = "Chisq"
)
#======================================================
# 8. UJI PARSIAL (WALD TEST)
#======================================================
summary(model)
#======================================================
# 9. ODDS RATIO
#======================================================
exp(coef(model))
exp(
cbind(
Odds_Ratio = coef(model),
confint(model)
)
)
#======================================================
# 10. GOODNESS OF FIT
# HOSMER-LEMESHOW TEST
#======================================================
hoslem.test(
as.numeric(data$Status.Kemiskinan..Y.)-1,
fitted(model)
)
#======================================================
# 11. PSEUDO R-SQUARE
#======================================================
pR2(model)
#======================================================
# 12. PREDIKSI PROBABILITAS
#======================================================
data$Probabilitas <- predict(
model,
type = "response"
)
head(data$Probabilitas)
#======================================================
# 13. KLASIFIKASI
#======================================================
data$Prediksi <- ifelse(
data$Probabilitas > 0.5,
"Tinggi",
"Rendah"
)
table(
Aktual = data$Status.Kemiskinan..Y.,
Prediksi = data$Prediksi
)
#======================================================
# 14. AKURASI MODEL
#======================================================
conf <- table(
Aktual = data$Status.Kemiskinan..Y.,
Prediksi = data$Prediksi
)
akurasi <- sum(diag(conf))/sum(conf)
cat("Akurasi Model =", round(akurasi*100,2), "%\n")
#======================================================
# 15. MODEL AKHIR
#======================================================
coef(model)
cat("\nPersamaan Logit:\n")
cat(
"log(p/(1-p)) =",
round(coef(model)[1],4),
ifelse(coef(model)[2] >= 0," + "," "),
round(coef(model)[2],4),"IPM",
ifelse(coef(model)[3] >= 0," + "," "),
round(coef(model)[3],4),"TPT",
ifelse(coef(model)[4] >= 0," + "," "),
round(coef(model)[4],4),"RLS\n"
)
#======================================================
# 16. TABEL HASIL KOEFISIEN
#======================================================
hasil <- data.frame(
Koefisien = coef(model),
Odds_Ratio = exp(coef(model)),
p_value = summary(model)$coefficients[,4]
)
round(hasil,4)Jika p-value < 0,05 maka minimal terdapat satu variabel yang berpengaruh signifikan.
Jika p-value variabel < 0,05 maka variabel berpengaruh signifikan.
OR > 1 → meningkatkan peluang kejadian.
OR < 1 → menurunkan peluang kejadian.
p-value > 0,05 → model sesuai.
Digunakan ketika respon memiliki lebih dari dua kategori dan tidak memiliki urutan.
Preferensi Karier Mahasiswa.
Y : Career Preference
X:
\[ \log\left( \frac{P(Y=j)} {P(Y=referensi)} \right) = \beta_{0j}+ \beta_{1j}X_1+ \beta_{2j}X_2+ \beta_{3j}X_3+ \beta_{4j}X_4+ \beta_{5j}X_5 \]
REGRESI LOGISTIK MULTINOMIAL
# DATASET: college_student_career_preference_dataset.csv
# =========================================================
# Install package (jalankan sekali saja jika belum ada)
install.packages("nnet")
install.packages("caret")
install.packages("pscl")
library(nnet)
library(caret)
library(pscl)
# =========================================================
# IMPORT DATA
# =========================================================
data = read.csv(file.choose(), sep = ",", dec = ".", header = TRUE)
# =========================================================
# CEK DATA
# =========================================================
cat("\n===== STRUKTUR DATA =====\n")
str(data)
cat("\n===== RINGKASAN DATA =====\n")
summary(data)
cat("\n===== JUMLAH OBSERVASI =====\n")
print(nrow(data))
cat("\n===== DISTRIBUSI KATEGORI Y =====\n")
print(table(data$Career_Preference))
# =========================================================
# PERSIAPAN DATA
# =========================================================
data$Career_Preference <- as.factor(data$Career_Preference)
# Set kategori referensi otomatis
data$Career_Preference <- relevel(
data$Career_Preference,
ref = levels(data$Career_Preference)[1]
)
# =========================================================
# PEMBENTUKAN MODEL MULTINOMIAL
# =========================================================
model_multinom <- multinom(
Career_Preference ~
GPA +
Math_Score +
Programming_Skill +
Analytical_Skill +
Communication_Skill,
data = data,
trace = FALSE
)
# =========================================================
# HASIL MODEL
# =========================================================
cat("\n===== HASIL ESTIMASI PARAMETER =====\n")
print(summary(model_multinom))
# =========================================================
# UJI WALD (UJI PARSIAL)
# =========================================================
z_value <- summary(model_multinom)$coefficients /
summary(model_multinom)$standard.errors
p_value <- 2 * (1 - pnorm(abs(z_value)))
cat("\n===== P-VALUE UJI WALD =====\n")
print(round(p_value, 5))
# =========================================================
# ODDS RATIO
# =========================================================
OR <- exp(coef(model_multinom))
cat("\n===== ODDS RATIO =====\n")
print(round(OR, 4))
# =========================================================
# PSEUDO R-SQUARE
# =========================================================
null_model <- multinom(
Career_Preference ~ 1,
data = data,
trace = FALSE
)
LL_full <- as.numeric(logLik(model_multinom))
LL_null <- as.numeric(logLik(null_model))
McFadden_R2 <- 1 - (LL_full / LL_null)
cat("\n===== PSEUDO R-SQUARE =====\n")
print(round(McFadden_R2, 4))
# =========================================================
# LIKELIHOOD RATIO TEST
# =========================================================
LR <- -2 * (LL_null - LL_full)
df_LR <- attr(logLik(model_multinom), "df") -
attr(logLik(null_model), "df")
p_LR <- pchisq(LR, df_LR, lower.tail = FALSE)
cat("\n===== LIKELIHOOD RATIO TEST =====\n")
cat("Chi-Square :", round(LR,4), "\n")
cat("df :", df_LR, "\n")
cat("p-value :", round(p_LR,6), "\n")
# =========================================================
# PREDIKSI
# =========================================================
prediksi <- predict(
model_multinom,
newdata = data,
type = "class"
)
# =========================================================
# CONFUSION MATRIX
# =========================================================
cat("\n===== CONFUSION MATRIX =====\n")
cm <- confusionMatrix(
as.factor(prediksi),
as.factor(data$Career_Preference)
)
print(cm)
# =========================================================
# AKURASI MODEL
# =========================================================
cat("\n===== AKURASI MODEL =====\n")
print(cm$overall["Accuracy"])
# =========================================================
# PREDIKSI DISIMPAN KE DATA
# =========================================================
data$Prediksi_Karier <- prediksi
cat("\n===== 10 HASIL PREDIKSI PERTAMA =====\n")
print(head(data[, c("Career_Preference",
"Prediksi_Karier")], 10))Koefisien dibandingkan terhadap kategori referensi.
Odds Ratio menjelaskan kecenderungan memilih suatu kategori dibanding kategori referensi.
Digunakan ketika kategori respon memiliki urutan.
Tingkat Formalitas Tenaga Kerja Provinsi Indonesia Tahun 2024.
\[ \log\left( \frac{P(Y \le j)} {P(Y>j)} \right) = \theta_j- (\beta_1X_1+\beta_2X_2+\beta_3X_3+\beta_4X_4) \]
REGRESI ORDINAL
# ==============================================================================
# 1. INSTALASI DAN LOADING PACKAGES (Otomatis)
packages <- c("MASS", "brant", "lmtest")
install_if_missing <- function(p) {
if (!require(p, character.only = TRUE)) {
install.packages(p, dependencies = TRUE)
library(p, character.only = TRUE)
}
}
invisible(sapply(packages, install_if_missing))
# 2. MEMBACA DATASET
cat("Silakan pilih file 'RegresiOrdinal.csv' pada jendela dokumen yang muncul...\n")
data_raw <- read.csv(file.choose(), sep = ",", dec = ".", header = TRUE)
# 3. CLEANING & PENYELARASAN NAMA KOLOM
colnames(data_raw) <- c("Provinsi", "TK_Formal", "Tingkat_Formalitas", "IPM", "TPT", "Miskin", "RLS")
# Mengubah Variabel Dependen menjadi Faktor Ordinal (Berurutan)
data_raw$Tingkat_Formalitas <- factor(data_raw$Tingkat_Formalitas,
levels = c("Rendah", "Sedang", "Tinggi"),
ordered = TRUE)
# ==============================================================================
# 4. PEMBENTUKAN MODEL REGRESI ORDINAL (HESSIAN DIAPUS)
# ==============================================================================
cat("\n--- MEMBENTUK MODEL REGRESI ORDINAL ---\n")
# Di sini MASS::polr dipanggil TANPA Hessian agar tidak memicu error optimasi lagi
model_ordinal <- MASS::polr(Tingkat_Formalitas ~ IPM + TPT + Miskin + RLS,
data = data_raw)
# Tampilkan ringkasan dasar model
print(summary(model_ordinal))
# 5. MENAMPILKAN RINGKASAN MODEL & P-VALUE (MENGGUNAKAN COEFTEST)
# Karena Hessian dihapus, p-value dicari secara otomatis lewat fungsi coeftest()
cat("\n--- RINGKASAN MODEL & SIGNIFIKANSI PARSIAL (UJI T) ---\n")
summary_table <- coeftest(model_ordinal)
print(summary_table)
# ==============================================================================
# 6. UJI SIMULTAN / SERENTAK (G-TEST / LIKELIHOOD RATIO TEST)
# ==============================================================================
cat("\n--- UJI SERENTAK / SIMULTAN (LIKELIHOOD RATIO TEST) ---\n")
model_null <- MASS::polr(Tingkat_Formalitas ~ 1, data = data_raw)
uji_simultan <- lrtest(model_null, model_ordinal)
print(uji_simultan)
# ==============================================================================
# 7. ODDS RATIO (OR) DAN CONFIDENCE INTERVAL (CI)
# ==============================================================================
cat("\n--- ODDS RATIO & CONFIDENCE INTERVAL (95%) ---\n")
odds_ratio <- exp(coef(model_ordinal))
confidence_interval <- exp(confint.default(model_ordinal))
or_table <- cbind(Odds_Ratio = odds_ratio, confidence_interval)
print(or_table)
# ==============================================================================
# 8. UJI ASUMSI PARALLEL LINES (BRANT TEST)
# ==============================================================================
cat("\n--- UJI ASUMSI PARALLEL LINES (BRANT TEST) ---\n")
uji_brant <- brant(model_ordinal)
print(uji_brant)Diuji menggunakan Brant Test.
p-value > 0,05 menunjukkan asumsi terpenuhi.
Digunakan untuk data cacahan.
Jumlah Tindak Pidana.
\[ \log(\mu_i)= \beta_0+\beta_1X_1+\beta_2X_2+\beta_3X_3+\log(offset) \]
REGRESI POISSON
# ==========================
# Import data
data <- read.csv(file.choose(), sep = ",", dec = ".", header = TRUE)
# Lihat struktur data
str(data)
summary(data)
# Membuat variabel offset
data$ln_penduduk <- log(data$JUMLAH.PENDUDUK..offset.)
# ==========================
# PEMBENTUKAN MODEL
# ==========================
model_poisson <- glm(
data$JUMLAH.TINDAK.PIDANA..Y. ~ data$TPT..X1. + data$X..PENDUDUK.MISKIN..X2. + data$KEPADATAN.PENDUDUK..X3. +
offset(data$ln_penduduk),
family = poisson(link = "log"),
data = data
)
# ==========================
# HASIL MODEL
# ==========================
summary(model_poisson)
# ==========================
# UJI SIGNIFIKANSI MODEL
# ==========================
anova(model_poisson, test = "Chisq")
# ==========================
# IRR (INCIDENCE RATE RATIO)
# ==========================
IRR <- exp(coef(model_poisson))
IRR
# Confidence Interval IRR
exp(confint(model_poisson))
# ==========================
# GOODNESS OF FIT
# ==========================
deviance(model_poisson)
df.residual(model_poisson)
# Rasio deviance terhadap derajat bebas
deviance(model_poisson) / df.residual(model_poisson)
# ==========================
# CEK OVERDISPERSION
# ==========================
dispersion <- sum(residuals(model_poisson,
type = "pearson")^2) /
model_poisson$df.residual
dispersion
if(dispersion > 1.5){
print("Terdapat indikasi overdispersion")
} else {
print("Tidak terdapat overdispersion yang serius")
}
# ==========================
# PREDIKSI
# ==========================
data$Prediksi <- predict(
model_poisson,
type = "response"
)
head(data)
# ==========================
# AIC MODEL
# ==========================
AIC(model_poisson)
# ==========================
# RINGKASAN HASIL
# ==========================
cat("\n===== HASIL REGRESI POISSON =====\n")
cat("AIC :", AIC(model_poisson), "\n")
cat("Dispersion :", dispersion, "\n")
cat("Deviance/df :",
deviance(model_poisson) /
df.residual(model_poisson), "\n")
cat("\n===== IRR =====\n")
print(IRR)IRR = exp(beta)
IRR > 1 → meningkatkan laju kejadian.
IRR < 1 → menurunkan laju kejadian.
| Metode | Y | Parameter |
|---|---|---|
| Biner | 2 kategori | Odds Ratio |
| Multinomial | Nominal | Odds Ratio |
| Ordinal | Berurutan | Odds Ratio |
| Poisson | Count | IRR |