Model Support Vector Regression (SVR) dengan Scikit-Learn
Support Vector Regression (SVR)
SVR adalah varian dari Support Vector Machine (SVM) yang digunakan untuk permasalahan regresi, yaitu memprediksi nilai kontinu. Tujuan utama SVR adalah menemukan fungsi regresi yang dapat memprediksi nilai kontinu dengan optimal, dengan menjaga agar kesalahan prediksi berada dalam batas toleransi tertentu yang disebut epsilon (ε). Secara spesifik SVR bertujuan untuk:
- Minimalkan Kesalahan Prediksi: SVR mencoba meminimalkan kesalahan prediksi dengan memfokuskan hanya pada kesalahan yang melebihi margin epsilon, sehingga model lebih tahan terhadap noise kecil dalam data.
- Generalisasi hasil: Dengan menggunakan konsep margin dan support vectors, SVR bertujuan untuk menghasilkan model yang tidak hanya sesuai dengan data pelatihan, tetapi juga dapat melakukan prediksi yang baik pada data baru yang belum pernah dilihat sebelumnya.
- Penanganan Data Non-Linear: Melalui penggunaan kernel trick, SVR dapat menangani hubungan yang kompleks dan non-linear antara fitur-fitur dalam data, memungkinkan model untuk bekerja dengan baik pada berbagai jenis data.
Konsep Utama dalam SVR:
- Epsilon-Insensitive Tube (ε): Sebuah margin epsilon di sekitar fungsi regresi di mana titik-titik data di dalam margin tersebut dianggap sebagai prediksi yang benar.
- Support Vectors: Titik-titik data yang berada di luar margin epsilon yang menentukan fungsi regresi.
- Kernel: Fungsi yang memetakan data ke dalam ruang fitur berdimensi tinggi sehingga memungkinkan memisahkan atau mendekati data dengan lebih baik.
Tutorial ini akan membahas implementasi SVR dengan Python menggunakan pustaka scikit-learn
. Pembahasan akan mencakup langkah-langkah mulai dari penyiapan dataset, transformasi data, pembagian dataset, pemodelan SVR, serta evaluasi performa model. Selain itu, pembahasan juga mencakup cara melakukan tuning hyperparameter menggunakan Grid Search untuk mencari model SVR terbaik. Keseluruhan proses pemodelan juga akan dilakukan dengan menerapkan pipelining, sehingga model nantinya dapat digunakan untuk memprediksi data baru tanpa harus melakukan tahapan-tahapan preprocessing secara manual.
Penyiapan Data
Dalam tutorial ini, kita akan menggunakan dataset prediksi umur kepiting yang tersedia di Kaggle (Crab Age Prediction). Dataset ini berisi berbagai fitur karakter morfologis dari kepiting yang digunakan untuk memprediksi perkiraan umurnya. Total observasi pada dataset adalah sebanyak 3.893 yang terdiri dari 8 buah fitur dengan 1 peubah respon yaitu Age
(dalam bulan).
Python
import pandas as pd data = pd.read_csv("https://raw.githubusercontent.com/sainsdataid/dataset/main/crab_age_dataset.csv") data.info()
# OUTPUT <class 'pandas.core.frame.DataFrame'> RangeIndex: 3893 entries, 0 to 3892 Data columns (total 9 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Sex 3893 non-null object 1 Length 3893 non-null float64 2 Diameter 3893 non-null float64 3 Height 3893 non-null float64 4 Weight 3893 non-null float64 5 Shucked Weight 3893 non-null float64 6 Viscera Weight 3893 non-null float64 7 Shell Weight 3893 non-null float64 8 Age 3893 non-null int64 dtypes: float64(7), int64(1), object(1) memory usage: 273.9+ KB
Transformasi dan Pembagian Data
Dataset yang kita gunakan memiliki 1 fitur dengan tipe kategorik yaitu Sex
dengan 3 kategori nilai yaitu M
untuk Male
, F
untuk Female
dan I untuk Indetermine
. Oleh karena itu kolom Sex
perlu ditransformasi terlebih dahulu. Transformasi yang akan kita gunakan adalah One-hot Encoding.
Model SVR merupakan model berbasis jarak, sehingga sensitif terhadap skala fitur yang berbeda-beda. Oleh karena itu, kita juga perlu melakukan transformasi fitur numerik agar memiliki skala yang sama misalkan dengan standardisasi. Standardisasi mengubah skala fitur sehingga memiliki mean 0 dan standar deviasi 1, yang membantu mempercepat konvergensi algoritma optimasi serta meningkatkan kinerja model. Dengan memastikan semua fitur berada pada skala yang sama, model dapat mempelajari pola yang lebih konsisten dan akurat untuk setiap fiturnya.
Transformasi data akan dilakukan menggunakan fungsi ColumnTransformer
dari modul sklearn.compose
, dengan peubah kategorik menggunakan fungsi OneHotEncoder
dan standardisasi peubah numerik dengan fungsi StandardScaler
.
Transformasi menyebabkan struktur data berubah. Proses ini tentunya juga harus terus dilakukan seandainya kita memiliki data baru dikemudian hari. Oleh karena itu, untuk memastikan setiap data baru nantinya akan melewati tahapan preprocessing yang sama (encoding fitur kategorik dan standardisasi fitur numerik) maka seluruh tahapan pemodelan akan kita kerjakan dalam bentuk pipelining. Proses ini dilakukan menggunakan fungsi Pipeline
dari model sklearn.pipeline
.
Pada tahap ini, kita juga membagi dataset menjadi data latih dan data uji. Data latih akan digunakan untuk pelatihan model serta tuning hyperparameter. Sedangkan data uji digunakan untuk mengevaluasi kinerja model. Pembagian dataset dilakukan menggunakan fungsi train_test_split
dari modul sklearn.model_selection
dengan proprosi 80 persen data latih dan 20 persen data uji.
Python
from sklearn.compose import ColumnTransformer from sklearn.preprocessing import StandardScaler, OneHotEncoder from sklearn.pipeline import Pipeline from sklearn.model_selection import train_test_split # Memilih fitur dan target X = data.drop(columns="Age") y = data["Age"] # Membagi dataset menjadi set pelatihan dan pengujian X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42 ) # Membuat ColumnTransformer num_features = [ "Length", "Diameter", "Height", "Shucked Weight", "Viscera Weight", "Shell Weight", ] cat_feature = ["Sex"] # Pipeline untuk preprocessing numerik numeric_transformer = Pipeline(steps=[("scaler", StandardScaler())]) # Pipeline untuk preprocessing kategorik categorical_transformer = Pipeline(steps=[("onehot", OneHotEncoder())]) # Menggabungkan langkah preprocessing dengan ColumnTransformer preprocessor = ColumnTransformer( transformers=[ ("num", numeric_transformer, num_features), ("cat", categorical_transformer, cat_feature), ] )
Model SVR
Sebelum kita melatih model, penting untuk memahami parameter dalam proses pembangunan model SVR dan bagaimana nilai-nilai tersebut mempengaruhi kinerja model. Pembuatan model SVR dilakukan menggunakan fungsi SVR
dari modul sklearn.SVM
. Fungsi SVR
memiliki beberapa parameter yang dapat diatur meliputi:
C
: Parameter regularisasi. Tingkat regularisasi yang diterapkan adalah berbanding terbalik denganC
. parameter ini harus bernilai positif. Penalti yang digunakan pada proses regularisasi adalah L2 kuadrat.kernel
: Fungsi kernel yang digunakan untuk memproyeksikan data ke dalam ruang fitur yang lebih tinggi. Kernel yang umum digunakan meliputi'linear'
(kernel linear),'poly'
(kernel polinomial),'rbf'
(Radial Basis Function kernel atau Gaussian kernel), dan'sigmoid'
(kernel sigmoid). Dapat juga menggunakan fungsi yang kita definisikan sendiri. Default:'rbf'
degree
: derajat polinomial jika menggunakan kernel polinomial (kernel='poly'
). Default:3
gamma
: Koefisien kernel untuk fungsi kernelrbf
,poly
, dansigmoid
. Nilaigamma
mengontrol seberapa jauh pengaruh dari satu data training tunggal. Nilai yang kecil berarti pengaruh yang lebih besar dari setiap data poin. Default:'scale'
(yaitu1 / (n_features * X.var())
)coef0
: Parameter untuk bias (intercept) dalam kernel polinomial dan sigmoid. Default:0.0
tol
: Toleransi untuk menghentikan kriteria yang mengontrol presisi dari solusi akhir. Default:1e-3
max_iter
: Batas maksimal iterasi untuk algoritma pelatihan. Default:-1
(tanpa batas iterasi, penghentian algoritma berdasarkan nilaitol
)
Pemodelan
Model SVR pertama yang kita buat adalah SVR dengan kernel
polinomial derajat 2 serta nilai C=100
dan gamma=0.1
. Nilai-nilai lainnya tetap menggunakan nilai defaultnya masing-masing.
Seperti penjelasan sebelumnya, pemodelan akan kita lakukan menggunakan pipeline, sehingga kita perlu membuat objek Pipeline
untuk mendefinisikan tahapan-tahapan pemodelan. Dalam hal ini, hanya terdapat dua tahap saja yang diberi nama preprocessor
dan regressor
. Tahapan preprocessor
yaitu proses transformasi data dan regressor
adalah tahapan pemodelan dengan SVR.
Python
from sklearn.svm import SVR model_svr = SVR(C=100, degree=2, gamma=0.1, kernel="poly") # Pipeline lengkap dengan model SVR svr_pipeline = Pipeline( steps=[("preprocessor", preprocessor), ("regressor", model_svr)] ) # Melatih model SVR dengan pipeline svr_pipeline.fit(X_train, y_train)
# OUTPUT SVR(C=100, degree=2, gamma=0.1, kernel='poly')
Prediksi dan Evaluasi Model
Model yang telah dilatih selanjutnya dievaluasi dengan data uji. Evaluasi model dilakukan dengan membuat prediksi nilai Age
untuk setiap observasi pada data uji. Hasil prediksi kemudian dibandingkan dengan nilai sebenarnya. Pada contoh ini, kita akan menggunakan metrik Mean Absolute Percentage Error (MAPE).
Hasil di bawah ini menunjukkan nilai MAPE sebesar 14,12%. Artinya, berdasarkan data uji secara rata-rata tingkat kesalahan prediksi model adalah sebesar 14,12% dari nilai sebenarnya.
Python
from sklearn.metrics import mean_absolute_percentage_error # Prediksi y_pred = svr_pipeline.predict(X_test) # Evaluasi mape = mean_absolute_percentage_error(y_test, y_pred) * 100 print(f"MAPE: {round(mape, 2)}%")
# OUTPUT MAPE: 14.12%
Tuning Hyperparameter (Grid Search)
Untuk mencari kemungkinan model SVR dengan kinerja yang lebih baik, penting untuk melakukan proses tuning hyperparameter. Tuning hyperparameter membantu menemukan kombinasi parameter yang optimal untuk model tersebut. Di sini, kita akan menggunakan teknik yang paling sederhana yaitu Grid Search.
Penentuan Nilai Hyperparameter
Pertama, kita tentukan terlebih dahulu daftar nilai-nilai yang akan menjadi dasar pencarian. Pada contoh ini, pencarian akan menggunakan kombinasi dari 5 hyperparameter yaitu C
, gamma
, epsilon
, kernel
dan degree
dengan nilai seperti yang ditampilkan pada kode di bawah ini. Nantinya, proses pencarian akan dilakukan pada setiap kombinasi yang terbentuk dari keseluruhan hyperparameter tersebut.
Terlihat pada kode di bawah ini, terdapat penambahan teks "regressor__"
di bagian awal nama-nama hyperparameter. Penambahan ini diperlukan sebagai identifikasi dalam proses pipeline bahwa nilai-nilai yang diberikan merupakan bagian dari step "regressor"
.
Perlu menjadi catatan juga, semakin banyak hyperaparameter dan nilai yang diberikan maka proses pencarian Grid Search akan semakin lama. Jadi, untuk proses pembelajaran silahkan jika ingin menyesuaikan ukurannya menjadi lebih sedikit agar tidak menghabiskan waktu.
Python
# Daftar nilai hyperaprameter param_grid = { "regressor__C": [1, 10, 20, 100], "regressor__gamma": [0.01, 0.1, 0.2], "regressor__epsilon": [0.01, 0.1, 0.5, 1], "regressor__kernel": ["linear", "poly", "rbf"], "regressor__degree": [2, 3], # Hanya untuk kernel 'poly' }
Pencarian Model
Proses Grid Search dilakukan dengan fungsi GridSearchCV
dari modul sklearn.model_selection
. Pengukuran kinerja model akan dilakukan menggunakan validasi silang K-Fold dengan 5 fold dengan metrik MAPE. (catatan: fungsi GridSearchCV
selalu menggunakan nilai terbesar sebagai nilai yang lebih baik, oleh karena itu untuk nilai MAPE, scoring
yang digunakan adalah "neg_mean_absolute_percentage_error"
).
Hasil pencarian menunjukkan kinerja model terbaik saat pelatihan memiliki nilai MAPE sebesar 14,28% (rata-rata berdasarkan validasi silang K-Fold). Nilai ini diperoleh pada model dengan kernel="rbf"
; C=10
; epsilon=0.5
dan gamma=0.1
. (nilai degree
dapat diabaikan karena kernel yang digunakan adalah rbf)
Python
from sklearn.model_selection import GridSearchCV # Inisiasi Model Awal base_model = SVR() # Inisiasi Model Pipeline svr_pipeline_cv = Pipeline( steps=[("preprocessor", preprocessor), ("regressor", base_model)] ) # Inisiasi Grid Search grid_search = GridSearchCV( svr_pipeline_cv, param_grid, cv=5, refit=True, scoring="neg_mean_absolute_percentage_error", n_jobs=-1, # gunakan seluruh CPU core yang tersedia ) # Fit model grid_search.fit(X_train, y_train) # Mendapatkan parameter terbaik best_par = grid_search.best_params_ print("Parameter terbaik:\n", best_par) # Mendapatkan skor terbaik mape_cv = -100 * grid_search.best_score_ print("Skor MAPE terbaik:\n", mape_cv)
# OUTPUT Parameter terbaik: {'C': 10, 'degree': 2, 'epsilon': 0.5, 'gamma': 0.1, 'kernel': 'rbf'} Skor MAPE terbaik: 14.24
Prediksi dan Evaluasi
Berdasarkan hasil temuan hyperparameter terbaik tersebut, kita dapat mengevaluasi kinerja model dengan data uji seperti sebelumnya. Hasil evaluasi menunjukkan nilai MAPE model sebesar 13,93%. Nilai ini sedikit lebih baik dibandingkan model awal tanpa tuning hyperparameter.
Python
# Memilih model terbaik best_model = grid_search.best_estimator_ # prediksi data uji pred_cv = best_model.predict(X_test) # Evaluasi mape = mean_absolute_percentage_error(y_test, pred_cv) * 100 print(f"MAPE: {round(mape, 2)}%")
# OUTPUT MAPE: 13.93%
Persistensi Model
Persistensi model adalah proses menyimpan model yang telah dilatih ke dalam sebuah file sehingga model tersebut dapat digunakan kembali di masa depan tanpa perlu melatih ulang. Ini sangat berguna ketika kita ingin menggunakan model yang sama untuk melakukan prediksi di waktu mendatang atau untuk diterapkan pada aplikasi produksi.
Menyimpan Model
Setelah model terbaik ditemukan melalui proses pelatihan dan tuning hyperparameter, kita dapat menyimpannya menggunakan fungsi dump
dari pustaka joblib
. File yang dihasilkan akan berisi seluruh informasi yang diperlukan untuk merekonstruksi model, termasuk struktur model dan bobot yang telah dilatih. Misalnya, joblib.dump(best_model, 'model_svr.pkl')
akan menyimpan model terbaik ke dalam file
.model_svr
.pkl
Python
import joblib joblib.dump(best_model, "model_svr.pkl") print("Model saved to model_svr.pkl")
# OUTPUT Model saved to model_svr.pkl
Memuat Model
Model yang telah disimpan dapat dimuat kembali dari file menggunakan fungsi load
dari pustaka joblib
. Misalnya, loaded_model = joblib.load('model_svr.pkl')
akan memuat model dari file model_svr.pkl
dan menyimpannya dalam variabel loaded_model
.
Python
loaded_model = joblib.load("model_svr.pkl") print("Model loaded from model_svr.pkl")
# OUTPUT Model loaded from catboost_model.pkl
Prediksi Data Baru
Setelah model dimuat, kita dapat menggunakannya untuk membuat prediksi pada data baru. Misalkan, terdapat data baru dari 2 data kepiting baru. Berdasarkan data tersebut, maka kita dapat memprediksi perkiraan umur kepiting tersebut menggunkaan model ada.
Salah satu keunggulan penggunaan pipeline dalam pelatihan model adalah kita tidak perlu memikirkan tahapan-tahapan preprocessing seperti encoding data, standardisasi data maupun proses lainnya ketika berhadapan dengan data baru. Keseluruhan proses tersebut akan dikerjakan secara otomatis saat kita melakukan prediksi menggunakan model tersebut.
Kode berikut ini menampilkan ilustrasi yaitu terdapat dua data baru yang akan diprediksi. Karena kita menggunakan pipeline maka data tersebut dapat langsung diprediksi tanpa harus melakukan proses one-hot encoding pada peubah Sex
maupun standardisasi nilai peubah numeriknya. Dapat dilihat hasil prediksi untuk kepiting pertama diperkirakan berumur sekitar 6,9
bulan dan kepiting kedua berumur sekitar 10
bulan.
Python
# contoh data baru data_baru = [ { "Sex": "I", "Length": 1.05, "Diameter": 0.8, "Height": 0.25, "Weight": 9.63, "Shucked Weight": 4.94, "Viscera Weight": 1.41, "Shell Weight": 2.67, }, { "Sex": "M", "Length": 1.45, "Diameter": 1.15, "Height": 0.375, "Weight": 29.73, "Shucked Weight": 14.75, "Viscera Weight": 5.48, "Shell Weight": 8.64, }, ] # Reformat data menjadi dataframe data_baru_df = pd.DataFrame(data_baru) # Prediksi Umur Kepiting pred_baru = loaded_model.predict(data_baru_df) print(pred_baru)
# OUTPUT [6.89733796 9.99640727]
Selamat mencoba!
API
- Pipeline: Pipeline — scikit-learn documentation
- Support Vector Regression (SVR): SVR — scikit-learn documentation
- GridSearchCV: GridSearchCV — scikit-learn documentation