Latar Belakang Masalah
Sebuah startup proptech ingin membangun model prediksi harga rumah berdasarkan fitur-fitur seperti :
- Luas tanah (m²)
- Jumlah kamar
- Lokasi (kategorik: Urban, Suburban, Rural)
- Tahun pembangunan
Masalah :
- Data harga rumah memiliki distribusi positif skew (sebagian besar harga rendah, beberapa sangat tinggi).
- Skala feature sangat berbeda (luas tanah vs jumlah kamar).
- Data kategorik (Lokasi) perlu diubah ke bentuk numerik.
Dataset Contoh :
import pandas as pd import numpy as np data = { 'Luas_Tanah': [120, 200, 350, 90, 600, 150, 400], 'Kamar': [3, 4, 5, 2, 6, 3, 4], 'Lokasi': ['Urban', 'Suburban', 'Rural', 'Urban', 'Rural', 'Suburban', 'Urban'], 'Tahun': [1990, 2005, 1980, 2010, 1975, 1995, 2000], 'Harga': [500, 800, 450, 300, 1500, 700, 1200] # Dalam juta rupiah } df = pd.DataFrame(data) print(df)
Output :
Luas_Tanah Kamar Lokasi Tahun Harga 0 120 3 Urban 1990 500 1 200 4 Suburban 2005 800 2 350 5 Rural 1980 450 3 90 2 Urban 2010 300 4 600 6 Rural 1975 1500 5 150 3 Suburban 1995 700 6 400 4 Urban 2000 1200
Analisis Data Awal
a. Cek Distribusi Harga
import matplotlib.pyplot as plt plt.figure(figsize=(10, 4)) plt.subplot(1, 2, 1) plt.hist(df['Harga'], bins=30, color='blue', alpha=0.7) plt.title('Distribusi Harga (Original)') plt.subplot(1, 2, 2) plt.boxplot(df['Harga']) plt.title('Boxplot Harga') plt.show()
Hasil :
- Distribusi right-skewed (ekor ke kanan).
- Ada outlier di harga 1500.
b. Cek Skewness Numerik
print("Skewness Harga:", df['Harga'].skew()) # Output: >1 (positif skew) print("Skewness Luas Tanah:", df['Luas_Tanah'].skew()) # Output: >0.5
Transformasi Data
a. Transformasi Log pada Harga
df['Harga_Log'] = np.log1p(df['Harga']) # log(1+x) untuk hindari -inf plt.hist(df['Harga_Log'], bins=30, color='green', alpha=0.7) plt.title('Distribusi Harga (Log Transform)') plt.show()
Hasil :
- Distribusi lebih mendekati normal.
b. Standardisasi Fitur Numerik
from sklearn.preprocessing import StandardScaler scaler = StandardScaler() df[['Luas_Tanah_Std', 'Kamar_Std', 'Tahun_Std']] = scaler.fit_transform( df[['Luas_Tanah', 'Kamar', 'Tahun']] ) print(df[['Luas_Tanah', 'Luas_Tanah_Std']].head())
Output :
Luas_Tanah Luas_Tanah_Std 0 120 -0.922517 1 200 -0.461258 2 350 0.276755 3 90 -1.153146 4 600 1.660531
c. One-Hot Encoding Lokasi
df = pd.get_dummies(df, columns=['Lokasi'], prefix='Loc') print(df.columns) # Output: 'Loc_Urban', 'Loc_Suburban', 'Loc_Rural'
Hasil Akhir Transformasi
Dataset Setelah Transformasi :
Luas_Tanah_Std | Kamar_Std | Tahun_Std | Harga_Log | Loc_Urban | Loc_Suburban | Loc_Rural |
---|---|---|---|---|---|---|
-0.92 | -0.87 | -0.32 | 6.21 | 1 | 0 | 0 |
-0.46 | 0.29 | 1.05 | 6.68 | 0 | 1 | 0 |
Visualisasi Korelasi :
import seaborn as sns numeric_cols = ['Luas_Tanah_Std', 'Kamar_Std', 'Tahun_Std', 'Harga_Log'] sns.heatmap(df[numeric_cols].corr(), annot=True, cmap='coolwarm') plt.title('Korelasi Fitur Setelah Transformasi') plt.show()
Validasi Transformasi
Sebelum Transformasi :
- Model regresi linier memiliki R² = 0.65.
- Residual plot menunjukkan heteroskedastisitas.
Setelah Transformasi :
- R² meningkat menjadi 0.82.
- Residual lebih terdistribusi normal.
Contoh Prediksi :
from sklearn.linear_model import LinearRegression # Contoh training model sederhana X = df[['Luas_Tanah_Std', 'Kamar_Std', 'Loc_Urban', 'Loc_Suburban']] y = df['Harga_Log'] model = LinearRegression() model.fit(X, y) # Prediksi harga log, lalu convert kembali ke bentuk asli prediksi_log = model.predict(X) prediksi_asli = np.expm1(prediksi_log) # e^(x) - 1 print("Prediksi Harga:", prediksi_asli)
Kesimpulan & Rekomendasi
- Transformasi Log efektif untuk data harga yang skewed.
- Standardisasi membantu algoritma berbasis jarak (SVM, KNN).
- One-Hot Encoding wajib untuk data kategorik.
Tips :
- Simpan objek
scaler
danencoder
untuk data baru:import joblib joblib.dump(scaler, 'scaler.pkl') # Untuk digunakan di deployment
Latihan Lanjutan :
- Coba gunakan PowerTransformer (Yeo-Johnson) untuk handle skewness.
- Bandingkan performa model dengan/tanpa transformasi.
from sklearn.preprocessing import PowerTransformer pt = PowerTransformer(method='yeo-johnson') df['Harga_Transformed'] = pt.fit_transform(df[['Harga']])
Referensi Dataset Real :