Perbandingan antara K-Nearest Neighbor & Logistic Regression dalam Pengklasifikasian Data

Justin Jap
9 min readJun 10, 2022

--

Ditulis oleh Justin Jap & David Christian.

Sel kanker payudara di bawah mikroskop (Sumber: Johns Hopkins University).

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

Halaman dataset Breast Cancer Wisconsin (Diagnostic) pada Kaggle.

1.2. Buatlah repository baru dan upload file CSV tersebut ke dalam repository yang dibuat.

Repository GitHub yang memuat file CSV (data.csv).

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.

file CSV (data.csv) raw dari GitHub.

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()
Hasil dataset.info() sebelum membersihkan kolom-kolom yang tidak diperlukan.

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 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 dari pengecekan nilai null pada dataset.

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])
Hasil dari label encoder untuk diagnosis pada data baris pertama dan data baris 569.

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()
Box plot dari data dengan kolom yang bersifat kontinu.

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()
Pie chart yang menunjukkan komposisi dari kolom “diagnosis”.

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()
Scatter plot dari kolom “radius_mean” terhadap kolom “diagnosis”.

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()
Pair plot dari data dengan kolom yang bersifat kontinu.

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()
Heatmap dari data semua kolom.

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)
Perbandingan hasil prediksi dengan data testing untuk model KNN.

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])
Prediksi dengan 3 dummy data untuk model KNN.

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()
Confusion matrix dan heatmap-nya untuk model KNN.

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))
TN, FN, TP, FP, skor akurasi, senstivity, dan specificity untuk model KNN.

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)
Perbandingan hasil prediksi dengan data testing untuk model Logistic Regression.

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])
Prediksi dengan 3 dummy data untuk model Logistic Regression.

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()
Confusion matrix dan heatmap-nya untuk model Logistic Regression.

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))
TN, FN, TP, FP, skor akurasi, senstivity, dan specificity untuk model Logistic Regression.

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/

--

--

Justin Jap
0 Followers

Informatics Student at Ciputra University