Tuning Model XGBoost dengan Python

Tuning Model XGBoost Python Sklearn

XGBoost (Extremely Gradient Boosting) adalah pustaka gradient boosting terdistribusi yang telah dioptimasi untuk mampu bekerja dengan sangat efisien, fleksibel, dan portabel. Algoritma ini merupakan peningkatan dari algoritma Gradient Boosting. XGBoost mampu menyelesaikan banyak masalah pembelajaran mesin dengan cara yang cepat dan akurat. Kode yang sama juga dapat dijalankan pada distributed environment seperti Hadoop, SGE dan MPI, serta mampu menangani komputasi yang melibatkan miliaran data.

Pada tutorial ini, kita akan membahas penggunaan XGBoost untuk pemodelan klasifikasi. Sebelum melakukan pemodelan pastikan sudah menginstal pustaka yang diperlukan.

Python

# menggunakan pip
pip install pandas
pip install scikit-learn
pip install xgboost

Penyiapan Data

Dataset yang akan kita gunakan adalah red wine quality. Tujuan utama yang ingin dicapai adalah membuat model XGBoost untuk memprediksi kualitas red wine berdasarkan 10 karakteristik hasil tes physicochemical. Adapun label yang digunakan adalah quality, yang merupakan ukuran kualitas red wine dengan rentang nilai 3-8.

Seperti yang disampaikan di atas, model XGBoost yang akan dibangun adalah pemodelan klasifikasi sehingga fitur quality tersebut akan kita kelompokkan terlebih dahulu. Misal, untuk red wine dengan kualitas lebih dari 5 masuk dalam kelompok kualitas Baik, sementara kurang dari 5 masuk kelompok kurang baik. Namun tentu saja anda dapat mencoba batasan lainnya.

Dari hasil pengelompokan diperoleh 855 data yang memiliki kualitas baik (label 1) dan 744 lainnya dengan kualitas kurang baik (label 0).

Python

import pandas as pd

# membaca dataset
data = pd.read_csv("winequality-red.csv")

# menampilkan informasi dataset
print(data.info())

print("===========================================")

# melihat nilai unik pada kolom "quality"
print(f"nilai quality : {data['quality'].unique()}")

# merubah nilai pada kolom "quality" menjadi biner (1 : good dan 0 : not good)
data["quality"] = data["quality"].apply(lambda x: 1 if x > 5 else 0)

print("===========================================")

# menampilkan jumlah amatan menurut kolom "quality"
print(data.groupby(["quality"]).count()["alcohol"])

Output

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1599 entries, 0 to 1598
Data columns (total 12 columns):
 #   Column                Non-Null Count  Dtype  
---  ------                --------------  -----  
 0   fixed acidity         1599 non-null   float64
 1   volatile acidity      1599 non-null   float64
 2   citric acid           1599 non-null   float64
 3   residual sugar        1599 non-null   float64
 4   chlorides             1599 non-null   float64
 5   free sulfur dioxide   1599 non-null   float64
 6   total sulfur dioxide  1599 non-null   float64
 7   density               1599 non-null   float64
 8   pH                    1599 non-null   float64
 9   sulphates             1599 non-null   float64
 10  alcohol               1599 non-null   float64
 11  quality               1599 non-null   int64  
dtypes: float64(11), int64(1)
memory usage: 150.0 KB
None

===========================================
nilai quality : [5 6 7 4 8 3]
===========================================

quality
0    744
1    855
Name: alcohol, dtype: int64

Data Latih dan Data Uji

Pembagian data menjadi data latih dan data uji dilakukan menggunakan fungsi train_test_split. Beberapa pengaturan yang kita buat yaitu:

  • test_size=0.2 : 20% data uji dan 80% data latih
  • stratify=y : pembagian data dilakukan menggunakan stratified sampling menurut variabel y. Artinya, data akan dibagi sehingga masing-masing kelas memiliki keterwakilan yang proporsional pada data latih dan data uji.
  • random_state=123 : silahkan menggunakan sembarang bilangan (gunakan nilai yang sama jika ingin mereproduksi hasil yang sama persis dengan tutorial ini)

Python

# memuat pustaka yang diperlukan
from sklearn.model_selection import train_test_split

# features
X = data.drop(["quality"], axis=1)

# label
y = data[["quality"]]

# pembagian data
X_train, X_test, y_train, y_test = train_test_split(
    X,
    y,
    test_size=0.2,
    stratify=y,
    random_state=123,
)

# melihat jumlah data
print("data latih :", len(y_train))
print("data uji :", len(y_test))

