Perbandingan antara K-Nearest Neighbor & Logistic Regression dalam Pengklasifikasian Data
Ditulis oleh Justin Jap & David Christian.
Pada kesempatan kali ini, kita akan mempelajari cara untuk melakukan pengklasifikasian data dengan menerapkan algoritma K-Nearest Neighbor (KNN) dan analisis Logistic Regression atau Regresi Logistik. Apakah yang dimaksud dengan pengklasifikasian? Pengklasifikasian adalah suatu proses mengelompokkan objek ke dalam suatu kelas atau kategori yang telah ditentukan (Handoko, 2021). Kita akan mengaplikasikan kedua metode tersebut pada dataset Breast Cancer Wisconsin (Diagnostic). Dataset ini dikeluarkan oleh University of Wisconsin yang berisi 569 hasil diagnosis kanker payudara beserta dengan karakteristik-karakteristik dari inti sel kanker tersebut. Algoritma K-Nearest Neighbor (KNN) dan analisis Logistic Regression akan diterapkan pada dataset ini untuk menentukan hasil dari diagnosis kanker payudara berdasarkan karakteristik dari inti sel kanker tesebut. Setelah kita mengaplikasikan kedua metode tersebut, kita akan melihat metode mana yang akan memberikan hasil yang lebih akurat.
Apa itu Analisis K-Nearest Neighbor & Logistic Regression?
K-Nearest Neighbor (KNN) adalah metode yang digunakan untuk melakukan klasifikasi dari suatu data berdasarkan atribut-atributnya dengan mengambil sejumlah K data terdekat (tetangganya). KNN menggunakan algoritma supervised training dimana hasil dari query instance yang baru diklasifikasikan merupakan mayoritas dari kategori pada KNN.
Kelebihan K-Nearest Neighbor (KNN):
- Hanya sedikit parameter yang perlu ditentukan/diatur.
- Dapat digunakan pada kasus klasifikasi non-linear.
Sama seperti KNN, Logistic Regression atau Regresi Logistik digunakan untuk melakukan klasifikasi. Regresi Logistik digunakan untuk melakukan prediksi dari probabilitas suatu kejadian seperti halnya dengan Regresi Linier. Perbedaannya adalah variabel Y pada Regresi Logistik hanya ada 2 pilihan saja atau bersifat biner, seperti Ya atau Tidak, Sukses atau Tidak Sukses, Positif atau Negatif, dan lain-lain.
Kelebihan Logistic Regression:
- Lebih cepat bila dibandingkan dengan algoritma KNN.
- Dapat menunjukkan confidence level dari prediksinya sedangkan KNN hanya dapat menampilkan label.
Praktik Analisis KNN & Logistic Regression Menggunakan Python
Kita akan mencoba untuk membuat sebuah model KNN dan juga sebuah model Logistic Regression yang dapat memprediksi diagnosis kanker payudara.
Step 1: Download Dataset
1.1. Kita akan menggunakan dataset Breast Cancer Wisconsin (Diagnostic) Data Set yang dipublikasikan oleh UCI Machine Learning di Kaggle. Download file CSV melalui URL berikut: https://www.kaggle.com/datasets/uciml/breast-cancer-wisconsin-data
1.2. Buatlah repository baru dan upload file CSV tersebut ke dalam repository yang dibuat.
1.3. Setelah file CSV telah diupload, tekan file tersebut untuk membukanya di GitHub lalu tekan tombol “raw” yang berada di bagian kanan atas. URL dari halaman raw yang muncul akan digunakan sebagai path dari dataset kita.
Step 2: Lakukan Import Library
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import confusion_matrix, accuracy_score
from sklearn.feature_selection import SelectKBest, chi2
Di sini, terdapat beberapa library yang akan kita gunakan. Library pandas dan NumPy akan mempermudah kita dalam mengolah file CSV menjadi sebuah dataset yang dapat dimanfaatkan oleh library-library lainnya. Matplotlib dan Seaborn akan digunakan untuk memvisualisasikan data yang kita gunakan, lalu sklearn atau scikit-learn akan digunakan untuk membuat sebuah model KNN dan Logistic Regression dari dataset kita.
Step 3: Import Dataset
3.1. Masukkan link raw.githubusercontent.com yang didapatkan pada step 1.3 dan masukkan ke dalam variabel path. Kita akan memuat file CSV sebagai dataset pandas dengan nama variabel dataset.
path = "https://raw.githubusercontent.com/dchristian09/breast_data/main/data.csv"
dataset = pd.read_csv(path)
dataset.info()
dengan kolom terikat yang akan digunakan adalah kolom:
- “diagnosis”: hasil diagnosis kanker payudara (M = malignant, B = benign)
3.2. Untuk menentukan kolom-kolom yang akan dianalisa dan digunakan dalam membangun model, kita akan menggunakan metode SelectKBest yang disediakan di library sklearn di mana metode ini akan mengembalikan kolom-kolom yang paling signifikan terhadap variabel terikat. Karena kasus kita merupakan kasus klasifikasi, maka kita akan menggunakan metode score_func = chi2 yang akan dimasukkan ke dalam parameter SelectKBest. Parameter terakhir berupa k yang dapat diisi dengan jumlah kolom yang ingin diambil (di sini kita akan mengambil 5 kolom yang paling signifikan). Variabel y akan diisi dengan kolom diagnosis sedangkan variabel X akan diisi dengan kolom 5 kolom variabel bebas yang paling signifikan.
X = dataset[["radius_mean", "texture_mean", "perimeter_mean", "area_mean", "smoothness_mean", "compactness_mean", "concavity_mean", "concave points_mean", "symmetry_mean", "fractal_dimension_mean"]]
y = dataset["diagnosis"]selector = SelectKBest(score_func=chi2, k=5)
selector.fit(X, y)
cols = selector.get_support(indices=True)
X = X.iloc[:,cols]
X.info()
Hasil dari kolom bebas yang diambil adalah:
- “radius_mean”: rata-rata jarak dari pusat sel ke titik-titik di perimeter (berupa float)
- “texture_mean”: rata-rata standar deviasi nilai gray-scale pada sel (berupa float)
- “perimeter_mean”: rata-rata perimeter dari sel (berupa float)
- “area_mean”: rata-rata area dari sel (berupa float)
- “concavity_mean”: rata-rata tingkat kecekungan dari kontur sel (berupa float)
3.3. Kita akan memeriksa apakah dataset kita memiliki nilai kosong. Karena dataset kita telah dipisah sebelumnya menjadi variabel X dan y, maka kita akan gabungkan terlebih dahulu menggunakan pd.concat.
print('Dataset memiliki nilai null: ', pd.concat([X, y], axis=1).isnull().values.any())
Hasil pengecekan berupa false yang berarti tidak ada nilai null di dalam dataset. Maka itu, kita dapat langsung lanjut ke langkah berikutnya.
Step 4: Mengubah Data Diskrit
Di kolom “diagnosis”, kita memiliki tipe data berupa huruf. Kita harus mengganti tipe data tersebut menjadi angka agar dapat diproses sehingga data “B” (benign) akan diubah menjadi angka 0 dan data “M” (malignant) akan diubah menjadi angka 1. Untuk melakukan hal tersebut, kita akan menggunakan LabelEncoder().
print("Diagnosis No. 1: ", y[0])
print("Diagnosis No. 569: ", y[568])le = LabelEncoder()
y = le.fit_transform(y)
y = pd.Series(y, name='diagnosis')print()
print("Diagnosis No. 1: ", y[0])
print("Diagnosis No. 569: ", y[568])
Step 5: Eksplorasi & Analisis Data
5.1. Univariate & Bivariate
5.1.1. Untuk melihat distribusi data, kita akan membuat box plot untuk kolom-kolom dengan data kontinu yaitu bagi semua kolom variabel X.
plt.subplot(1, 5, 1)
sns.boxplot(data=X[["radius_mean"]])plt.subplot(1, 5, 2)
sns.boxplot(data=X[["texture_mean"]])plt.subplot(1, 5, 3)
sns.boxplot(data=X[["perimeter_mean"]])plt.subplot(1, 5, 4)
sns.boxplot(data=X[["area_mean"]])plt.subplot(1, 5, 5)
sns.boxplot(data=X[["concavity_mean"]])plt.tight_layout()
plt.show()
5.1.2. Untuk kolom “diagnosis”, kita akan membuat sebuah pie chart oleh karena tipe datanya yang bersifat diskrit.
diagnosis, diagnosis_count = np.unique(y,return_counts=True)
plt.pie(diagnosis_count , labels = ['B (Benign)', 'M (Malignant)'], autopct="%1.2f%%")
plt.axis("equal")
plt.title("Diagnosis Composition", pad=20)
plt.show()
5.1.3. Kita juga akan membuat sebuah scatter plot untuk melihat hubungan antara kolom “radius_mean” dengan kolom “diagnosis”.
plt.scatter(X["radius_mean"], y)
plt.title("Klasifikasi Mean Radius Terhadap Kanker Payudara", fontsize = 20, pad=20)
plt.xlabel("Radius Mean", fontsize = 15)
plt.ylabel("Diagnosis", fontsize = 15)
plt.show()
5.2. Multivariate
5.2.1. Untuk analisis multivariate, kita akan membuat pairplot bagi kolom yang bersifat kontinu dengan hue dari kolom “diagnosis”.
sns.pairplot(pd.concat([X, y], axis=1), hue="diagnosis")
plt.show()
5.2.2. Selanjutnya, kita juga akan membuat heatmap bagi semua kolom.
df = pd.concat([X, y], axis=1)
sns.heatmap(df.corr(), vmin=-1, vmax=1, cmap="coolwarm", annot=True)
plt.show()
Step 6: Split Dataset
Dataset variabel X dan y akan dibagi menjadi dataset untuk training dan dataset untuk testing. Pembagian akan dilakukan dengan 75% data sebagai dataset training dan 25% data sebagai dataset testing.
sc = StandardScaler()
X_scaled = sc.fit_transform(X)X_train, X_test, y_train, y_test = train_test_split(X_scaled,y,test_size = 0.25, random_state = 50)
Model KNN
Setelah dataset kita sudah siap, kita akan memulai proses training model. Kita akan membuat model KNN terlebih dahulu.
Step 7: Training Model KNN
classifier = KNeighborsClassifier(n_neighbors = 5, metric = "euclidean", p = 2)
classifier.fit(X_train, y_train)
Step 8: Evaluasi Model KNN
8.1. Bandingkan data dari hasil prediksi model dengan data dari dataset testing.
# Gunakan X_test untuk membuat prediksi
y_pred = classifier.predict(X_test)# Compare data test vs. hasil prediksi
evaluate = pd.DataFrame({"y_test":y_test,"y_pred":y_pred})
evaluate.head(10)
8.2. Lakukan prediksi dengan dummy data.
print("Dummy Data Diagnosis 1: ", classifier.predict([[18 , 11, 120, 1000, 0.3]])[0])
print("Dummy Data Diagnosis 2: ", classifier.predict([[10 , 19, 80, 466, 0.06]])[0])
print("Dummy Data Diagnosis 3: ", classifier.predict([[15 , 13, 100, 793, 0.13]])[0])
8.3. Tampilkan Confusion Matrix beserta dengan heatmap-nya.
cm = confusion_matrix(y_test, y_pred)
print("Confusion Matrix\n", cm)sns.heatmap(cm/np.sum(cm), vmin=0, vmax=1, cmap="Blues", annot=True)
plt.show()
8.4. Tampilkan skor akurasi, Senstivity (True Positive Rate), dan Specificity (True Negative Rate) dari model. Di sini, True Positive Rate merupakan persentase keberhasilan dari model dalam memprediksi kasus Malignant (Ganas). Sedangkan, True Negative Rate merupakan persentase keberhasilan dari model dalam memprediksi kasus Benign (Jinak).
TN = cm[0][0]
FN = cm[1][0]
TP = cm[1][1]
FP = cm[0][1]print("True Negative: ",TN)
print("False Negative: ",FN)
print("True Positive: ",TP)
print("False Positive: ",FP)print("Accuracy Score: ", accuracy_score(y_test, y_pred))
print("Sensitivity (True Positive Rate): {:0.2f}%".format(TP / (TP + FN) * 100))
print("Specificity (True Negative Rate): {:0.2f}%".format(TN / (TN + FP) * 100))
Model Logistic Regression
Setelah kita berhasil membuat sebuah model KNN, kita akan mencoba membuat model Logistic Regression untuk membandingkan model yang mana yang lebih unggul dalam kasus ini.
Step 7: Training Model Logistic Regression
classifier = LogisticRegression(random_state = 0)
classifier.fit(X_train, y_train)
Step 8: Evaluasi Model Logistic Regression
8.1. Bandingkan data testing dengan hasil prediksi.
# Gunakan X_test untuk membuat prediksi
y_pred = classifier.predict(X_test)# Compare data test vs. hasil prediksi
evaluate = pd.DataFrame({"y_test":y_test,"y_pred":y_pred})
evaluate.head(10)
8.2. Lakukan prediksi dengan dummy data.
print("Dummy Data Diagnosis 1: ", classifier.predict([[18 , 11, 120, 1000, 0.3]])[0])
print("Dummy Data Diagnosis 2: ", classifier.predict([[10 , 19, 80, 466, 0.06]])[0])
print("Dummy Data Diagnosis 3: ", classifier.predict([[15 , 13, 100, 793, 0.13]])[0])
8.3. Tampilkan Confusion Matrix beserta dengan heatmap-nya.
cm = confusion_matrix(y_test, y_pred)
print("Confusion Matrix\n", cm)sns.heatmap(cm/np.sum(cm), vmin=0, vmax=1, cmap="Blues", annot=True)
plt.show()
8.4. Tampilkan skor akurasi, Senstivity (True Positive Rate), dan Specificity (True Negative Rate) dari model Logistic Regression.
TN = cm[0][0]
FN = cm[1][0]
TP = cm[1][1]
FP = cm[0][1]print("True Negative: ",TN)
print("False Negative: ",FN)
print("True Positive: ",TP)
print("False Positive: ",FP)print("Accuracy Score: ", accuracy_score(y_test, y_pred))
print("Sensitivity (True Positive Rate): {:0.2f}%".format(TP / (TP + FN) * 100))
print("Specificity (True Negative Rate): {:0.2f}%".format(TN / (TN + FP) * 100))
Kesimpulan
Setelah melakukan analisis di atas, kita telah memiliki sebuah model KNN dan sebuah model Logistic Regression untuk memprediksi diagnosis kanker payudara. Tetapi, yang manakah sebaiknya kita gunakan?
Dalam segi akurasi, model Logistic Regression menunjukkan hasil skor akurasi yang lebih tinggi (92.31% dibandingkan dengan 90.91%). Akan tetapi, kita tidak dapat langsung menentukan bahwa model tersebut merupakan model yang terbaik hanya dari skor akurasinya saja. Bila kita melihat Senstivity (True Positive Rate) dan Specificity (True Negative Rate) dari kedua model maka terdapat perbedaan yang cukup penting. Model Logistic Regression menunjukkan Senstivity yang lebih rendah (92.45% dibandingkan dengan 94.34%) tetapi dengan Specificity yang lebih tinggi (92.22% dibandingkan dengan 88.89%).
Pada kasus diagnosis kanker, sangat penting untuk meminimalisir Type 1 Error (False Positive) karena efek samping dari pengobatan kanker seperti kemoterapi yang cukup berat. Tidak seluruh pasien kanker dengan diagnosis jinak (Benign) memerlukan kemoterapi (Kementerian Kesehatan Republik Indonesia, n.d.). Maka itu, model Logistic Regression lebih tepat untuk digunakan dalam kasus ini oleh karena model Logistic Regression memiliki Specificity yang lebih tinggi dibandingkan dengan model KNN.
Python Notebook dari analisis di atas dapat diakses melalui Google Collab di link ini.
Referensi
UCI Machine Learning. (2016). Breast Cancer Wisconsin (Diagnostic) Data Set. https://www.kaggle.com/datasets/uciml/breast-cancer-wisconsin-data
Kementerian Kesehatan Republik Indonesia. (n.d.). Panduan Penatalaksanaan Kanker Payudara. http://kanker.kemkes.go.id/guidelines/PPKPayudara.pdf
Kresna (2019). Kelebihan Analisis regresi logistik (Skripsi Dan Tesis). https://konsultasiskripsi.com/2019/09/30/kelebihan-analisis-regresi-logistik-skripsi-dan-tesis/
Handoko, B. L. (2021). Penggunaan regresi linear Dan regresi Logistik Dalam Penelitian Kuantitatif. https://accounting.binus.ac.id/2021/11/16/penggunaan-regresi-linear-dan-regresi-logistik-dalam-penelitian-kuantitatif/