Regresi linear pada chapter sebelumnya bekerja baik karena harga rumah naik nyaris rata terhadap luas tanah. Namun pemilik Toko Kopi Kita menghadapi pola yang berbeda: makin besar biaya iklan harian, pendapatan memang naik, tetapi kenaikannya melandai — dari 5 ribu rupiah iklan tambahan di awal datang penambahan pendapatan besar, sementara di titik jenuh nyaris tidak terasa. Hubungan berbentuk lengkung seperti itu tidak bisa ditangkap garis lurus, dan di sinilah regresi polinomial masuk. Pada chapter ini kita melengkungkan model dengan PolynomialFeatures, membandingkan derajat 1, 2, dan 9, lalu menyaksikan sendiri bagaimana derajat yang terlalu tinggi justru merusak prediksi pada data baru.
Melengkungkan Garis dengan Fitur Turunan #
Ide regresi polinomial terasa nyaris curang karena sangat sederhana: modelnya tidak diganti sama sekali. Kita hanya menambahkan fitur turunan berupa pangkat dari fitur asli. Dari satu fitur x kita buat x dan x², lalu melatih LinearRegression yang biasa:
derajat 1: pendapatan = b0 + b1*x garis lurus
derajat 2: pendapatan = b0 + b1*x + b2*x² parabola (lengkung)
derajat 3: pendapatan = b0 + b1*x + b2*x² + b3*x³ lengkung berlekuk-lekukPerhatikan bahwa persamaan derajat 2 tetap linear terhadap parameter b0, b1, b2 — tidak ada parameter yang dipangkatkan. Karena itu LinearRegression scikit-learn yang sama masih bisa melatihnya; kita hanya memberi makan kolom-kolom baru. Makin tinggi derajat, makin lentur kurvanya, dan makin mudah model menempel pada data — kelenturan ini berguna, tetapi ada harganya:
| Derajat | Bentuk kurva | Karakter |
|---|---|---|
| 1 | Garis lurus | Kaku, hanya tren naik/turun |
| 2 | Parabola | Satu lekukan; cocok untuk efek yang melandai |
| 3-4 | Lengkung berlekuk | Beberapa belokan; mulai perlu kehati-hatian |
| 9 ke atas | Sangat lentur | Menempel hampir di tiap titik; risiko overfitting tinggi |
Menjinakkan PolynomialFeatures #
Kelas PolynomialFeatures dari modul sklearn.preprocessing mengerjakan pembuatan fitur turunan tersebut. Kita pakai data 16 hari promosi Toko Kopi Kita — biaya iklan harian (ribu rupiah) dan pendapatan hari itu (ribu rupiah):
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
iklan = pd.DataFrame({
"biaya_iklan": [0, 5, 10, 15, 20, 25, 30, 35,
40, 45, 50, 55, 60, 65, 70, 75],
"pendapatan": [180, 235, 295, 345, 380, 430, 455, 495,
505, 540, 575, 545, 600, 555, 605, 565],
})
X = iklan[["biaya_iklan"]]
y = iklan["pendapatan"]
X_latih, X_uji, y_latih, y_uji = train_test_split(X, y, test_size=0.3, random_state=42)
poly = PolynomialFeatures(degree=2, include_bias=False)
X_latih_poly = poly.fit_transform(X_latih)
print("Nama fitur turunan :", poly.get_feature_names_out())
print("Contoh hasil transformasi:")
print(pd.DataFrame(X_latih_poly[:5], columns=poly.get_feature_names_out()).to_string(index=False))
model = LinearRegression()
model.fit(X_latih_poly, y_latih)
b0 = model.intercept_
b1, b2 = model.coef_
print()
print("Persamaan: pendapatan = %.1f + %.2f*x + (%.4f)*x^2" % (b0, b1, b2))
print("Titik puncak kurva : x = %.1f ribu rupiah" % (-b1 / (2 * b2)))Output yang Dihasilkan:
Nama fitur turunan : ['biaya_iklan' 'biaya_iklan^2']
Contoh hasil transformasi:
biaya_iklan biaya_iklan^2
55.0 3025.0
40.0 1600.0
45.0 2025.0
10.0 100.0
75.0 5625.0
Persamaan: pendapatan = 179.8 + 12.11*x + (-0.0917)*x^2
Titik puncak kurva : x = 66.0 ribu rupiahMari kita telaah baris-baris kode di atas:
PolynomialFeatures(degree=2, include_bias=False): parameterdegreemenentukan pangkat tertinggi fitur turunan;include_bias=Falsemencegah kolom bernilai konstan 1, karenaLinearRegressionsudah menghitung intersep sendiri lewatmodel.intercept_.poly.fit_transform(X_latih)menghasilkan matriks baru: kolom pertamabiaya_iklanapa adanya, kolom kedua nilainya dikuadratkan — terlihat pada baris pertama, 55 menjadi 3.025. Kolom kedua inilah yang melengkungkan model.poly.transform(X_uji)(dipakai nanti) menerapkan transformasi yang sama tanpa mempelajari ulang — perbedaanfit_transformuntuk data latih dantransformuntuk data uji kita tegaskan lagi di bawah.-b1 / (2 * b2)mencari puncak parabola dari kalkulus paling dasar: turunanb1 + 2*b2*xbernilai nol di titik itu. Hasilnya praktis sekali: pendapatan harian berhenti naik sekitar biaya iklan 66 ribu rupiah — membelanjakan lebih dari itu hanya mengikuti hamburan, karena koefisienx²yang negatif menarik kurva turun.
Derajat 1 vs 2 vs 9: Perlombaan R² #
Sekarang kita adu tiga derajat pada data yang sama. Setiap model dilatih pada 11 hari latih lalu dinilai R² pada 5 hari uji yang tidak pernah dilihatnya:
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
iklan = pd.DataFrame({
"biaya_iklan": [0, 5, 10, 15, 20, 25, 30, 35,
40, 45, 50, 55, 60, 65, 70, 75],
"pendapatan": [180, 235, 295, 345, 380, 430, 455, 495,
505, 540, 575, 545, 600, 555, 605, 565],
})
X = iklan[["biaya_iklan"]]
y = iklan["pendapatan"]
X_latih, X_uji, y_latih, y_uji = train_test_split(X, y, test_size=0.3, random_state=42)
print("Derajat | R2 latih | R2 uji")
for derajat in [1, 2, 9]:
poly = PolynomialFeatures(degree=derajat, include_bias=False)
X_latih_poly = poly.fit_transform(X_latih)
X_uji_poly = poly.transform(X_uji)
model = LinearRegression()
model.fit(X_latih_poly, y_latih)
print("%7d | %8.3f | %6.3f" % (derajat,
model.score(X_latih_poly, y_latih),
model.score(X_uji_poly, y_uji)))Output yang Dihasilkan:
Derajat | R2 latih | R2 uji
1 | 0.850 | 0.832
2 | 0.983 | 0.991
9 | 0.992 | -1.443Tabel kecil ini memuat seluruh cerita chapter:
- Derajat 1 ketinggalan bentuk: R² latih 0,850 — garis lurus memang tidak bisa mengikuti efek melandai, jadi kesalahannya sistematik, bukan derau.
- Derajat 2 pas: R² uji justru naik ke 0,991. Satu lekukan parabola menangkap pola jenuh iklan dengan tiga parameter saja.
- Derajat 9 terlalu jauh: R² latih mentok di 0,992, tetapi R² uji jatuh ke -1,443. Angka negatif berarti prediksi pada data uji lebih buruk daripada sekadar menebak rata-rata
y_latihterus-menerus — model telah menghafal derau (hari hujan, hari raya) yang menempel di 11 titik latih, lalu membawa hafalan keliru itu ke data baru. Inilah overfitting dalam wujud paling gamblang; bentuknya akan kita lihat pada grafik berikut.
Melihat Bentuk Ketiganya #
Angka-angka di atas lebih mudah dipercaya setelah kita lihat wujud kurvanya. Blok berikut menggambar sebaran data latih bersama prediksi ketiga model pada rentang biaya iklan 0 sampai 75 ribu rupiah:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
iklan = pd.DataFrame({
"biaya_iklan": [0, 5, 10, 15, 20, 25, 30, 35,
40, 45, 50, 55, 60, 65, 70, 75],
"pendapatan": [180, 235, 295, 345, 380, 430, 455, 495,
505, 540, 575, 545, 600, 555, 605, 565],
})
X = iklan[["biaya_iklan"]]
y = iklan["pendapatan"]
X_latih, X_uji, y_latih, y_uji = train_test_split(X, y, test_size=0.3, random_state=42)
kurus = pd.DataFrame({"biaya_iklan": np.linspace(0, 75, 300)})
plt.figure(figsize=(7, 4.5))
plt.scatter(X_latih, y_latih, color="dimgray", label="data latih", zorder=3)
for derajat, warna in [(1, "tab:red"), (2, "tab:blue"), (9, "tab:green")]:
poly = PolynomialFeatures(degree=derajat, include_bias=False)
model = LinearRegression().fit(poly.fit_transform(X_latih), y_latih)
plt.plot(kurus, model.predict(poly.transform(kurus)), color=warna,
linewidth=1.6, label="derajat %d" % derajat)
plt.xlabel("Biaya iklan harian (ribu rupiah)")
plt.ylabel("Pendapatan harian (ribu rupiah)")
plt.legend()
plt.tight_layout()
plt.show()Grafiknya menampilkan titik-titik data latih berwarna abu-abu dan tiga kurva. Garis merah (derajat 1) terlihat memotong awan titik secara miring — terlalu rendah di kiri, terlalu tinggi di kanan. Kurva biru (derajat 2) mengikuti alur naik lalu melandai dengan mulus. Kurva hijau (derajat 9) tampak seperti tali yang diikat di setiap titik: hampir menyentuh seluruh titik latih, tetapi berayun liar di sela-selanya — persis alasan R² ujinya jatuh negatif.
Kekuatan dan Kelemahan Regresi Polinomial #
| Aspek | Keterangan |
|---|---|
| Menangkap lengkungan | Satu-satunya cara termurah melenturkan regresi linear |
| Tetap transparan | Persamaan b0 + b1x + b2x² masih bisa dibaca dan dicari puncaknya |
| Ekstrapolasi cepat melenceng | Di luar rentang data, pangkat tinggi meluncur turun atau naik tanpa kendali |
| Derajat tinggi = overfitting | Sebagaimana dibuktikan derajat 9 kita |
| Jumlah fitur membengkak | Derajat tinggi dengan banyak fitur menghasilkan puluhan kolom turunan |
Kapan Kita Memakainya #
Regresi polinomial tepat ketika kita mengetahui atau menduga ada efek melandai, seperti hubungan iklan-pendapatan, pupuk-hasil panen, atau harga-permintaan. Derajat 2 atau 3 biasanya cukup; naik ke derajat tinggi hanya dengan alasan kuat dari R² data uji. Untuk data yang bentuknya bebas dan tidak bisa dilukis parabola, model berbasis pohon di chapter-chapter berikutnya lebih aman. Namun sebelum itu, ada satu keluarga regresi yang masih memakai rumus linear — tetapi untuk menjawab pertanyaan ya/tidak.
Rangkuman #
- Regresi polinomial = regresi linear + fitur turunan pangkat;
LinearRegressiontetap dipakai karena model tetap linear terhadap parameter. PolynomialFeatures(degree=d, include_bias=False)membuat kolom x, x², …; latih denganfit_transform(X_latih), terapkan ke data uji dengantransform(X_uji).- Derajat 2 menangkap efek melandai iklan (R² uji 0,991) dan memberi tahu titik jenuh di 66 ribu rupiah.
- Derajat 9 menghafal derau: R² latih naik tipis tetapi R² uji jatuh ke -1,443 — overfitting dalam bentuk paling jelas.
- Pilih derajat dari skor data uji, bukan skor latih; ekstrapolasi di luar rentang data berbahaya.
Garis dan lengkungan yang kita bangun sejauh ini sama-sama memprediksi angka: harga rumah, pendapatan harian. Padahal separuh persoalan bisnis justru bertanya biner — pelanggan akan berhenti berlangganan atau tidak. Membengkokkan rumus linear ke dunia peluang itulah tugas Regresi Logistik .