Tuning Hyperparameter Model dengan Particle Swarm Optimization


Salah satu aspek penting dalam membangun model machine learning yang optimal adalah tuning hyperparameter, yaitu proses mencari nilai-nilai parameter yang mengontrol bagaimana algoritma bekerja. Hyperparameter tidak dioptimalkan secara langsung ketika melatih model machine learning, sehingga perlu dilakukan pencarian optimal. Terdapat berbagai teknik tuning hyperparameter yang dapat digunakan misalnya grid search, random search, Bayesian Optimization, Particle Swarm Optimization (PSO) dan lain sebagainya. Tuning hyperparameter yang tepat dapat secara signifikan meningkatkan kinerja model dan membuatnya lebih akurat serta efisien.
Pada tutorial ini kita akan membahas teknik optimasi menggunakan Particle Swarm Optimization dan menerapkannya untuk melakukan pencarian hyperparameter optimal pada model Random Forest.
Particle Swarm Optimization
PSO adalah algoritma optimisasi berbasis populasi yang dikembangkan oleh Kennedy dan Eberhart pada tahun 1995, terinspirasi dari perilaku kawanan burung atau ikan dalam mencari makanan. Dalam PSO, setiap solusi potensial diperlakukan sebagai partikel yang bergerak dalam ruang pencarian, mencoba menemukan solusi terbaik berdasarkan posisi terbaik mereka sendiri serta posisi terbaik kawanan (swarm).
Berikut ini adalah beberapa konsep dasar pada PSO:
Populasi Partikel: Dalam PSO, ada sejumlah partikel yang bergerak dalam ruang solusi. Setiap partikel mewakili solusi potensial yang mencoba menemukan solusi optimal dimana posisi setiap partikel merepresentasikan nilai solusi, sementara kecepatannya menentukan arah dan besar perubahan posisi di setiap iterasi.
Posisi dan Kecepatan: Setiap partikel memiliki dua karakteristik utama:
- Posisi (
x
): Menggambarkan solusi saat ini dari partikel tersebut. - Kecepatan (
v
): Menggambarkan seberapa cepat dan ke arah mana partikel tersebut bergerak.
Posisi Terbaik Individu dan Global:
- pBest (personal best): Posisi terbaik yang pernah ditemukan oleh masing-masing partikel.
- gBest (global best): Posisi terbaik yang ditemukan oleh seluruh kawanan (swarm).
Fungsi Objektif: Setiap partikel dievaluasi berdasarkan fungsi objektif yang ingin dioptimalkan. Tujuannya adalah meminimalkan atau memaksimalkan fungsi ini, tergantung pada kebutuhan masalah.
Persamaan Gerak Partikel: Kecepatan baru (v
) dari partikel diperbarui menggunakan dua faktor yaitu Jarak antara posisi saat ini terhadap pBest dan gBest.
Persamaan untuk memperbarui kecepatan:
$$v_{i}^{t+1} = w \cdot v_i^t + c_1 \cdot r_1 \cdot (\text{pBest}_i – x_i^t) + c_2 \cdot r_2 \cdot (\text{gBest} – x_i^t)$$
Di mana:
w
: Faktor inersia, menentukan pengaruh kecepatan sebelumnya.c1
danc2
: Koefisien akselerasi untuk pBest dan gBest.r1
danr2
: Bilangan acak antara 0 dan 1 untuk menjaga variasi dalam pergerakan partikel.
Setelah kecepatan diperbarui, posisi baru dihitung dengan persamaan:
$$x_{i}^{t+1} = x_i^t + v_i^{t+1}$$
Algoritma PSO:
- Inisialisasi posisi dan kecepatan partikel secara acak.
- Evaluasi fungsi objektif untuk setiap partikel.
- Tentukan pBest dan gBest.
- Perbarui kecepatan dan posisi setiap partikel.
- Ulangi proses sampai kriteria penghentian terpenuhi (misalnya, iterasi maksimum atau konvergensi solusi).
Penyiapan Pustaka
Sebelum memulai pemodelan, kita perlu menyiapkan beberapa pustaka yaitu pandas
, scikit-learn
dan pyswarm
. Jika belum tersedia, paket-paket tersebut dapat di-install menggunakan pip
dengan sintaks berikut:
Python
pip install pandas scikit-learn pyswarm
Selanjutnya, kita mengimpor setiap modul yang dibutuhkan seperti yang disajikan berikut ini:
Python
# manipulasi dan pemrosesan data import pandas as pd # pembagian data from sklearn.model_selection import train_test_split # validasi silang K-Fold from sklearn.model_selection import cross_val_score # model random forest from sklearn.ensemble import RandomForestClassifier # metrik evaluasi model klasifikasi from sklearn.metrics import accuracy_score, confusion_matrix, classification_report # particle swarm optimization from pyswarm import pso
Penyiapan Dataset
Dataset yang akan digunakan adalah data Wine Quality yang sudah dimodifikasi menjadi klasifikasi biner. Dataset terdiri dari 1.143 observasi dengan 10 fitur (tanpa kolom id
) dan 1 peubah respon yaitu quality
(HIGH
atau LOW
). Jumlah observasi menurut kelas respon relatif seimbang serta tidak terdapat missing value pada seluruh observasi.
Dalam pemodelan, sangat disarankan untuk melakukan eksplorasi data secara mendalam agar memahami karakteristik data dengan lebih baik. Namun pada tulisan ini kita akan fokus pada tahapan pemodelan dan tuning hyperparameter menggunakan Particle Swarm Optimization. Silahkan pembaca melakukan eksplorasi secara mandiri jika diinginkan.
Python
# Memuat dataset dari URL url = "https://raw.githubusercontent.com/sainsdataid/dataset/main/wine-quality-binary.csv" data = pd.read_csv(url) # Melihat struktur data data.info() # Menghapus kolom 'id' data.drop(columns='id') # Melihat jumlah observasi per kelas respon print(data.groupby("quality").agg({"quality":"count"}))
# OUTPUT <class 'pandas.core.frame.DataFrame'> RangeIndex: 1143 entries, 0 to 1142 Data columns (total 13 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 id 1143 non-null int64 1 fixed.acidity 1143 non-null float64 2 volatile.acidity 1143 non-null float64 3 citric.acid 1143 non-null float64 4 residual.sugar 1143 non-null float64 5 chlorides 1143 non-null float64 6 free.sulfur.dioxide 1143 non-null float64 7 total.sulfur.dioxide 1143 non-null float64 8 density 1143 non-null float64 9 pH 1143 non-null float64 10 sulphates 1143 non-null float64 11 alcohol 1143 non-null float64 12 quality 1143 non-null object dtypes: float64(11), int64(1), object(1) memory usage: 116.2+ KB quality quality HIGH 621 LOW 522
Pembagian Data Latih dan Data Uji
Pada langkah ini, dataset dibagi menjadi dua bagian: data latih dan data uji. Data latih (70% dari total data) digunakan untuk melatih model, sedangkan data uji (30% dari total data) digunakan untuk mengevaluasi kinerja model. Pembagian ini penting untuk memastikan bahwa model dapat digeneralisasikan dengan baik dan tidak overfitting pada data latih.
Python
# Memisahkan fitur dan respon X = data.drop(columns='quality') y = data['quality'] # Membagi dataset menjadi data latih dan data uji X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=123)
Ruang Hyperparameter
Hyperparameter adalah parameter yang nilainya tidak dipelajari dari data. Berbeda dengan parameter model (seperti bobot dalam neural network) atau keofisen pada model regresi, hyperparameter ditentukan sebelum proses pelatihan dimulai dan sangat mempengaruhi kinerja model. Oleh karena itu, pemilihan hyperparameter yang tepat dapat memberikan hasil model dengan kinerja optimal.
Model random forest memiliki beberapa hyperparameter utama seperti jumlah pohon (n_estimators
), kedalaman pohon (max_depth
), jumlah maksimal fitur untuk penentuan splitting (max_features
) dan sebagainya. Untuk mendapatkan performa terbaik, kita perlu melakukan tuning hyperparameter ini. Dalam PSO, kita mendefinisikan ruang pencarian hyperparameter berupa batas bawah dan batas atas untuk setiap hyperparameternya.
Pada contoh berikut kita akan melakukan pencarian untuk 4 hyperparameter yaitu:
n_estimators
: jumlah pohon (100 hingga 500).max_depth
: kedalaman maksimal pohon (2 hingga 20).min_samples_split
: jumlah minimal sampel yang diperlukan untuk membagi node (2 hingga 20).max_features
: jumlah fitur yang dipertimbangkan pada pembagian setiap node dapat berupa proporsi maupun integer. Di sini kita akan gunakan proporsi (0.1, 1.0)
Python
# Batasan hyperparameter: # Batas bawah untuk n_estimators, max_depth, min_samples_split, max_features lb = [10, 2, 2, 0.1] # Batas atas untuk n_estimators, max_depth, min_samples_split, max_features ub = [200, 20, 20, 1.0]
Fungsi Objektif
Fungsi objektif adalah fungsi yang digunakan dalam proses optimasi untuk menentukan seberapa baik suatu solusi atau konfigurasi dalam memenuhi tujuan tertentu. Dalam konteks machine learning atau optimasi, fungsi objektif mengukur performa solusi berdasarkan kriteria yang ditetapkan (misalnya, akurasi model, biaya, atau kesalahan prediksi).
Dalam masalah optimasi:
- Jika kita ingin meminimalkan suatu nilai (misalnya, kesalahan), maka fungsi objektif akan mengevaluasi solusi dengan tujuan untuk mendapatkan nilai sekecil mungkin.
- Jika kita ingin memaksimalkan suatu nilai (misalnya, akurasi), kita bisa menggunakan fungsi objektif yang berfungsi dengan cara serupa tetapi tujuannya adalah untuk meningkatkan nilai setinggi mungkin.
Secara sederhana, fungsi objektif adalah target yang kita coba optimalkan, dan metode seperti PSO digunakan untuk menemukan solusi terbaik berdasarkan hasil evaluasi fungsi ini.
Adapun fungsi pso_objective
berikut ini, dibuat untuk|engevaluasi performa model Random Forest pada kombinasi hyperparameter tertentu dan mengembalikan nilai yang akan digunakan oleh algoritma PSO untuk mengarahkan pencarian hyperparameter terbaik.
Python
# Fungsi objektif untuk optimasi hyperparameter Random Forest def pso_objective(params): # Param adalah [n_estimators, max_depth, min_samples_split, max_features] n_estimators = int(params[0]) max_depth = int(params[1]) min_samples_split = int(params[2]) max_features = float(params[3]) # Definisikan model Random Forest dengan hyperparameter yang dioptimalkan model = RandomForestClassifier( n_estimators=n_estimators, max_depth=max_depth, min_samples_split=min_samples_split, max_features=max_features, random_state=42, ) # Evaluasi model dengan cross-validation score = cross_val_score(model, X, y, cv=5, scoring="accuracy").mean() # PSO meminimalkan fungsi, jadi kita negasikan skor untuk memaksimalkan akurasi return -score
Pencarian Hyperparameter dengan PSO
Setelah menentukan batas atas, batas bawah hyperparameter, dan fungsi objektif, kita dapat menggunakan fungsi pso
dari pustaka pyswarm. Beberapa parameter penting yang perlu ditentukan dalam pso
adalah:
- Fungsi Objektif (
func
): Fungsi yang akan dioptimalkan, sepertipso_objective
, yang mengevaluasi kombinasi hyperparameter. - Batas Bawah (
lb
) dan Batas Atas (ub
): Mendefinisikan rentang nilai hyperparameter yang akan dioptimalkan. - Ukuran Kawanan (
swarmsize
): Jumlah partikel yang digunakan dalam setiap iterasi, menentukan cakupan pencarian. - Iterasi Maksimum (
maxiter
): Jumlah iterasi maksimum yang akan dijalankan oleh PSO untuk memperbarui partikel.
Parameter tambahan opsional seperti omega
, phip
, dan phig
juga dapat diatur untuk mengontrol perilaku partikel dalam pencarian solusi terbaik.
Waktu pencarian menggunakan PSO dapat bervariasi tergantung jenis model yang dioptimalkan, banyaknya hyperparameter serta rentang nilai yang digunakan dan tentunya semakin banyak iterasi maka waktu pencarian akan semakin lama.
Output di bawah ini menunjukkan hyperparameter optimal yang ditemukan berdasarkan validasi silang pada data latih. Pengaturan yang diperoleh adalah n_estimators=84
, max_depth=13
, min_samples_split=4
dan max_features=0,566
. Adapun rata-rata akurasi dari 5 fold validasi silang dengan pengaturan tersebut adalah sebesar 0,7875
.
Python
# Optimasi menggunakan PSO best_params, best_score = pso( pso_objective, lb, ub, kwargs={"X": X_train, "y": y_train}, swarmsize=30, maxiter=50 ) print("Best Hyperparameters:", best_params) print("Best Score:", -best_score)
# OUTPUT Stopping search: Swarm best objective change less than 1e-08 Best Hyperparameters: [84.32999294 13.31920437 4.70119775 0.56600369] Best Score: 0.7875000000000001
Melatih Model dengan Hyperparameter Optimal
Setelah mendapatkan hyperparameter terbaik melalui optimasi menggunakan PSO, langkah selanjutnya adalah melatih model Random Forest dengan menggunakan seluruh data pelatihan. Model dibangun dengan hyperparameter optimal yang ditemukan pada proses optimasi.
Python
# Hyperparameter terbaik yang diperoleh dari PSO best_n_estimators = int(best_params[0]) best_max_depth = int(best_params[1]) best_min_samples_split = int(best_params[2]) best_max_features = float(best_params[3]) # Definisikan model Random Forest dengan hyperparameter optimal rf_model = RandomForestClassifier( n_estimators=best_n_estimators, max_depth=best_max_depth, min_samples_split=best_min_samples_split, max_features=best_max_features, random_state=42 ) # Melatih model dengan seluruh data pelatihan rf_model.fit(X_train, y_train)
# OUTPUT RandomForestClassifier(max_depth=13, max_features=0.5660036940709607, min_samples_split=4, n_estimators=84, random_state=42)
Evaluasi Model
Model yang sudah dilatih menggunakan parameter optimal, selanjutnya dievaluasi menggunakan data uji. Berdasarkan hasil evaluasi, diperoleh akurasi model sebesar 0,776.
Secara keseluruhan model mampu memprediksi secara tepat sekitar 77,6 persen dari keseluruhan data uji yang diberikan. Berdasarkan confussion matrix serta classification report, kita juga dapat melihat kinerja model berdasarkan metrik-metrik lainnya.
Python
# menghitung akurasi berdasarkan hasil prediksi y_pred = rf_model.predict(X_test) # Akurasi akurasi = accuracy_score(y_test, y_pred) print(f"\nAkurasi: {akurasi: .3f}") # Confusion matrix cm = confusion_matrix(y_test, y_pred) print(f"\nConfussion Matrix:\n{cm}") # Classification Report cr = classification_report(y_test, y_pred) print(f"\nClassification Report:\n{cr}")
# OUTPUT Akurasi: 0.776 Confussion Matrix: [[147 39] [ 38 119]] Classification Report: precision recall f1-score support HIGH 0.79 0.79 0.79 186 LOW 0.75 0.76 0.76 157 accuracy 0.78 343 macro avg 0.77 0.77 0.77 343 weighted avg 0.78 0.78 0.78 343
Kode Lengkap
Berikut adalah kode lengkap keseluruhan proses pemodelan Random Forest dengan tuning hyperparameter menggunakan particle swarm optimization:
Python
# PENYIAPAN PAKET # manipulasi dan pemrosesan data import pandas as pd # pembagian data from sklearn.model_selection import train_test_split # validasi silang K-Fold from sklearn.model_selection import cross_val_score # model random forest from sklearn.ensemble import RandomForestClassifier # metrik evaluasi model klasifikasi from sklearn.metrics import accuracy_score, confusion_matrix, classification_report # particle swarm optimization from pyswarm import pso # PENYIAPAN DATA # Memuat dataset dari URL url = ( "https://raw.githubusercontent.com/sainsdataid/dataset/main/wine-quality-binary.csv" ) data = pd.read_csv(url) # Melihat struktur data data.info() # Menghapus kolom 'id' data.drop(columns="id") # Melihat jumlah observasi per kelas respon print(data.groupby("quality").agg({"quality": "count"})) # PEMBAGIAN DATA LATIH DAN DATA UJI # Memisahkan fitur dan respon X = data.drop(columns="quality") y = data["quality"] # Membagi dataset menjadi data latih dan data uji X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.3, random_state=123 ) # PENENTUAN BATAS ATAS DAN BATAS BAWAH # Batas bawah untuk n_estimators, max_depth, min_samples_split, max_features lb = [10, 2, 2, 0.1] # Batas atas untuk n_estimators, max_depth, min_samples_split, max_features ub = [200, 20, 20, 1.0] # FUNGSI OBJEKTIF # Fungsi objektif untuk optimasi hyperparameter Random Forest def pso_objective(params, X, y): # Param adalah [n_estimators, max_depth, min_samples_split, max_features] n_estimators = int(params[0]) max_depth = int(params[1]) min_samples_split = int(params[2]) max_features = float(params[3]) # Definisikan model Random Forest dengan hyperparameter yang dioptimalkan model = RandomForestClassifier( n_estimators=n_estimators, max_depth=max_depth, min_samples_split=min_samples_split, max_features=max_features, random_state=42, ) # Evaluasi model dengan cross-validation score = cross_val_score(model, X, y, cv=5, scoring="accuracy").mean() # PSO meminimalkan fungsi, jadi kita negasikan skor untuk memaksimalkan akurasi return -score # PROSES OPTIMASI best_params, best_score = pso( pso_objective, lb, ub, kwargs={"X": X_train, "y": y_train}, swarmsize=30, maxiter=50 ) print("Best Hyperparameters:", best_params) print("Best Score:", -best_score) # MELATIH MODEL DENGAN HYPERPARAMETER OPTIMAL # Hyperparameter terbaik yang diperoleh dari PSO best_n_estimators = int(best_params[0]) best_max_depth = int(best_params[1]) best_min_samples_split = int(best_params[2]) best_max_features = float(best_params[3]) # Definisikan model Random Forest dengan hyperparameter optimal rf_model = RandomForestClassifier( n_estimators=best_n_estimators, max_depth=best_max_depth, min_samples_split=best_min_samples_split, max_features=best_max_features, random_state=42, ) # Melatih model dengan seluruh data pelatihan rf_model.fit(X_train, y_train) # EVALUASI MODEL # menghitung akurasi berdasarkan hasil prediksi y_pred = rf_model.predict(X_test) # Akurasi akurasi = accuracy_score(y_test, y_pred) print(f"\nAkurasi: {akurasi: .3f}") # Confusion matrix cm = confusion_matrix(y_test, y_pred) print(f"\nConfussion Matrix:\n{cm}") # Classification Report cr = classification_report(y_test, y_pred) print(f"\nClassification Report:\n{cr}")