Model regresi yang sudah dilatih menghasilkan angka, tetapi angka itu belum berkata apa-apa sampai kita mengukur seberapa jauh prediksi melenceng dari kenyataan. Untuk itu kita membutuhkan metrik evaluasi regresi — rumus yang meringkas seluruh galat menjadi satu angka yang bisa dibandingkan antar model. Chapter ini membedah empat metrik standar (MAE, MSE, RMSE, R²) dari definisinya, menghitung masing-masing dua kali — manual dengan NumPy dan lewat sklearn.metrics — lalu menjalankan satu eksperimen kecil yang menjelaskan mengapa pilihan metrik bukan urusan selera: melipatduakan satu galat besar ternyata menggerakkan tiap metrik dengan kekuatan yang sangat berbeda.
Empat Metrik dan Pertanyaan Masing-masing #
Misalkan yᵢ adalah nilai aktual dan ŷᵢ prediksi model; galat tiap sampel adalah selisihnya. Keempat metrik dihitung sebagai berikut:
MAE = (1/n) * Σ |yᵢ - ŷᵢ|
MSE = (1/n) * Σ (yᵢ - ŷᵢ)²
RMSE = akar(MSE)
R² = 1 - SSE/SST dengan SSE = Σ (yᵢ - ŷᵢ)² dan SST = Σ (yᵢ - ȳ)²MAE (mean absolute error) menjawab “rata-rata prediksi meleset berapa?” dalam satuan yang sama dengan target — juta rupiah kalau targetnya harga rumah. MSE (mean squared error) mengkuadratkan galat lebih dulu, sehingga galat besar dihukum jauh lebih berat; satuannya menjadi kuadrat (juta kuadrat) dan angkanya sulit dibaca manusia, tetapi sifat diferensiabelnya membuat MSE cocok sebagai fungsi loss saat training. RMSE (root mean squared error, akar MSE) mengembalikan satuan ke bentuk aslinya sambil mempertahankan kepekaan terhadap galat besar — kompromi yang menjadikannya metrik laporan paling populer. Terakhir R² (koefisien determinasi) membaca hal yang berbeda sama sekali: berapa bagian variasi target yang berhasil dijelaskan model, dibandingkan tebakan naif yang selalu memakai rerata ȳ.
R² punya jangkar yang membuatnya mudah dibaca: tebakan naif “selalu prediksi rerata” bernilai tepat 0, dan model sempurna bernilai 1. Konsekuensinya jarang disadari pemula: R² bisa negatif. Prediksi yang lebih buruk daripada sekadar menebak rerata akan menghasilkan SSE lebih besar daripada SST, dan 1 − SSE/SST jatuh di bawah nol — penanda kuat bahwa model (atau data latihnya) bermasalah serius.
| Metrik | Satuan | Sensitivitas pencilan | Kekuatan utama |
|---|---|---|---|
| MAE | Sama dengan target | Rendah — tahan banting | Komunikasi ke pemangku kepentingan |
| MSE | Kuadrat satuan target | Tinggi — kuadrat galat | Fungsi loss saat training, optimasi |
| RMSE | Sama dengan target | Tinggi — setara MSE | Laporan akurasi yang mudah dibaca |
| R² | Tanpa satuan (0–1, bisa negatif) | Tinggi lewat SSE | Perbandingan relatif antar target |
Contoh Kode: Manual vs sklearn.metrics #
File metrik-regresi.py memakai delapan prediksi harga rumah — tujuh prediksi hanya meleset ±5 sampai ±10 juta, satu rumah meleset +120 juta (prediksi 760, terjual 640). Kita menghitung keempat metrik dari rumus mentahnya, membandingkannya dengan hasil sklearn.metrics, lalu melipatduakan galat rumah terakhir menjadi +240 juta dan mengamati efeknya pada tiap metrik.
# Metrik evaluasi regresi: MAE, MSE, RMSE, dan R^2 dihitung manual dengan
# NumPy lalu dibandingkan dengan sklearn.metrics -- angkanya identik.
import numpy as np
from sklearn.metrics import (
mean_absolute_error,
mean_squared_error,
r2_score,
root_mean_squared_error,
)
# Delapan prediksi harga rumah (juta rupiah) vs harga terjual sesungguhnya.
# Rumah terakhir sengaja diberi galat besar: prediksi 760, terjual 640.
y_aktual = np.array([350.0, 420.0, 510.0, 480.0, 620.0, 590.0, 710.0, 640.0])
y_prediksi = np.array([355.0, 415.0, 505.0, 470.0, 625.0, 580.0, 705.0, 760.0])
def metrik_manual(y_a, y_p):
"""Hitung keempat metrik regresi dari definisinya."""
galat = y_p - y_a
mae = np.mean(np.abs(galat))
mse = np.mean(galat**2)
rmse = np.sqrt(mse)
sse = np.sum(galat**2)
sst = np.sum((y_a - y_a.mean()) ** 2)
r2 = 1.0 - sse / sst
return mae, mse, rmse, r2
# Bagian 1: rumus manual vs sklearn.metrics pada data yang sama.
mae_m, mse_m, rmse_m, r2_m = metrik_manual(y_aktual, y_prediksi)
print("Perbandingan metrik manual vs sklearn.metrics:")
print(f"{'metrik':<7} {'manual':>12} {'scikit-learn':>14}")
print(f"{'MAE':<7} {mae_m:>12.3f} {mean_absolute_error(y_aktual, y_prediksi):>14.3f}")
print(f"{'MSE':<7} {mse_m:>12.3f} {mean_squared_error(y_aktual, y_prediksi):>14.3f}")
print(f"{'RMSE':<7} {rmse_m:>12.3f} {root_mean_squared_error(y_aktual, y_prediksi):>14.3f}")
print(f"{'R2':<7} {r2_m:>12.3f} {r2_score(y_aktual, y_prediksi):>14.3f}")
print()
# Bagian 2: galat besar pada rumah terakhir dilipatduakan (+120 -> +240),
# enam galat kecil lainnya tidak disentuh.
y_prediksi_2 = y_prediksi.copy()
y_prediksi_2[-1] = 880.0
mae_2, mse_2, rmse_2, r2_2 = metrik_manual(y_aktual, y_prediksi_2)
print("Satu galat besar dilipatduakan (+120 menjadi +240):")
print(f" MAE {mae_m:10.3f} -> {mae_2:10.3f} ({mae_2 / mae_m:.2f}x)")
print(f" MSE {mse_m:10.3f} -> {mse_2:10.3f} ({mse_2 / mse_m:.2f}x)")
print(f" RMSE {rmse_m:10.3f} -> {rmse_2:10.3f} ({rmse_2 / rmse_m:.2f}x)")
print(f" R2 {r2_m:10.3f} -> {r2_2:10.3f}")
print()
# Bagian 3: R^2 bisa NEGATIF jika prediksi lebih buruk daripada
# tebakan naif "selalu tebak rerata".
y_a_kecil = np.array([10.0, 20.0, 30.0, 40.0, 50.0])
y_p_kecil = np.array([50.0, 10.0, 40.0, 20.0, 30.0])
r2_negatif = r2_score(y_a_kecil, y_p_kecil)
print(f"Prediksi melenceng jauh pada lima titik kecil: R2 = {r2_negatif:.3f}")
print("(negatif berarti lebih buruk daripada menebak rerata)")Output yang Dihasilkan:
Perbandingan metrik manual vs sklearn.metrics:
metrik manual scikit-learn
MAE 20.625 20.625
MSE 1840.625 1840.625
RMSE 42.903 42.903
R2 0.857 0.857
Satu galat besar dilipatduakan (+120 menjadi +240):
MAE 20.625 -> 35.625 (1.73x)
MSE 1840.625 -> 7240.625 (3.93x)
RMSE 42.903 -> 85.092 (1.98x)
R2 0.857 -> 0.437
Prediksi melenceng jauh pada lima titik kecil: R2 = -1.600
(negatif berarti lebih buruk daripada menebak rerata)Bedah kode di atas baris demi baris:
- Baris 4–10 (import): keempat fungsi metrik diimpor dari
sklearn.metrics;root_mean_squared_errortersedia sejak scikit-learn 1.4 dan menggantikan kebiasaan lamasqrt(mean_squared_error(...)). - Baris 14–15 (data): dua array sejajar — harga aktual dan harga prediksi. Selisih keduanya,
galat, adalah bahan mentah seluruh metrik. - Baris 18–27 (
metrik_manual): seluruh rumus pada bloktextdi atas diterjemahkan baris demi baris: nilai mutlak lalu dirata-rata (MAE), kuadrat lalu dirata-rata (MSE), akar kuadrat (RMSE), dan1 − SSE/SST(R²). - Baris 31–37 (perbandingan): keempat pasangan angka tercetak berdampingan dan identik hingga desimal ketiga — bukti bahwa pustaka mengeksekusi definisi yang sama, tanpa langkah tersembunyi apa pun.
- Baris 42–49 (eksperimen pencilan): hanya elemen terakhir
y_prediksi_2[-1]yang diubah dari 760 menjadi 880; galatnya naik dari +120 menjadi +240. - Baris 54–58 (R² negatif): lima titik kecil diprediksi buruk sengaja;
r2_scoremenghasilkan −1,600 — di bawah titik nol rerata.
Membaca Hasil Eksperimen Pencilan #
Hasil bagian kedua adalah pelajaran paling penting chapter ini. Melipatduakan satu galat dari +120 ke +240 menggerakkan MAE dari 20,625 ke 35,625 (naik 1,73x) — kenaikan yang jujur sebanding: satu galat membesar dua kali, rata-rata absolut naik seperdelapan dari selisihnya. Metrik yang sama pada MSE melonjak 3,93x (1.840,625 → 7.240,625), karena kuadrat galat tersebut berubah dari 14.400 ke 57.600 dan mendominasi total. RMSE naik 1,98x, dan R² terjun dari 0,857 ke 0,437 — model yang tadinya menjelaskan 86% variasi harga kini hanya 44% gara-gara satu rumah.
Metrik Hanyalah Awal: Perkenalan Residu #
Satu angka ringkasan menyembunyikan pola. Dua model bisa sama-sama berkata “RMSE 42 juta” sementara model pertama meleset merata di semua harga dan model kedua sangat akurat untuk rumah murah tetapi buruk untuk rumah mahal. Analisis residu — memplot galat = y − ŷ terhadap prediksi atau fitur — membongkar hal semacam ini: pola melengkung menandakan hubungan nonlinier yang belum ditangkap, sebaran yang melebar pada prediksi tinggi menandakan heteroskedastisitas, dan satu titik yang menjauh dari kawanannya adalah kandidat pencilan atau kesalahan data. Kita akan banyak memplot residu saat membangun proyek prediksi harga rumah di akhir Course ini.
Empat metrik ini juga memberi kita alat ukur untuk pertanyaan berikutnya: bagaimana jika hubungan fitur dan target tidak lurus? Regresi linier murni akan menghasilkan galat sistematis yang residunya melengkung — dan obatnya bukan meninggalkan dunia linier, melainkan menambahkan fitur berpangkat. Chapter Regresi Polynomial membahas caranya.
Referensi Resmi #
- Regression metrics — scikit-learn User Guide — penjelasan resmi seluruh metrik regresi beserta kegunaannya.
- sklearn.metrics.mean_squared_error — API Reference — implementasi MSE yang kita hitung manual di atas.
- sklearn.metrics.r2_score — API Reference — definisi resmi R², termasuk kasus skor negatif.