Fitur yang tepat sering mengubah kinerja model lebih besar daripada pergantian algoritma. Topik ini membahas penciptaan fitur, yaitu bagian rekayasa fitur (feature engineering) yang menambahkan kolom baru berdasarkan penalaran tentang domain data. Praktiknya menggunakan catatan sensor suhu harian selama satu tahun dalam sebuah DataFrame beserta skrip fitur-dari-domain.py. Skrip itu membandingkan model linear pada fitur mentah dengan model yang sama setelah satu fitur turunan ditambahkan. Setelah membaca topik ini, penambahan fitur baru dapat dilakukan secara terukur, bukan sekadar menebak-nebak kolom.
Fitur sebagai hipotesis tentang mekanisme data#
Penciptaan fitur adalah proses menambahkan kolom baru yang merangkum mekanisme dunia nyata di balik data. Kolom mentah seperti suhu_luar dan kelembapan hanya menyimpan pengukuran, sedangkan kolom hasil ciptaan menyimpan penafsiran, misalnya seberapa jauh suhu menyimpang dari titik nyaman manusia. Setiap fitur baru pada dasarnya adalah hipotesis tentang apa yang benar-benar menggerakkan target. Fitur deviasi_kuadrat yang dibuat pada skrip di bawah menyatakan hipotesis bahwa konsumsi energi naik sebanding dengan kuadrat jarak suhu dari titik nyaman 21 derajat Celsius.
Sifat hipotesis itulah yang menjadikan penciptaan fitur sebagai pengali kinerja. Dengan pengetahuan domain, struktur yang mahal untuk dipelajari dari data dapat ditanamkan ke dalam satu kolom dengan biaya satu baris kode. Model yang sama, bahkan model yang sederhana, dapat mencapai skor jauh lebih tinggi karena bentuk hubungannya sudah disiapkan. Klaim ini tetap perlu diuji pada data, sebab hipotesis domain juga dapat keliru, dan pengujian itulah yang dilakukan skrip pada bagian berikutnya.
Kandidat fitur jarang muncul dari menatap tabel kosong. Sebagian besar muncul dari eksplorasi data (exploratory data analysis), yaitu memperhatikan pola yang tersisa setelah fitur yang ada diperhitungkan, misalnya sisa prediksi yang menumpuk pada suhu ekstrem. Sumbangan yang lain datang dari pengetahuan lapangan, seperti titik nyaman 21 derajat Celsius pada contoh topik ini, yang tidak mungkin ditebak dari angka mentahnya saja. Keduanya bermuara pada langkah yang sama, yaitu menuliskan dugaan mekanisme ke dalam kolom baru, lalu membiarkan data memutuskan apakah dugaan itu bertahan.
Mengapa model linear membutuhkan bantuan#
Model linear membangun prediksi sebagai jumlah berbobot dari fitur, sebagaimana dinyatakan rumus berikut.
Bentuk itu berarti prediksi hanya dapat bergerak lurus terhadap setiap fitur. Apabila target sebenarnya naik pada suhu rendah dan pada suhu tinggi tetapi turun di tengah, hubungan membentuk huruf U dan tidak ada garis lurus yang dapat mengikutinya. Model seperti pohon keputusan memang mampu menekuk sendiri, tetapi kemampuan itu dibayar dengan kebutuhan data yang lebih banyak dan risiko overfitting. Menanamkan bentuk hubungan lewat fitur turunan jauh lebih hemat. Model linear terhadap fitur baru tetap sederhana untuk dilatih, sedangkan kelengkungan terhadap fitur asal sudah tertanam di dalam kolom.
Perhitungan biayanya juga berpihak pada fitur turunan. Menambah kolom tidak menambah baris, sehingga biaya pelatihan dan penyimpanan hampir tidak berubah, sedangkan menambah kompleksitas model menuntut penyetelan dan data yang jauh lebih banyak. Satu kolom hasil penalaran domain dengan demikian menjadi jalan termurah untuk memperluas jangkauan sebuah model yang sudah ada.
Dari catatan sensor ke fitur deviasi kuadrat#
Skrip berikut membangun catatan sensor suhu selama 365 hari dengan tiga kolom pengukuran, yaitu suhu_luar, kelembapan, dan konsumsi_kwh. Mekanisme yang ditanamkan pada data adalah konsumsi yang naik terhadap kuadrat jarak suhu dari titik nyaman 21 derajat Celsius, ditambah pengaruh kecil kelembapan dan derau pengukuran. Skrip kemudian menghitung korelasi setiap fitur mentah terhadap target, membuat dua kolom turunan, lalu membandingkan skor model linear pada fitur mentah dengan model yang sama pada fitur yang diperkaya. Kedua konfigurasi menggunakan pemecahan indeks yang identik agar selisih skor murni berasal dari fiturnya.
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
# catatan sensor suhu: satu tahun data harian konsumsi listrik sebuah rumah
rng = np.random.default_rng(42)
n = 365
suhu = rng.uniform(12.0, 30.0, n) # suhu luar rata-rata harian (derajat Celsius)
kelembapan = rng.uniform(40.0, 90.0, n) # kelembapan relatif (persen)
derau = rng.normal(0.0, 0.8, n)
df = pd.DataFrame({
"suhu_luar": suhu.round(1),
"kelembapan": kelembapan.round(0),
})
# pengetahuan domain: energi naik terhadap kuadrat jarak suhu dari titik nyaman 21 derajat
df["konsumsi_kwh"] = (5.0 + 0.6 * (suhu - 21.0) ** 2 + 0.05 * kelembapan + derau).round(2)
print(df.head())
# hubungan fitur mentah dengan target, untuk melihat mengapa model linear gagal
print("\nKorelasi dengan konsumsi_kwh:")
print(df[["suhu_luar", "kelembapan", "konsumsi_kwh"]].corr()["konsumsi_kwh"].round(3))
# penciptaan fitur: deviasi suhu dari titik nyaman beserta kuadratnya
df["deviasi_nyaman"] = df["suhu_luar"] - 21.0
df["deviasi_kuadrat"] = df["deviasi_nyaman"] ** 2
y = df["konsumsi_kwh"]
# satu pemecahan indeks yang sama dipakai untuk kedua set fitur agar perbandingannya adil
idx = np.arange(n)
idx_latih, idx_uji = train_test_split(idx, test_size=0.2, random_state=42)
X_mentah = df.loc[idx_latih, ["suhu_luar", "kelembapan"]]
model_mentah = LinearRegression().fit(X_mentah, y.iloc[idx_latih])
skor_mentah = model_mentah.score(df.loc[idx_uji, ["suhu_luar", "kelembapan"]], y.iloc[idx_uji])
print(f"\nR2 fitur mentah : {skor_mentah:.4f}")
X_baru = df.loc[idx_latih, ["suhu_luar", "kelembapan", "deviasi_nyaman", "deviasi_kuadrat"]]
model_baru = LinearRegression().fit(X_baru, y.iloc[idx_latih])
skor_baru = model_baru.score(
df.loc[idx_uji, ["suhu_luar", "kelembapan", "deviasi_nyaman", "deviasi_kuadrat"]],
y.iloc[idx_uji],
)
print(f"R2 dengan fitur deviasi_kuadrat : {skor_baru:.4f}") suhu_luar kelembapan konsumsi_kwh
0 25.9 61.0 23.53
1 19.9 79.0 9.47
2 27.5 74.0 32.85
3 24.6 57.0 15.36
4 13.7 85.0 42.10
Korelasi dengan konsumsi_kwh:
suhu_luar -0.061
kelembapan 0.123
konsumsi_kwh 1.000
Name: konsumsi_kwh, dtype: float64
R2 fitur mentah : -0.0035
R2 dengan fitur deviasi_kuadrat : 0.9949Angka-angka pada keluaran membentuk gambaran yang utuh. Korelasi suhu_luar terhadap target hanya -0.061, hampir nol, karena konsumsi justru tinggi pada kedua ujung rentang suhu. Model pada fitur mentah memperoleh -0.0035, artinya prediksinya sedikit lebih buruk daripada menebak rata-rata tanpa peduli fitur apa pun. Setelah kolom deviasi_kuadrat ditambahkan, model yang sama mencapai 0.9949 pada data uji, dan kenaikan hampir satu poin itu berasal dari satu kolom tambahan. Fitur mentah tidak berubah sedikit pun, sehingga seluruh perbaikan dapat disandarkan pada hipotesis domain yang ditanamkan ke dalam kolom baru.
Kesalahan umum#
- Menambah banyak fitur sekaligus tanpa pembanding. Tanpa skor baseline pada fitur mentah, sumbangan setiap fitur baru tidak dapat dipisahkan dari kebetulan. Buatlah baseline terlebih dahulu, tambahkan fitur satu per satu, dan ukur ulang pada pemecahan data yang sama.
- Menggunakan informasi yang belum tersedia saat prediksi. Fitur yang dihitung dari catatan setelah kejadian selesai, misalnya rata-rata konsumsi sebulan penuh untuk memprediksi hari ke-20, tidak akan pernah ada pada saat model berjalan. Pastikan setiap fitur dapat dihitung tepat pada momen prediksi.
- Menghitung fitur dari target tanpa disiplin pemecahan data. Fitur semacam rata-rata target per kategori menyerap informasi jawaban dan menimbulkan kebocoran data (data leakage) apabila dihitung dari seluruh dataset. Statistik pembentuk fitur hanya boleh diambil dari data latih.
- Menambahkan fitur turunan tanpa memeriksa bentuk hubungannya terlebih dahulu. Kolom kuadrat hanya menolong apabila hubungan fitur dan target memang melengkung, sedangkan pada hubungan berbanding lurus kolom itu hanya menambah dimensi tanpa sumbangan. Perhatikan sebaran fitur terhadap target atau mulai dari sisa prediksi sebelum menentukan bentuk turunannya.
Ringkasan#
- Penciptaan fitur menanamkan hipotesis domain ke dalam kolom baru, sehingga model sederhana dapat menggunakan struktur yang mahal untuk dipelajari dari data.
- Model linear hanya dapat bergerak lurus terhadap fiturnya, dan fitur turunan seperti menjadi cara termurah untuk menanamkan kelengkungan.
- Perbandingan yang adil menggunakan model, pemecahan data, dan metrik yang sama, dengan matriks fitur sebagai satu-satunya yang berubah.
- Fitur wajib dapat dihitung pada saat prediksi, dan statistik pembentuknya tidak boleh menyentuh target maupun data uji.
Referensi#
- Preprocessing data — scikit-learn — Panduan resmi transformasi fitur, termasuk penanganan fitur non-numerik dan penskalaan.
- Essential basic functionality — pandas — Dokumentasi operasi dasar DataFrame seperti pembuatan kolom dan korelasi yang dipakai pada skrip.
- Linear Models — scikit-learn — Deskripsi keluarga model linear beserta asumsi bentuk hubungannya terhadap fitur.