Spaces:
Sleeping
Sleeping
Download feature_engineering.py from SelliCapstone/selli_ml_deployment: direct link, hf CLI and curl.
- Browser
- Download file 3.52 kB
-
https://huggingface.co/spaces/SelliCapstone/selli_ml_deployment/resolve/main/feature_engineering.py
- Command line
-
hf download hf://spaces/SelliCapstone/selli_ml_deployment/feature_engineering.py
-
curl -L -o feature_engineering.py https://huggingface.co/spaces/SelliCapstone/selli_ml_deployment/resolve/main/feature_engineering.py
3.52 kB
| import numpy as np | |
| import pandas as pd | |
| def add_features(df): | |
| """ | |
| Melakukan Feature Engineering yang telah divalidasi dan dioptimalkan berdasarkan | |
| analisis Feature Importance (Gain Metric) pada model LightGBM. | |
| Hanya fitur dengan sinyal prediksi kuat yang dipertahankan, sementara fitur noise | |
| dan redundan dihapus untuk efisiensi model. | |
| Features yang ditambahkan/ditransformasi: | |
| 1. pdays_cleaned: Mengganti nilai -1 (belum pernah dikontak) menjadi 1000 | |
| agar memiliki urutan numerik yang logis bagi Tree-based models. | |
| 2. debt_count: Agregasi beban hutang (housing + loan). Nilai 0-2. | |
| Terbukti memiliki Gain Importance jauh lebih tinggi (40.8) dibanding fitur terpisah. | |
| 3. prev_success: Binary flag (1 jika kampanye sebelumnya 'success'). | |
| Prediktor terkuat dalam dataset (Importance: 100.0). | |
| 4. education_level: Mapping ordinal (0: unknown s/d 3: tertiary) untuk menangkap | |
| hirarki sosial-ekonomi nasabah. | |
| 5. month_int: Mapping bulan ke integer (1-12) untuk menangkap musiman (seasonality) | |
| secara efisien tanpa One-Hot Encoding berlebih. | |
| 6. contact_unknown: Binary flag (1 jika contact='unknown'). | |
| Indikator kualitas data yang sangat kuat (Importance: 68.9). | |
| Features yang dihapus: | |
| - duration: Mencegah Data Leakage fatal (durasi tidak diketahui sebelum menelpon). | |
| - pdays: Digantikan oleh pdays_cleaned. | |
| - housing, loan: Dihapus karena sinyalnya sudah diambil alih oleh debt_count. | |
| - education: Digantikan oleh education_level. | |
| - month: Digantikan oleh month_int. | |
| - is_balance_negative: Dihapus karena Low Importance Score (0.2). | |
| Features Raw yang dipertahankan (Passthrough): | |
| - day: Angka tanggal mentah (1-31) terbukti lebih unggul daripada fitur 'payday'. | |
| - balance, age, campaign, previous: Fitur numerik standar. | |
| - job, marital, contact, poutcome: Fitur kategorikal untuk encoding di pipeline. | |
| Args: | |
| df (pd.DataFrame): DataFrame input raw (data training atau data baru). | |
| Returns: | |
| pd.DataFrame: DataFrame bersih yang siap masuk ke pipeline preprocessing. | |
| """ | |
| df = df.copy() | |
| if 'duration' in df.columns: | |
| df = df.drop(columns=['duration']) | |
| if 'pdays' in df.columns: | |
| df['pdays_cleaned'] = df['pdays'].replace(-1, 1000) | |
| df = df.drop(columns=['pdays']) | |
| if 'housing' in df.columns and 'loan' in df.columns: | |
| h = (df['housing'] == 'yes').astype(int) | |
| l = (df['loan'] == 'yes').astype(int) | |
| df['debt_count'] = h + l | |
| df = df.drop(columns=['housing', 'loan']) | |
| if 'poutcome' in df.columns: | |
| df['prev_success'] = (df['poutcome'] == 'success').astype(int) | |
| edu_map = {'unknown': 0, 'primary': 1, 'secondary': 2, 'tertiary': 3} | |
| if 'education' in df.columns: | |
| df['education_level'] = df['education'].astype(str).str.lower().map(edu_map).fillna(0) | |
| df = df.drop(columns=['education']) | |
| month_map = { | |
| 'jan': 1, 'feb': 2, 'mar': 3, 'apr': 4, 'may': 5, 'jun': 6, | |
| 'jul': 7, 'aug': 8, 'sep': 9, 'oct': 10, 'nov': 11, 'dec': 12 | |
| } | |
| if 'month' in df.columns: | |
| df['month_int'] = df['month'].astype(str).str.lower().map(month_map).fillna(0) | |
| df = df.drop(columns=['month']) | |
| if 'contact' in df.columns: | |
| df['contact_unknown'] = (df['contact'] == 'unknown').astype(int) | |
| if 'is_balance_negative' in df.columns: | |
| df = df.drop(columns=['is_balance_negative']) | |
| return df |