Sebelumnya kita import terlebih dahulu library-library ini digunakan untuk dapat memanggil berbagai fungsi yang akan memudahkan kita dalam proses implementasi untuk pembuatan program.
# u/ mengabaikan warnings / peringatan
import warnings
warnings.filterwarnings("ignore")# u/ menghubungkan ke gdrive
from google.colab import drive
from google.colab import files# u/ mengolah data csv
import os
import numpy as np
import pandas as pd# u/ plot visualisasi data
import seaborn as sns
import matplotlib.pyplot as plt
import plotly.graph_objects as go
from plotly.subplots import make_subplots# u/ preprocessing data
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import RobustScaler,MinMaxScaler# u/ training dan evaluasi model
# u/ saving model
from xgboost import XGBClassifier
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix,precision_score,recall_score,f1_score
import joblib
Nah setelah melakukan import library kemudian kita siapkan dataset yang akan kita gunakan nantinya. Dataset ini didapat dari website Kaggle berjudul Cardiovascular Disease Dataset yang berjumlah 70.000 data dengan format file (.csv). Selain itu dataset ini memiliki feature berjumlah 11 Feature dan 1 Target feature (2 Class = Cardio (1) , Non-Cardio (0).
1.1 Load Dataset
Load dataset menggunakan library pandas dengan fungsi read_csv. Pada dataset ini menggunakan separator “;” untuk pembatas tiap kolom.
df_cardio = pd.read_csv('cardio_train.csv', sep=';', index_col="id")
df_cardio.head()
Hasilnya sebagai akan nampak sebagai berikut :
1.2 Check Nilai Null / NaN / NA
Selanjutnya kita mengecek nilai kosong pada dataset dengan menggunakan fungsi isna() kemudian ditotal.
df_cardio.isna().sum()
Pada dataset ini tidak ditemukan nilai null / NA pada dataset ini.
1.3 Merubah nama kolom dan konversi kolom ‘age’
Pada tahap ini dilakukan rename kolom untuk memudahkan dalam mengenali data serta dilakukan konversi format dari hari menjadi format tahun. Konversi ini ditujukan untuk memudahkan dalam mengenali usia dari pasien penderita cardiovascular.
# U/ merubah nama kolom
df_cardio.rename(columns={'ap_hi': 'systolic', 'ap_lo': 'diastolic','gluc': 'glucose', 'alco': 'alcohol','cardio': 'cardiovascular'}, inplace=True)# Konversi kolom age dari format hari menjadi format tahun (365)
df_cardio.age = np.round(df_cardio.age/365,decimals=0)
df_cardio.head()
Sehingga hasilnya sebagai berikut :
1.4 Describe Data
Pada tahapan ini kita mulai mengeksplore dataset nya dengan cara mendeskripsikan data tersebut.
df_cardio.describe().round()
Setelah kita mengeksplore dataset tersebut dan melalui penjabaran deskripsi dataset diatas kita mendapat beberapa informasi antara lain :
a. Usia terendah penderita penyakit ini berumur 30th dan usia tertingginya 65th maka dapat disimpulkan bahwa koresponden penelitian ini tidak melibatkan anak-anak
b. Berdasarkan referensi dari Heart.org dikatakan bahwa penderita dengan tekanan darah tinggi (systolic) lebih dari 180 mm Hg atau tekanan darah rendah (diastolic) lebih dari 120 mm Hg harus sesegera mungkin ditangani dokter (parah). Namun pada data ini nilai tertinggi berada pada 16020 mm Hg dan 110000 mm Hg dimana hal tersebut aneh serta pada nilai minimumnya yang berada pada nilai negatif sehingga dapat dikatakan sebagai data pencilan / outlier
c. Pada kolom height ketinggian Minimum dan Maksimum terlihat salah. Meskipun juga dapat merepresentasikan manusia terkecil dan tertinggi : 55 cm dan 250 cm, namun tetap tampak seperti kesalahan data (Error).
Nah pada tahapan ini dilakukan pengolahan dataset agar tiap feature di dataset tsb menjadi feature yang optimal sehingga memudahkan kita untuk melakukan proses klasifikasi.
2.1 Remove Data Duplicate
Ditahapan ini kita akan menghapus / remove data ganda pada dataset menggunakan fungsi drop_duplicates().
# Data duplicate
print("Total Data Duplicate = ",df_cardio.duplicated().sum(), "nn")
df_cardio[df_cardio.duplicated()].sort_values(by=['gender', 'height', 'weight'], ascending= False)# Remove data duplicated
df_cardio.drop_duplicates(inplace=True)
Total Data duplicate pada dataset tersebut sebesar 3816 data. Maka ketika dilakukan remove data akan berkurang jumlahnya menjadi 66184 data.
2.2 Remove Outlier pada Systolic , Diastolic , Height dan Weight.
Pada boxplot Systolic dan Diastolic berikut nampak jika terdapat banyak outlier diluar kuartil ke-3.
Tidak semua semua outlier di luar kuartil ke-3 akan diremove / hapus karena pasien dengan tekanan darah >180 pada systolic maupun >120 pada diastolic dapat mengalami krisis hipertensi dalam artian data tersebut masih bisa digunakan. Maka dari itu saya ambil patokan untuk pasien krisis hipertensi di 210 systolic dan 150 diastolic. Sehingga didapatkan batas 90–210 systolic dan 65–150 diastolic.
df_cardio = df_cardio[~((df_cardio['systolic'] >= 210) | (df_cardio['systolic'] <= 90)|(df_cardio['diastolic'] >= 150) | (df_cardio['diastolic'] <= 65))]
Setelah digunakan patokan tersebut maka hasil yang didapat sebagai berikut:
Begitu pula yang akan kita lakukan juga pada kolom height dan weight.
df_cardio = df_cardio[(df_cardio['height'] > 143) & (df_cardio['height'] < 210)]
df_cardio = df_cardio[~(df_cardio['weight'] < 40)]
Sehingga hasil yang didapatkan sebagai berikut:
2.3 Split Dataset
Pada tahapan ini dilakukan split data / pembagian data dengan ratio 80:20. Pembagian Data train sebesar 80% dan Data test sebesar 20% ratio ini didasari dari Pareto Principle.
# X feature dari data dan Y sebagai target label
X = df_cardio.drop(['cardiovascular'], axis = 1).copy()
y = df_cardio['cardiovascular']# Split Data berdasarkan Parrot Principle (80:20)
X_train,X_test,y_train,y_test = train_test_split(X,y, test_size = 0.20, random_state = 88)
2.4 Rescaling Dataset
Sebelum itu proses scaling ini terlebih dahulu dilakukan splitting data karena Jika scaling digunakan sebelum splitting data (train_test_split) maka akan terjadi kebocoran data. Untuk menanggulangi itu maka dilakukanlah scaling setelah splitting data (train_test_split)
Penjelasan memakai 2 Scaler yaitu Robust Scaler dan MinMax Scaler :
- MinMax Scaler :
Proses scaling yang akan mengubah setiap nilai di kolom secara proporsional dalam rentang [0,1]. - Robust Scaler :
Sebagai alternatif proses scaling ketika terdapat data pencilan / outlier.
#RobustScaler
rs = RobustScaler()#Diastolic - RobustScaler
X_train['diastolic'] = rs.fit_transform(X_train[['diastolic']].values)
X_test['diastolic'] = rs.fit_transform(X_test[['diastolic']].values)#Systolic - RobustScaler
X_train['systolic'] = rs.fit_transform(X_train[['systolic']].values)
X_test['systolic'] = rs.fit_transform(X_test[['systolic']].values)#Weight - RobustScaler
X_train['weight'] = rs.fit_transform(X_train[['weight']].values)
X_test['weight'] = rs.fit_transform(X_test[['weight']].values)#MinMaxScaler
mms = MinMaxScaler()#Age - MinMaxScaler
X_train['age'] = mms.fit_transform(X_train[['age']].values)
X_test['age'] = mms.fit_transform(X_test[['age']].values)#Height - MinMaxScaler
X_train['height'] = mms.fit_transform(X_train[['height']].values)
X_test['height'] = mms.fit_transform(X_test[['height']].values)
Pada tahapan ini dilakukan implementasi model XGBoost dengan memanggil fungsi model XGBoost dari sklearn yaitu XGBClassifier().
# Deklarasi model XGBoost yaitu eXtreme Gradient Boosting Classifier
xgb_model = XGBClassifier()
xgb_model.fit(X_train,y_train)
ypred_xgb = xgb_model.predict(X_test)#Classification Report
print("XGBoost Model - Classification Report n")
print(classification_report(y_test, ypred_xgb))#Confusion Matrix
print("XGBoost Model - Classification Report n")
print(confusion_matrix(y_test, ypred_xgb))
XGBClassifier dideklarasikan kemudian dilatih / training dengan data train kemudian hasil prediksi nya menggunakan data test. Sehingga hasil akurasi yang didapat pada proses klasifikasi ini sebesar 73%.
Nilai Precision Model : 0.7914805908622466
Nilai Recall Model : 0.681757656458056
Nilai F1-Score Model : 0.7325331849614498
Selanjutnya dilakukan hyperparameter tuning untuk mendapatkan best parameter pada model XGBoost menggunakan Library GridSearchCV. Beberapa parameter yang akan diuji demi mendapatkan parameter terbaik antara lain: learning rate, max_depth, subsample, n_estimator dll.
#Deklarasi Model
xgb_model = XGBClassifier()# Parameter untuk diHparams Tuning
param_grid = {
'learning_rate': [0.1, 0.2],
'max_depth': [6],
'min_child_weight': [2],
'subsample': [0.7],
'n_estimators': [100, 300, 600]}# Proses Tuning Menggunakan GridSearchCV
xgb_tuning = GridSearchCV(xgb_model, param_grid, scoring='accuracy', cv=None, n_jobs=1)
xgb_tuning.fit(X_train, y_train)# Hasil Parameter Terbaik
print("Best Parameter dari XGBoost : {}".format(xgb_tuning.best_params_))
Nah.. setelah melakukan proses tuning didapatkanlah parameter terbaik untuk diimplementasikan dan diuji pada model sebagai berikut :
Best Parameter dari XGBoost : {'learning_rate': 0.1, 'max_depth': 6, 'min_child_weight': 2, 'n_estimators': 100, 'subsample': 0.7}
Kemudian best parameter tsb diimplentasikan kedalam model XGBoost sehingga hasil yang didapatkan sebagai berikut:
Nilai Precision Model : 0.7667468223978015
Nilai Recall Model : 0.7022180273714016
Nilai F1-Score Model : 0.7330651120781673
Pada tahap terakhir dilakukan evaluasi model sehingga dapat mengetahui perbedaan hasil yang didapat sebelum dan sesudah diimplementasikannya Hyperparameter Tuning pada model XGBoost dalam mengklasifikasikan penyakit Cardiovascular. Pada segi akurasi mengalami peningkatan namun terjadi penurunan pada precision score tetapi recall mengalami kenaikan.
Yup gak kerasa udah kesimpulan aja. Kesimpulannya hasil yang didapat memiliki perbedaan sedikit namun kurang signifikan, tetapi Hyperparameter Tuning dapat menaikkan nilai akurasi pada model dan memberikan parameter terbaik untuk digunakan pada model. Selain itu kalian juga dapat mengeksplore lebih lagi terhadap datasetnya seperti penambahan feature BMI yang didapat dari height dan weight, menggunakan algoritma lain seperti LGBClassifier, RandomForest dll.
Terima kasih sudah menyempatkan membaca artikel ini jangan lupa mampir ke github ku untuk mendapat full codenya. Semoga dengan adanya artikel ini membuat kalian merasa terbantu dan tetap semangat untuk mengeksplore lebih dalam lagi tentang materi ini…. bye bye …
Instagram : Hazmi Cokro
Github : Hazmi Cokro