24  Notebook Bab 6 - Pembentukan Fitur Turunan

Open In ColabNotebook Bab 6 ini punya dua bagian. Bagian Demo tinggal Anda jalankan lalu amati keluarannya; bagian Mini Project berisi soal dan data yang Anda kerjakan sendiri.Fitur turunan (rasio, encoding waktu, interaksi) sering mengekspos pola yang tak tertangkap model dari kolom mentah.

24.1 Persiapan

import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score

RANDOM_STATE = 42
rng = np.random.default_rng(RANDOM_STATE)
print('Setup selesai.')
Setup selesai.

25 Section 1 - Demo: Fitur Turunan Menaikkan Sinyal

25.1 Data mentah

Risiko gagal bayar ditentukan oleh rasio pengeluaran terhadap pendapatan dan oleh jam transaksi (larut malam lebih berisiko). Keduanya tidak eksplisit di kolom mentah.

n = 2000
df = pd.DataFrame({
    'jam': rng.integers(0, 24, n),
    'pendapatan': rng.gamma(3, 2000000, n),
    'pengeluaran': rng.gamma(3, 1500000, n),
})
rasio = df['pengeluaran'] / df['pendapatan']
malam = ((df['jam'] < 6) | (df['jam'] > 22)).astype(int)
y = (rng.random(n) < 1 / (1 + np.exp(-(5.0 * (rasio - 0.9) + 2.0 * malam)))).astype(int)
print('Data mentah:', df.shape)
df.head()
Data mentah: (2000, 3)
jam pendapatan pengeluaran
0 2 3.258032e+06 2.610465e+06
1 18 5.447176e+06 3.078514e+06
2 15 4.994007e+06 3.239438e+06
3 10 7.612125e+06 3.579406e+06
4 10 2.603533e+06 6.944745e+06

25.2 Baseline (mentah) vs setelah fitur turunan

def skor(Xdf):
    pipe = Pipeline([('sc', StandardScaler()), ('lr', LogisticRegression(max_iter=1000))])
    return cross_val_score(pipe, Xdf, y, cv=5).mean()

skor_mentah = skor(df[['jam', 'pendapatan', 'pengeluaran']])

der = df.copy()
der['rasio_pengeluaran'] = der['pengeluaran'] / der['pendapatan']
der['jam_sin'] = np.sin(2 * np.pi * der['jam'] / 24)
der['jam_cos'] = np.cos(2 * np.pi * der['jam'] / 24)
der['transaksi_malam'] = ((der['jam'] < 6) | (der['jam'] > 22)).astype(int)
skor_turunan = skor(der)

print(f'Fitur mentah    = {skor_mentah:.3f}')
print(f'+ fitur turunan = {skor_turunan:.3f}')
Fitur mentah    = 0.816
+ fitur turunan = 0.836

🔎 Amati. Menambahkan rasio pengeluaran dan encoding siklik jam (sin/cos) menaikkan akurasi. Model linear tidak bisa membentuk rasio dari dua kolom terpisah, dan jam sebagai angka 0-23 menyesatkan karena jam 23 dan jam 0 sebenarnya berdekatan; encoding siklik memperbaiki keduanya.

26 Section 2 - Mini Project

26.1 Soal

Anda diberi data transaksi dengan kolom tanggal (hari ke-0..364), jumlah_item, total_belanja, dan poin_loyalitas. Targetnya pakai_promo (1/0).

Tugas:

  1. Buat minimal 5 fitur turunan (misalnya harga rata-rata per item, fitur musiman dari tanggal via sin/cos, rasio poin terhadap belanja).
  2. Bandingkan model pada fitur mentah vs fitur mentah + turunan.
  3. Tunjukkan mana fitur turunan yang paling menaikkan skor.

Luaran: kode pembentukan fitur, perbandingan skor, dan 2-3 kalimat kesimpulan.

Kriteria penilaian: (a) minimal 5 fitur turunan; (b) encoding waktu yang benar (siklik); (c) evaluasi CV yang adil.

# DATA AWAL (jangan diubah) - transaksi ritel.
n = 2500
tanggal = rng.integers(0, 365, n)
jumlah_item = rng.integers(1, 30, n)
total_belanja = jumlah_item * rng.gamma(2.0, 25000, n)
poin = rng.gamma(2.0, 100, n)
musim = np.sin(2 * np.pi * tanggal / 365)
logit = 1.5 * musim + 0.0000015 * total_belanja - 0.008 * poin
pakai_promo = (rng.random(n) < 1 / (1 + np.exp(-logit))).astype(int)
trx = pd.DataFrame({'tanggal': tanggal, 'jumlah_item': jumlah_item,
                    'total_belanja': total_belanja.round(0), 'poin_loyalitas': poin.round(1),
                    'pakai_promo': pakai_promo})
print('Data:', trx.shape)
trx.head()
Data: (2500, 5)
tanggal jumlah_item total_belanja poin_loyalitas pakai_promo
0 242 27 1103013.0 115.2 1
1 26 9 33120.0 98.0 0
2 122 13 287846.0 226.5 1
3 258 9 64840.0 36.7 0
4 336 29 513477.0 138.2 0
# Kerjakan di sini.
# Petunjuk: buat kolom turunan di DataFrame, lalu bandingkan cross_val_score sebelum vs sesudah.