Output

data latih : 1279
data uji : 320

Model XGBoost

Pembuatan model XGBoost untuk masalah klasifikasi dapat dilakukan menggunakan fungsi XGBClassifier pada pustaka xgboost. Berikut langkah pengerjaannya:

  • memuat pustaka xgboost
  • memuat pustaka sklearn.metrics untuk mengukur performa model meliputi nilai akurasi dan confusion matrix
  • membuat list yang berisi tuple pasangan data latih dan data uji. Variabel ini diperlukan untuk evaluasi dalam proses pembuatan model
  • membuat model menggunakan fungsi XGBClassifier. Pada contoh di bawah ini, nilai-nilai parameter kita set dengan nilai defaultnya.
    • max_depth : Maksimum kedalaman pohon yang ditumbuhkan. Nilai yang lebih kecil akan mencegah adanya overfitting.
    • learning_rate atau eta : besarnya penyusutan pada setiap pembaruan untuk mencegah overfitting. Setelah setiap 1 proses boosting, kita dapat secara langsung memperoleh bobot fitur baru, dan nilai learning_rate akan mengurangi bobot fitur tersebut agar proses boosting lebih konservatif
    • n_estimator : banyaknya (maksimum) pohon keputusan yang ditumbuhkan
    • early_stopping_rounds : digunakan untuk menghentikan proses pelatihan jika setelah iterasi sebanyak early_stopping_rounds, performa model tidak meningkat lagi
    • selain yang sudah disebutkan di atas, terdapat beberapa parameter lain yang dapat diatur (lihat di sini)
  • melatih model dengan memanggil method fit.
  • memprediksi data uji
  • mengukur nilai akurasi model pada data uji

Python

import xgboost as xgb
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report

# membuat list dataset untuk evaluasi
eval_set = [(X_train, y_train), (X_test, y_test)]

# inisiasi model XGBoost
model = xgb.XGBClassifier(
    max_depth=6,
    learning_rate=0.3,
    n_estimators=100,
    early_stopping_rounds=10,
)

# melatih model
model.fit(X_train, y_train, eval_set=eval_set, verbose=0)

# memprediksi data uji
y_pred = model.predict(X_test)

# menampilkan nilai akurasi
print("Accuracy:", accuracy_score(y_test, y_pred), "\n")

# menampilkan confusion matrix
print(confusion_matrix(y_test, y_pred), "\n")

# menampilkan classification report
print(classification_report(y_test, y_pred))

Output

Accuracy: 0.80625 

[[118  31]
 [ 31 140]] 

              precision    recall  f1-score   support

           0       0.79      0.79      0.79       149
           1       0.82      0.82      0.82       171

    accuracy                           0.81       320
   macro avg       0.81      0.81      0.81       320
weighted avg       0.81      0.81      0.81       320

Output model yang telah dibuat menunjukkan nilai akurasi sebesar 0.80625 atau model mampu memprediksi dengan benar sebanyak 80,6% data uji. Lebih rinci dari 149 kelas 0 (“kurang baik”) pada data uji, 118 diprediksi tepat dan sebanyak 31 salah. Begitu pula untuk kelas 1 (“baik”) dimana 140 diprediksi benar namun sebanyak 31 salah prediksi.

Model yang dihasilkan sebelumnya kita peroleh melalui nilai parameter tertentu. Dengan menggunakan grid search, kita bisa menyiapkan daftar nilai untuk masing-masing parameter, kemudian akan dilakukan pencarian model terbaik berdasarkan kombinasi nilai tersebut. proses ini diharapkan mampu meningkatkan performa model dasarnya.

Pencarian dengan grid search dapat dibuat menggunakan fungsi GridSearchCV dari sklearn.model_selection. Berikut langkah pengerjaannya:

  • memuat fungsi GridSearchCV pada modul sklearn.model_selection
  • inisiasi daftar nilai parameter untuk proses grid search dalam bentuk dict {key: value}
    • key menunjukkan nama parameter yang akan di-tuning
    • value untuk setiap key disimpan dalam bentuk list [...]
  • inisiasi model awal untuk proses grid search (untuk parameter yang tidak ikut di-tuning dapat dimasukkan pada saat inisiasi model awal), beberapa yang kita tambahkan yaitu:
    • early_stopping_rounds (sudah jelas)
    • n_jobs : parameter ini tidak berkaitan dengan performa model, nilai n_jobs menunjukkan banyaknya proses paralel yang akan dilakukan pada 1 waktu.
    • n_jobs secara default bernilai None, atau hanya satu pekerjaan yang akan dilakukan pada satu waktu
    • n_jobs=-1, pelatihan model dilakukan secara paralel menggunakan semua inti (core) yang tersedia pada CPU
    • n_jobs=2, dua pekerjaan dilakukan secara paralel
    • semakin tinggi nilai yang diberikan akan meningkatkan waktu komputasi namun akan menggunakan resource komputer lebih besar
  • inisiasi model grid search menggunakan fungsi GridSearchCV
    • model : menunjukkan model yang digunakan untuk proses grid search
    • param_grid : daftar parameter yang akan digunakan untuk proses grid search
    • cv : jumlah fold yang digunakan untuk validasi silang menggunakan K-Fold CV
    • scoring : metrik yang digunakan untuk menentukan model terbaik hasil grid search
  • melatih model
  • memprediksi data uji
  • evaluasi model

