Respons yang bernilai biner, seperti lulus dan tidak lulus, tidak dapat dimodelkan dengan garis lurus, sehingga fungsi glm() beserta keluarganya dibutuhkan. Topik ini memperkenalkan regresi logistik (logistic regression) sebagai anggota pertama generalized linear model, mulai dari data lulus dan tidak lulus, penyesuaian model dengan glm(family = binomial), pembacaan koefisien pada skala log-odds, konversinya menjadi odds ratio dengan exp(), hingga prediksi probabilitas dengan predict(). Batas interpretasinya dan arah pengembangan berikutnya ditutup di bagian akhir.
Keterbatasan regresi linear pada respons biner#
Misalnya pertanyaan diganti menjadi apakah seorang siswa lulus atau tidak, yang disimpan sebagai angka 0 dan 1. Menjalankan lm() atas respons semacam ini menghasilkan dua persoalan sekaligus. Pertama, garis model terus bergerak tanpa batas, sehingga prediksinya dapat keluar dari rentang probabilitas 0 sampai 1, misalnya 1,3 atau -0,2 yang tidak memiliki makna sebagai peluang. Kedua, residualnya membentuk dua pita terpisah karena responsnya hanya memiliki dua nilai, sehingga asumsi normalitas residual langsung runtuh.
Bentuk hubungan yang benar untuk probabilitas memang bukan garis lurus, melainkan kurva S yang mendekati nol di satu sisi dan mendekati satu di sisi lainnya, dengan daerah peralihan di tengahnya. Kurva S dicapai dengan menghubungkan rata-rata respons ke prediktor melalui fungsi tautan (link function), dan inilah gagasan inti generalized linear model. Ketika fungsi tautannya adalah logit, yaitu logaritma dari odds, modelnya disebut regresi logistik dan koefisiennya berada pada skala log-odds. Persamaan modelnya berbentuk
dengan sebagai probabilitas lulus, dan sisi kirinya disebut log-odds.
Data lulus dan tidak lulus#
Data contohnya berupa 40 siswa dengan jam belajar 1 sampai 8 jam per minggu. Probabilitas lulus tiap siswa disusun dari fungsi logistik plogis() dengan pola dasar -6,5 ditambah 1,15 kali jam belajar, kemudian hasil lulus atau tidaknya ditarik dengan rbinom(). Kolom lulus dibungkus factor() dengan urutan tingkat "Tidak" lalu "Lulus", karena model binomial di R menganggap tingkat kedua faktor sebagai keberhasilan yang dimodelkan.
library(tidyverse)
set.seed(2026)
n <- 40
nama <- c("Ali", "Budi", "Citra", "Dewi", "Eka", "Fajar", "Gita", "Hana", "Indra", "Joko",
"Kartika", "Laila", "Maya", "Nanda", "Oki", "Putri", "Rahmat", "Sari", "Tono", "Umar",
"Vina", "Wawan", "Yuni", "Zaki", "Bagas", "Dian", "Farhan", "Gading", "Halim", "Intan",
"Jefri", "Kirana", "Laras", "Mila", "Nadia", "Oscar", "Puspa", "Rizki", "Sinta", "Taufik")
jam <- round(runif(n, min = 1, max = 8), 1)
prob_lulus <- plogis(-6.5 + 1.15 * jam)
belajar <- tibble(
siswa = nama,
jam = jam,
lulus = factor(rbinom(n, size = 1, prob = prob_lulus), levels = c(0, 1), labels = c("Tidak", "Lulus"))
)
slice_head(belajar, n = 10)
count(belajar, lulus)── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr 1.2.1 ✔ readr 2.2.0
✔ forcats 1.0.1 ✔ stringr 1.6.0
✔ ggplot2 4.0.3 ✔ tibble 3.3.1
✔ lubridate 1.9.5 ✔ tidyr 1.3.2
✔ purrr 1.2.2
── 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
# A tibble: 10 × 3
siswa jam lulus
<chr> <dbl> <fct>
1 Ali 5.9 Lulus
2 Budi 4.9 Lulus
3 Citra 2 Tidak
4 Dewi 3 Tidak
5 Eka 4.9 Tidak
6 Fajar 1.2 Tidak
7 Gita 4.3 Lulus
8 Hana 7 Lulus
9 Indra 2.8 Tidak
10 Joko 5.1 Tidak
# A tibble: 2 × 2
lulus n
<fct> <int>
1 Tidak 30
2 Lulus 10Sepuluh baris pertama sudah memperlihatkan kecenderungannya, yaitu siswa dengan jam belajar tinggi seperti Ali dan Hana dinyatakan lulus, sedangkan siswa dengan jam belajar rendah tidak. Rekapitulasi menunjukkan 30 siswa tidak lulus dan 10 siswa lulus, sehingga responsnya benar-benar biner.
Menyesuaikan model dengan glm()#
Fungsi glm() menerima formula dan data seperti lm(), dengan tambahan argumen family = binomial yang menetapkan fungsi tautan logit untuk respons biner.
model_logistik <- glm(lulus ~ jam, data = belajar, family = binomial)
summary(model_logistik)
Call:
glm(formula = lulus ~ jam, family = binomial, data = belajar)
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -4.7059 1.4601 -3.223 0.00127 **
jam 0.8563 0.3014 2.841 0.00450 **
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 44.987 on 39 degrees of freedom
Residual deviance: 32.559 on 38 degrees of freedom
AIC: 36.559
Number of Fisher Scoring iterations: 5Struktur tabel koefisiennya serupa dengan lm(), tetapi kolom ujinya berganti dari t value menjadi z value karena estimasinya memakai metode maksimum likelihood dengan pendekatan normal. Koefisien jam sebesar 0,8563 berada pada skala log-odds, sehingga dibacanya adalah setiap tambahan satu jam belajar menaikkan log-odds kelulusan sekitar 0,86. Bagian deviance menggantikan peran R-squared sebagai ukuran ketidakcocokan model terhadap data. Null deviance 44,987 pada model tanpa prediktor turun menjadi residual deviance 32,559 dengan penurunan 12,43, dan AIC 36,559 menjadi acuan pembanding antar model dengan kompleksitas berbeda. Baris terakhir melaporkan lima iterasi Fisher scoring, yaitu prosedur numerik yang dijalankan glm() untuk menemukan estimasinya.
Dari log-odds ke odds ratio#
Log-odds memang sulit dipahami secara langsung, sehingga koefisiennya lazim dikonversi menjadi odds ratio dengan fungsi exp().
exp(coef(model_logistik))(Intercept) jam
0.009041696 2.354367417 Konversi exp() berarti odds, yaitu perbandingan peluang keberhasilan terhadap peluang kegagalan, mengalikan dirinya dengan faktor tertentu untuk setiap tambahan satu jam. Odds ratio jam sebesar 2,354 dibaca bahwa setiap tambahan satu jam belajar per minggu mengalikan odds kelulusan dengan 2,35 kali, dan konversi sebaliknya berlaku untuk koefisien negatif yang mengalikan odds dengan faktor di bawah satu. Nilai pada intersep, yaitu 0,009, merupakan odds kelulusan pada jam belajar nol, dan angka sekecil itu wajar karena tanpa belajar sama sekali, satu keberhasilan berbanding lebih dari seratus kegagalan. Dengan demikian, odds 2,35 berarti keberhasilan 2,35 kali lebih mungkin daripada kegagalannya.
Probabilitas lulus dengan predict()#
Prediksi probabilitas memerlukan argumen type = "response", karena tanpa argumen tersebut predict() mengembalikan nilai pada skala log-odds sebagaimana sisi kiri persamaan modelnya.
predict(model_logistik, newdata = tibble(jam = c(2, 4, 6, 8)), type = "response") 1 2 3 4
0.04772655 0.21741063 0.60628525 0.89513193 Probabilitas lulusnya naik dari 0,048 pada jam belajar 2, menjadi 0,217 pada jam 4, 0,606 pada jam 6, dan 0,895 pada jam 8. Kenaikannya tidak konstan, yaitu pelan di kedua ujung dan paling curam di daerah tengah sekitar jam 5,5, sesuai bentuk kurva S-nya. Konversi dari log-odds ke probabilitas inilah yang menjamin seluruh prediksi tetap berada di antara 0 dan 1.
Kurva logistik dan arah lanjutan#
Kurva probabilitasnya digambar dengan mengevaluasi prediksi model pada seratus titik jam belajar, lalu menimpanya pada titik data 0 dan 1.
kurva <- tibble(jam = seq(1, 8, length.out = 100))
kurva$prob <- predict(model_logistik, newdata = kurva, type = "response")
p <- ggplot(belajar, aes(x = jam, y = as.numeric(lulus == "Lulus"))) +
geom_point(size = 2, color = "#4472C4", alpha = 0.7) +
geom_line(data = kurva, aes(x = jam, y = prob), color = "#C0504D", linewidth = 1, inherit.aes = FALSE) +
labs(
x = "Jam belajar per minggu",
y = "Lulus (1) atau tidak (0)",
title = "Kurva probabilitas lulus dari regresi logistik"
) +
theme_minimal()
ggplot2::ggsave("kurva-logistik.svg", p, width = 5, height = 3.2)Kurva pada grafik memang berbentuk S dengan titik-titik data menempel pada ketinggian 0 dan 1, sehingga bentuk modelnya terlihat sesuai dengan sifat responsnya. Interpretasi koefisiennya tetap asosiatif pada data observasional, sama seperti regresi linear, sehingga klaim kausal tidak dapat ditegakkan dari model ini saja.
Regresi logistik ini hanyalah satu anggota generalized linear model. Ganti argumen family menjadi poisson untuk respons berupa hitungan, atau Gamma untuk respons positif dengan sebaran condong, dan seluruh kerangka formula, summary(), serta predict() tetap dipakai tanpa perubahan.
Ringkasan#
- Respons biner tidak cocok untuk
lm()karena prediksinya keluar dari rentang probabilitas dan residualnya membentuk dua pita terpisah, sehingga modelnya diganti melalui fungsi tautan logit. glm(lulus ~ jam, data = belajar, family = binomial)menyesuaikan regresi logistik, dengan tingkat kedua faktor sebagai keberhasilan yang dimodelkan.- Koefisien berada pada skala log-odds, dan
exp(coef(model))mengonversinya menjadi odds ratio, yaitu 2,354 kali per tambahan satu jam belajar. predict()dengantype = "response"mengembalikan probabilitas, sedangkan tanpa argumen itu keluarannya berupa log-odds.- Keluarga
glm()lain seperti poisson memakai kerangka yang sama untuk tipe respons yang berbeda.
Referensi#
- An Introduction to R — CRAN — Bab Generalized linear models pada dokumen yang sama merinci argumen family dan keluarga binomial untuk glm().
- R for Data Science, edisi ke-2 — Wickham, Çetinkaya-Rundel, Grolemund — Bab model memperkenalkan generalisasi model di luar regresi linear beserta alat pembacanya.