Chapter sebelumnya memperlihatkan model linier menghasilkan probabilitas seperti 0,5041 untuk email di batas keputusan. Pertanyaannya: bagaimana sebuah model yang “linier” bisa mengeluarkan angka antara 0 dan 1? Jawabannya ada pada satu fungsi kecil bernama sigmoid yang menjepit hasil hitungan linier ke rentang probabilitas. Regresi logistik — meski bernama “regresi” — adalah algoritme klasifikasi binier paling fundamental: cepat, dapat diinterpretasikan, dan menjadi fondasi bagi jaringan saraf modern. Kita akan membedah sigmoidnya, memahami fungsi biayanya, lalu membaca koefisien model sebagai perubahan log-odds pada kisah deteksi spam kita.

Dari Garis Linier ke Probabilitas #

Langkah pertama regresi logistik masih murni aljabar linear — materi Chapter Aljabar Linear untuk Machine Learning. Untuk setiap email, model menghitung sebuah skor mentah lewat perkalian titik antara vektor bobot w dan vektor fitur x:

text
z = w·x + b = w₁x₁ + w₂x₂ + b

Skor z bisa bernilai apa pun, dari negatif tak terbatas hingga positif tak terbatas. Fungsi sigmoid (disebut juga logistic function) kemudian menjepit skor tersebut ke rentang (0, 1):

text
σ(z) = 1 / (1 + e^(-z))

Sifat-sifat sigmoid mudah dibaca dari rumusnya. Ketika z = 0, hasilnya tepat 0,5 — titik paling ragu-ragu, persis di batas keputusan. Ketika z membesar positif, suku e^(-z) menuju 0 sehingga σ(z) menempel di 1. Ketika z membesar negatif, σ(z) menempel di 0. Sigmoid juga berbentuk S simetris: σ(-z) = 1 - σ(z). Probabilitas kelas spam adalah σ(z), dan probabilitas kelas ham otomatis 1 - σ(z).

zσ(z)Makna
-40,018Nyaris pasti kelas 0
-20,119Sangat condong kelas 0
00,500Tepat di batas keputusan
20,881Sangat condong kelas 1
40,982Nyaris pasti kelas 1

Mengapa Bukan MSE #

Pada Section Regresi kita memakai mean squared error (MSE) sebagai fungsi biaya. Untuk klasifikasi, MSE kurang cocok. Target kita kini bernilai 0 atau 1, sedangkan keluaran sigmoid selalu berada di antara keduanya; mengkuadratkan selisihnya memberi penalti yang landai justru pada prediksi yang salah dengan pede — kesalahan paling berbahaya. Kombinasi sigmoid + MSE juga menghasilkan permukaan biaya yang tidak konveks sehingga optimasi mudah tersangkut di solusi lokal.

Regresi logistik memakai log-loss (logaritma likelihood negatif): prediksi benar dengan probabilitas tinggi nyaris tanpa biaya, tetapi satu prediksi salah yang pede (misalnya memastikan email sebagai spam dengan probabilitas 0,99 padahal bukan) dihukum dengan biaya yang melonjak tanpa batas. Perilaku asimetris inilah yang kita inginkan dari model probabilistik. Perhitungan detail log-loss akan kita bahas di Section Evaluasi dan Validasi Model; untuk sekarang, cukup pahami alasan pemilihannya.

Koefisien sebagai Log-Odds #

Keunggulan praktis regresi logistik adalah koefisienya dapat dibaca. Definisikan odds sebagai p/(1-p) — perbandingan peluang spam terhadap ham. Logaritma odds, disebut log-odds, ternyata linier terhadap fitur:

text
ln(p / (1 - p)) = w·x + b

Akibatnya, koefisien w_j berarti: setiap kenaikan satu satuan fitur ke-j menambah log-odds sebesar w_j, dengan fitur lain tetap. Sebuah koefisien +2,64 pada fitur frekuensi_kata_promosi setara dengan mengalikan odds spam dengan e^2,64 ≈ 14 setiap satu kenaikan satuan. Tafsiran multipel seperti ini tidak dimiliki oleh label keras dari k-nearest neighbors — itulah alasan regresi logistik tetap populer sebagai model dasar yang bisa diaudit.

Regularisasi dan Parameter C #

Seperti regresi linier, regresi logistik rawan overfitting ketika jumlah fiturnya besar sementara data latihnya sedikit — koefisien bebas membesar demi mengejar tiap titik. Solusinya pun serupa: regularisasi L2 menambahkan penalti kuadrat koefisien ke fungsi biaya — persis mekanisme Ridge pada Chapter Regularisasi: Ridge, Lasso, dan Elastic Net.

Sekarang kita rakit semua konsep di atas menjadi satu contoh teruji: melatih regresi logistik pada 60 email sintetis, mencetak parameternya, lalu membuktikan bahwa predict_proba benar-benar hanyalah sigmoid dari hasil kali titik.

python
# Regresi logistik: sigmoid, koefisien sebagai log-odds, dan verifikasi manual.
# Data sintetis 60 email dengan dua fitur, kelanjutan kisah deteksi spam.

import numpy as np
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split

nama_fitur = ["rasio_tautan", "frekuensi_kata_promosi"]