Python

from sklearn.model_selection import GridSearchCV

# daftar parameter untuk grid search
list_param = {
    "subsample": [0.5, 0.75, 1],
    "colsample_bytree": [0.5, 0.75, 1],
    "max_depth": [3, 6, 10, 15],
    "min_child_weight": [1, 5, 10],
    "learning_rate": [0.3, 0.2, 0.1],
    "n_estimators": [50, 100],
}


# Inisiasi model XGBoost
model = xgb.XGBClassifier(
    n_jobs=2,
    early_stopping_rounds=10,
)

# inisiasi model GridSearchCV
model_tune = GridSearchCV(
    model,
    param_grid=list_param,
    cv=5,
    scoring="accuracy",
)


# pelatihan model
model_tune.fit(
    X_train,
    y_train,
    eval_set=eval_set,
    verbose=0,
)


# menampilkan parameter terbaik
print(model_tune.best_params_, "\n")

# prediksi data uji
y_pred = model_tune.predict(X_test)

# menampilkan nilai akurasi
print("Accuracy:", accuracy_score(y_test, y_pred), "\n")

# menampilkan confusion matriz
print(confusion_matrix(y_test, y_pred), "\n")

# menampilkan classification report
print(classification_report(y_test, y_pred))

Output

{
 'colsample_bytree': 0.75, 
 'learning_rate': 0.3, 
 'max_depth': 10, 
 'min_child_weight': 1, 
 'n_estimators': 50, 
 'subsample': 0.75
} 

Accuracy: 0.834375 

[[122  27]
 [ 26 145]] 

              precision    recall  f1-score   support

           0       0.82      0.82      0.82       149
           1       0.84      0.85      0.85       171

    accuracy                           0.83       320
   macro avg       0.83      0.83      0.83       320
weighted avg       0.83      0.83      0.83       320

Dari output di atas, model terbaik diperoleh dengan nilai parameter 'colsample_bytree': 0.75, 'learning_rate': 0.3, dan seterusnya hingga 'subsample': 0.75.

Prediksi data uji menunjukkan nilai akurasi sebesar 83,44% dimana nilai ini sekitar 2.8 lebih tinggi dibandingkan model sebelumnya. Dari 149 data uji dengan label 0 (“kurang baik”), 122 diprediksi dengan tepat dan 27 lainnya salah. Adapun untuk data uji dengan label 1 (“baik”) sebanyak 145 diprediksi dengan tepat dan 26 lainnya salah.

Hasil ini tentu saja dapat berbeda jika daftar parameter yang digunakan dalam proses grid search juga berbeda, begitu pula pembagian data latih dan data uji.

Menyimpan dan Memuat Model

Model yang telah dibuat dapat disimpan dalam bentuk file. Penyimpanan ini berguna agar model dapat digunakan lagi ataupun didistribusikan tanpa harus melakukan proses pelatihan lagi.

Untuk menyimpan model kita dapat menggunakan fungsi dump dari pustaka joblib. Model yang sudah disimpan dapat dibuka kembali menggunakan fungsi load yang juga tersedia pada pustaka joblib.

Python

from joblib import dump, load

# Menyimpan model ke dalam file
dump(model_tune, "model_tune.joblib")


# Membaca model dari file
model_from_file = load("model_tune.joblib")

print(model_from_file.best_params_)

Output

{
 'colsample_bytree': 0.75, 
 'early_stopping_rounds': 10, 
 'eval_metric': 'error', 
 'learning_rate': 0.3, 
 'max_depth': 10, 
 'min_child_weight': 1, 
 'n_estimators': 50, 
 'subsample': 0.75
}

Selamat mencoba!

API

Tulisan Lainnya

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *

Daftar Isi