X, y = make_classification(
    n_samples=60,
    n_features=2,
    n_informative=2,
    n_redundant=0,
    n_clusters_per_class=1,
    random_state=42,
)

X_latih, X_uji, y_latih, y_uji = train_test_split(
    X, y, test_size=0.25, random_state=42, stratify=y
)

model = LogisticRegression(random_state=42)
model.fit(X_latih, y_latih)

print("Parameter model terlatih:")
print(f"  intercept (b)      : {model.intercept_[0]:+.4f}")
for nama, koef in zip(nama_fitur, model.coef_[0]):
    print(f"  koefisien {nama:<22}: {koef:+.4f}")

# Verifikasi: hitung sigmoid secara manual untuk satu email latih,
# lalu bandingkan dengan predict_proba. Keduanya harus identik.
titik = X_latih[0]
z = model.intercept_[0] + model.coef_[0] @ titik
sigmoid_manual = 1.0 / (1.0 + np.exp(-z))
sigmoid_sklearn = model.predict_proba(titik.reshape(1, -1))[0, 1]

print("\nVerifikasi sigmoid untuk satu email latih:")
print(f"  z = b + w.x                      : {z:+.4f}")
print(f"  sigmoid manual 1/(1+e^-z)        : {sigmoid_manual:.6f}")
print(f"  model.predict_proba(...)[spam]   : {sigmoid_sklearn:.6f}")

print("\nTabel sigmoid untuk beberapa nilai z:")
print("    z    |  sigma(z)")
for nilai_z in range(-4, 5):
    sigma = 1.0 / (1.0 + np.exp(-nilai_z))
    print(f"  {nilai_z:>4d}   |  {sigma:.4f}")

akurasi = model.score(X_uji, y_uji)
print(f"\nAkurasi data uji: {akurasi:.3f}")

Output yang Dihasilkan:

text
Parameter model terlatih:
  intercept (b)      : +0.2556
  koefisien rasio_tautan          : +0.4043
  koefisien frekuensi_kata_promosi: +2.6421

Verifikasi sigmoid untuk satu email latih:
  z = b + w.x                      : +1.9552
  sigmoid manual 1/(1+e^-z)        : 0.876014
  model.predict_proba(...)[spam]   : 0.876014

Tabel sigmoid untuk beberapa nilai z:
    z    |  sigma(z)
    -4   |  0.0180
    -3   |  0.0474
    -2   |  0.1192
    -1   |  0.2689
     0   |  0.5000
     1   |  0.7311
     2   |  0.8808
     3   |  0.9526
     4   |  0.9820

Akurasi data uji: 1.000

Mari kita telaah baris-baris kode di atas:

  1. Baris 11–18 (make_classification): 60 email sintetis dengan dua fitur informatif dibuat dengan random_state=42 sehingga datanya sama setiap eksekusi. Argumen n_redundant=0 memastikan kedua fitur benar-benar membawa informasi, bukan salinan berkorelasi.
  2. Baris 20–22 (train_test_split): 45 email untuk latih dan 15 untuk uji; stratify=y menjaga proporsi kedua kelas tetap seimbang di kedua bagian.
  3. Baris 24–25 (LogisticRegression(...).fit): melatih model dengan nilai bawaan C=1.0 dan penalti L2. Hasil pelatihan tersimpan di atribut coef_ (koefisien w) dan intercept_ (intersep b).
  4. Baris 27–30 (cetak parameter): setiap koefisien dipetakan kembali ke nama fiturnya agar terbaca sebagai log-odds, bukan sekadar angka lepas.
  5. Baris 34–37 (verifikasi sigmoid): baris 35 menghitung z = b + w·x memakai operator @ (perkalian titik matriks); baris 36 menerapkan rumus sigmoid mentah dengan np.exp; baris 37 membaca probabilitas kelas spam dari predict_proba.
  6. Baris 46–48 (tabel sigmoid): loop menghitung σ(z) untuk z dari -4 sampai 4 — tabel yang sama dengan yang kita diskusikan di awal chapter.
  7. Baris 50–51 (model.score): akurasi pada data uji sebagai umpan balik kewarasan; teori metriknya menyusul di section evaluasi.

Hasil verifikasinya meyakinkan: sigmoid manual menghasilkan 0,876014 dan predict_proba menghasilkan 0,876014 — enam angka desimal identik. Tidak ada langkah tersembunyi di dalam pustaka; predict_proba sungguh menjalankan rumus yang kita tulis tangan. Koefisien frekuensi_kata_promosi sebesar +2,6421 juga konsisten dengan tafsiran log-odds: setiap satu kenaikan satuan frekuensi kata promosi melipatgandakan odds spam sekitar 14 kali, sementara rasio_tautan (+0,4043) berpengaruh jauh lebih lembut. Pola seperti ini masuk akal untuk penyaring spam: kata promosi adalah sinyal yang jauh lebih kuat daripada sekadar keberadaan tautan.

Regresi logistik menghafal rumus dari data. Algoritme berikutnya bekerja dengan cara yang nyaris kebalikannya: tidak menghafal apa pun, hanya menyimpan data dan mengukur jarak saat prediksi. Mari kita kenal k-Nearest Neighbors.