Anda di halaman 1dari 29

LAPORAN PRAKTIKUM

[RKK302] PEMBELAJARAN MESIN

Topik: K-Means Clustering


Kelas: RK-A1

OLEH:
RIFQY NURKHOLIQ (162112233086)

PROGRAM STUDI TEKNIK ROBOTIKA DAN KECERDASAN BUATAN


FAKULTAS TEKNOLOGI MAJU DAN MULTIDISIPLIN
UNIVERSITAS AIRLANGGA
2023
I. Tujuan

Mahasiswa dapat mempraktikkan metode pembelajaran mesin klasterisasi k-Means


menggunakan Python dengan benar.

II. Dasar Teori

Metode unsupervised memiliki beberapa teknik, salah satunya adalah klasterisasi.


Klasterisasi bertujuan untuk mengelompokkan data ke dalam beberapa klaster atau
kelompok, sehingga data dalam satu klaster memiliki tingkat kemiripan yang maksimum,
sementara data antar klaster memiliki kemiripan yang minimum [1]. Klasterisasi adalah
proses partisi suatu set objek data ke dalam himpunan bagian yang disebut klaster. Objek
yang berada dalam satu klaster memiliki kemiripan karakteristik satu sama lain dan
berbeda dari klaster lainnya. Partisi ini tidak dilakukan secara manual, melainkan dengan
menggunakan suatu algoritma klasterisasi. Oleh karena itu, klasterisasi sangat berguna dan
dapat membantu dalam menemukan kelompok yang tidak dikenal dalam data.

Klasterisasi juga dikenal sebagai data segmentasi karena klasterisasi mempartisi


banyak data set ke dalam banyak kelompok berdasarkan kesamaannya. Selain itu
klasterisasi juga bisa sebagai outlier detection. Klasterisasi memiliki beberapa manfaat,
antara lain:

1. Melakukan prediksi dan analisa masalah bisnis tertentu. Misalnya Segmentasi pasar,
marketing dan pemetaan zonasi wilayah.
2. Identifikasi objek dalam bidang berbagai bidang seperti visi komputer dan pemrosesan
citra.
K-means merupakan salah satu algoritma dalam data mining yang bisa digunakan untuk
melakukan pengelompokkan/clustering suatu data.

Metode K-means merupakan metode clustering yang paling sederhana dan umum
[1]. Hal ini dikarenakan K-means salah satu algoritma yang mempunyai kemampuan untuk
melakukan pengelompokan/clustering suatu data [2]. Kemampuan dari k-means juga hasil
yang cepat dan efisien [1]. Algoritma k-Means dalam penerapannya memerlukan tiga
parameter yang seluruhnya ditentukan pengguna yaitu jumlah klaster k, inisialisasi klaster,
dan jarak sistem. Algoritma K-Means direpresentasikan sebagai berikut:

1
• Tentukan berapa banyak klaster k dari dataset yang akan dibagi.
• Tetapkan secara acak data k menjadi pusat awal lokasi klaster.
• Untuk masing-masing data, temukan pusat klaster terdekat. Dengan demikian berarti
masing-masing pusat klaster memiliki sebuah subset dari dataset, sehingga mewakili
bagian dari dataset. Oleh karena itu, telah terbentuk klaster k: C1, C2, C3, …, Ck. S1
Teknik Robotika dan Kecerdasan Buatan, Fakultas Teknologi Maju dan Multidisiplin
Universitas Airlangga (RKK302) Praktikum Pembelajaran Mesin Semester Gasal T.A.
2023/2024 2
• Untuk masing-masing klaster k, temukan pusat luasan klaster, dan perbarui lokasi dari
masing-masing pusat klaster ke nilai baru dari pusat luasan.
• Ulangi langkah ke-3 dan ke-5 hingga data-data pada tiap klaster menjadi terpusat atau
selesai.

III. Metode
A. prosedur percobaan
• Pertama, coba lakukan pembuatan K-means Clustering seperti yang ditunjukkan dalam
contoh pertama. Setelah itu, buatlah flowchart berdasarkan pemahaman dan analisis
hasilnya.!
• Modifikasi contoh yang sudah dicoba dengan persamalahan dibawah ini:
Data yang digunakan berasal dari sumber sekunder dan berkaitan dengan kualitas
udara di kota Italia. Data ini diperoleh dari perangkat multisensor gas yang digunakan
di lapangan. Setiap jam, respons rata-rata perangkat tersebut dicatat bersama dengan
konsentrasi gas referensi dari penganalisa bersertifikat. Dalam analisis ini, kita akan
fokus pada variabel NMHC dan RH, sementara menghilangkan variabel yang tidak
diperlukan. Selanjutnya, kita akan melakukan klasterisasi data ke dalam lima klaster
dan membuat plot hasilnya. Data ini dapat diunduh dari
http://archive.ics.uci.edu/ml/datasets/Air+Quality .

2
• Implementasikan juga kasus pada pertanyaan nomor (2) dengan menggunakan library
ScikitLearn, serupa dengan contoh 4–5. Selanjutnya, bandingkan performa hasil dari
metode tersebut dalam hal Mean Absolute Error (MAE), akurasi, presisi, skor recall,
dan skor F1. Lakukan analisis terhadap hasil yang diperoleh.

IV. Data Hasil Percobaan

a. Hasil percobaan contoh pertama


Hasilnya adalah :

The mean absolute error between the predicted and true centroids i
s:0.05720900868245887
Accuracy score: 0.0490
Precision score: 0.0488
Recall score: 0.0490
F1 score: 0.0489

3
The mean absolute error between the predicted and true centroids i
s:0.05720900868245924
Accuracy score: 0.9180
Precision score: 0.9179
Recall score: 0.9180
F1 score: 0.9179

b. Flowchart

4
c. Hasil nomer dua dari modifikasi contoh satu.
Hasilnya adalah :

Inertia WCSS Score : 1152.962129718375


Silhouette Score : 0.5918200748742275

d. Percobaan ketiga
Evaluasi elbow method:

5
V. Analisis dan Pembahasan
a. Analisis perintah pertama
Pada percobaan pertama ini, pemahaman terhadap kode mengenai k-means
clustering dilakukan. Proses pembentukan cluster data dimulai dengan menentukan
jumlah cluster yang diinginkan. Setelah itu, titik pusat cluster ditentukan berdasarkan
data yang ada. Data yang memiliki jarak terdekat dengan titik pusat cluster akan
dikelompokkan ke dalam cluster yang sesuai. Proses ini dilakukan secara iteratif hingga
seluruh data berhasil dikelompokkan ke dalam cluster yang sesuai.

b. Analisis perintah kedua


Praktikan telah mengembangkan dan memodifikasi model algoritma K-Means
Clustering yang disediakan dalam modul untuk melakukan klasterisasi pada dataset
Air_Quality. Proses klasterisasi melibatkan normalisasi fitur terlebih dahulu
menggunakan modul 'Standard Scaler' dari library Scikit-learn. Pendekatan normalisasi
diterapkan karena K-Means, yang menggunakan ketidakseragaman skala fitur, dapat
menghasilkan kontribusi yang tidak seimbang dalam perhitungan jarak. Hal ini
mungkin mengakibatkan hasil yang kurang akurat. Melalui normalisasi, fitur-fitur
diubah sehingga memiliki rata-rata nol dan standar deviasi satu, sehingga setiap fitur
memiliki skala yang serupa.

Kualitas hasil klasterisasi model algoritma dinilai menggunakan metode Inertia


atau WCSS (Within-Cluster Sum of Squares) dan Silhouette Score. Kedua metode ini
dipilih karena pada kasus ini tidak tersedia 'true_labels' untuk data, yang merujuk pada
label sebenarnya dari setiap titik data. Oleh karena itu, dalam evaluasi performa
clustering model ini, metode seperti mean absolute error (MAE), akurasi, presisi, skor
recall, dan skor F1 tidak digunakan.

c. Analisis perintah ketiga


Praktikan juga melakukan plot grafik elbow method untuk mengidentifikasi jumlah
klaster yang optimal perbedaanya pada percobaan ini menggunakan library scikir-
learn dibandingkan pada yang kedua. Elbow method adalah teknik yang digunakan
untuk menentukan jumlah kluster yang optimal dalam algoritma K-Means clustering.
Tujuannya adalah mencari nilai optimal untuk jumlah kluster yang memberikan

6
keseimbangan terbaik antara akurasi model dan efisiensi komputasional. Berdasarkan
hasil grafik elbow method, kurva mengalami penurunan drastis hingga mencapai
jumlah klaster di titik 3. Artinya, pada titik ini, jumlah klaster dianggap sebagai
minimum yang efektif untuk digunakan, karena penurunan kurva setelahnya tidak
terlalu signifikan.

Hasil performa yang didapatkan menggunakan model algoritma manual yakni:

Inertia WCSS Score : 1152.962129718375


Silhouette Score : 0.5918200748742275

Jika hasil secara manual dibandingkan, perbandingan yang tidak terlalu signifikan
menunjukkan bahwa kedua algoritma memiliki kinerja model yang serupa dan
menghasilkan kluster yang sama. Hal ini dapat diartikan sebagai tanda bahwa kedua
algoritma beroperasi dengan baik dan memberikan klasterisasi serupa untuk data yang
sama. Kesamaan dalam hasil performa model algoritma mungkin terjadi karena
kompleksitas dataset yang relatif rendah, sehingga kinerja keduanya menjadi serupa.

VI. Kesimpulan
K-means clustering adalah metode efisien untuk mengelompokkan data
berdasarkan kesamaannya. Tujuannya adalah membentuk kluster yang padat dan terpisah
dengan mengurangi inersia atau WCSS. Prosesnya melibatkan inisialisasi kluster,
penugasan sampel ke kluster berdasarkan jarak ke centroid, dan pembaruan centroid.
Algoritma ini berulang hingga mencapai konvergensi, di mana perubahan kecil pada
centroid dianggap tidak signifikan. Evaluasi kinerjanya menggunakan metrik seperti skor
silhouette dan skor inertia (WCSS) memberikan gambaran tentang seberapa baik kluster
dipisahkan dan seberapa padat kluster tersebut.

Dalam praktikum ini, K-means clustering digunakan untuk mengelompokkan


sampel dari dataset. Dua pendekatan diterapkan: model manual dan model dari library
scikit-learn. Evaluasi hasil dilakukan dengan membandingkan metrik seperti Mean
Absolute Error (MAE), akurasi, presisi, skor recall, dan skor F1 dari kedua pendekatan.
Perbandingan kinerja menunjukkan perbedaan yang sangat kecil, yang dapat diatributkan

7
pada kesamaan kinerja keduanya, sejalan dengan karakteristik dataset yang tidak terlalu
kompleks.

VII. Referensi

[1] D. Teori, “Modul 6 K-Means Clustering,” pp. 1–10, 2024.

[2] T. Firmansyah, P. Poningsih, and ..., “Analisis Clustering Algoritma K-Means Sebagai
Rekomendasi Penambahan Koleksi Buku Di Perpustakaan Madrasah Tsanawiyah Negeri
2 Simalungun,” ZAHRA Bul. Big Data …, vol. 1, no. 1, pp. 44–48, 2022, [Online].
Available:
https://ejurnal.pdsi.or.id/index.php/zahra/article/view/13%0Ahttps://ejurnal.pdsi.or.id/inde
x.php/zahra/article/viewFile/13/11

[3] Ben Auffarth, 2021, “Machine Learning for Time-Series with Python”, PACKT
Publishing.

[4] Gopal Sakarkar, Gaurav Patil, dan Prateek Dutta, 2021, “Machine Learning Algorithms
Using Python Programming”, Nova Science Publishers, Inc.

8
LAMPIRAN

#contoh_1
# imports
import numpy as np
from typing import Tuple, Dict
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
from sklearn.metrics import mean_absolute_error, \
accuracy_score, \
precision_score, \
recall_score, \
f1_score
# Membuat Algoritma kMeans
class KMeans(object):
"""
Class to encapsulate the K-Means algorithm
"""
def __init__(self, K: int=3, n_init: int=20, max_iters:
int=100) -> None:
"""
Initialiser function for a class instance
Inputs:
K -> integer number of clusters to assign
n_init -> integer number of times the algorithm will
be applied when training
max_iters -> maximum number of iterations the
algorithm is allowed to run before stopping
"""

9
if K <= 0:
raise ValueError(f'K must be a positive integer,
got: {K}')
if n_init <= 0:
raise ValueError(f'n_init must be a positive
integer, got: {n_init}')
if max_iters <= 0:
raise ValueError(f'Input argument max_iters must be
a positive integer, got: {max_iters}')
self.K = K
self.n_init = n_init
self.centroids = np.array([])
self.total_wcss = np.inf
self.wcss_array = np.array([])
self.max_iters = max_iters
def __del__(self) -> None:
"""
Destructor function for class instance
"""
del self.K
del self.n_init
del self.centroids
del self.total_wcss
del self.wcss_array
del self.max_iters
def __assign_samples(self, X : np.array, centroids :
np.array) -> np.array:
"""
Private function to assign samples to clusters

10
Inputs:
X -> numpy array of input features with shape:
[number_samples,
number_features]
centroids -> numpy array of centroids with shape: [K,
number_features]
Output:
numpy array indicating cluster assignment per sample
with shape:
[number_samples,]
"""
# compute difference between input features & centroids
through broadcasting
differences = X[:,np.newaxis] - centroids[np.newaxis]
# compute the squared euclidean distance for every
(number_samples, K)pairs
euclid_dist = np.einsum('ijk,ijk->ij', differences,
differences)
# find minimal distance for each sample & return
return np.argmin(euclid_dist, axis=1)
def __partition_data(self, X : np.array, cluster_assignment
: np.array) -> list:
"""
Private function to partition input features according
to cluster
assignment
Inputs:
X -> numpy array of input features with shape:
[number_samples,
number_features]

11
cluster_assignment -> numpy array of cluster assignments
with shape:
[number_samples,]
Output:
list of numpy arrays of centroid for cluster, each array
with shape:
[cluster_number_samples, number_features]
"""
# join features and cluster assignment
X_assigned = np.concatenate((X,
cluster_assignment.reshape(-1,1)),axis=1)
# sort on the cluster assignment
X_assigned = X_assigned[X_assigned[:, -1].argsort()]
# partition the data based on the cluster assignment &
return
return np.split(X_assigned[:,:-1],
np.unique(X_assigned[:, -1], return_index=True)[1][1:])
def __compute_wcss(self, X : np.array, cluster_assignment :
np.array,
centroids : np.array) -> Tuple[float, np.array]:
"""
Private function to compute WCSS over all clusters
Inputs:
X -> numpy array of input features with shape:
[number_samples,number_features]cluster_assignment -> numpy
array of cluster assignments with
shape:[number_samples,]centroids -> numpy array of centroids
with shape: [K, number_features]
Output:
tuple containing the total WCSS, along with numpy array
of WCSS values

12
for clusters with shape: [K]
"""
# break up the input features according to their cluster
assignments
X_clusters = self.__partition_data(X,
cluster_assignment)
# compute the WCSS for each cluster
wcss_array = np.array([np.einsum('ij,ij', X_clusters[i]
- centroids[i,:],
X_clusters[i] - centroids[i,:]) for i in
range(self.K)])
# return the WCSS per cluster, along with the sum over
all clusters
return (np.sum(wcss_array), wcss_array)
def __update_centroids(self, X : np.array,
cluster_assignment : np.array) -> np.array:
"""
Private function to update cluster centroids
Inputs:
X -> numpy array of input features with shape:
[number_samples,
number_features]
cluster_assignment -> numpy array of cluster assignments
with shape:
[number_samples,]
Output:
numpy array of centroids with shape: [K,
number_features]
"""

13
# break up the input features according to their cluster
assignments
X_clusters = self.__partition_data(X,
cluster_assignment)
# compute new centroids & return
return np.array([np.mean(x, axis=0) for x in
X_clusters])
def fit(self, X : np.array) -> None:
"""
Training function for the class. Aims to find the
optimal centroid values
that minimise the WCSS
Inputs:
X -> numpy array of input features of assumed shape
[number_samples,
number_features]
"""
# initialise wcss score
self.total_wcss = np.inf
# loop over all iterations requested
for _ in range(self.n_init):
# initialise centroids
centroids = X[np.random.choice(X.shape[0], self.K,
replace=False)]
old_centroids = np.copy(centroids)
# loop through the K-Means learning algorithm
centroid_diff = np.ones((self.K))
iteration = 0

14
while (not
np.array_equal(centroid_diff,np.zeros(self.K))) and iteration <
self.max_iters:
# assign samples to clusters
cluster_assignment = self.__assign_samples(X,
centroids)
# update centroids
centroids = self.__update_centroids(X,
cluster_assignment)
# compute difference between centroids
centroid_diff = np.abs(old_centroids -
centroids)
# increment counter & reset old_centroids
iteration += 1
old_centroids = np.copy(centroids)
# compute WCSS for the resulting clusters
total_wcss, wcss_array = self.__compute_wcss(X,
cluster_assignment,
centroids)
# check if we have a new optimal centroid
configuration?
if total_wcss < self.total_wcss:
# if so, update storage objects
self.total_wcss = total_wcss
self.wcss_array = wcss_array
self.centroids = centroids
def predict(self, X : np.array) -> None:
"""
Predict function for the class. Assigns cluster labels
to each sample

15
based on proximity to centroids
Input:
X -> numpy array of input features of assumed shape
[number_samples,
number_features]
Output:
numpy array indicating cluster assignment per sample
with shape:
[number_samples,]
"""
if self.centroids.size == 0:
raise Exception("It doesn't look like you have
trained this model yet!")
return self.__assign_samples(X, self.centroids)
def return_wcss(self) -> Tuple[float, np.array]:
"""
Public function to return WCSS scores (after training)
Output:
tuple containing the total WCSS, along with numpy array
of WCSS values
for clusters with shape: [K]
"""
if self.centroids.size == 0:
raise Exception("It doesn't look like you have
trained this model yet!")
return (self.total_wcss, self.wcss_array)
def return_centroids(self) -> np.array:
"""
Public function to return centroids (after training)

16
Output:
numpy array containing the centroids with shape: [K,
number_features]
"""
if self.centroids.size == 0:
raise Exception("It doesn't look like you have
trained this model yet!")
return self.centroids
def get_params(self, deep : bool = False) -> Dict:
"""
Public function to return model parameters
Inputs:
deep -> boolean input parameter
Outputs:
Dict -> dictionary of stored class input parameters
"""
return {'K':self.K,
'n_init':self.n_init,
'max_iters':self.max_iters}
# Memproduksi dataset
X, y, centers = make_blobs(n_samples=1000, centers=3,
n_features=2,
return_centers=True, random_state=0)

# visualise data
fig, ax = plt.subplots(figsize=(10,8))
sc = ax.scatter(X[:,0],X[:,1],c=y)
sc_centers = ax.scatter(centers[:,0],centers[:,1],c='r')

17
plt.xlabel('x1')
plt.ylabel('x2')
plt.title('Distribution of Data with True Cluster Assignments')
ax.legend(*sc.legend_elements(), title='clusters')
plt.show()

# Buat model KMeans


clt = KMeans(max_iters=300)

# Cocokkan model dengan data


clt.fit(X)

# Dapatkan prediksi
y_pred = clt.predict(X)

# Dapatkan prediksi sentroid


centers_pred = clt.return_centroids()

# Visualisasikan prediksi
fig, ax = plt.subplots(figsize=(10,8))
sc = ax.scatter(X[:,0],X[:,1],c=y_pred)
sc_centers =
ax.scatter(centers_pred[:,0],centers_pred[:,1],c='r')
plt.xlabel('x1')
plt.ylabel('x2')
plt.title('Distribution of Data with Custom Predicted Cluster
Assignments')

18
ax.legend(*sc.legend_elements(), title='clusters')
plt.show()

# Mendapatkan nilai cluster errors


clt.return_wcss()
# Seberapa akurat estimasi sentroid yang dihasilkan?
print(f'The mean absolute error between the predicted and true
centroids
is:{mean_absolute_error(centers,centers_pred[[2,0,1]])}')
# Kalibrasikan pelabelan (if needed)
idx_0 = y_pred == 0
idx_1 = y_pred == 1
idx_2 = y_pred == 2
y_pred[idx_0] = 2
y_pred[idx_1] = 0
y_pred[idx_2] = 1
# Seberapa akurat penempatan klasterisasi yang dihasilkan?
acc = accuracy_score(y,y_pred)
pre = precision_score(y,y_pred,average='weighted')
rec = recall_score(y,y_pred,average='weighted')
f1 = f1_score(y,y_pred,average='weighted')
print(f'Accuracy score: {acc:.4f}')
print(f'Precision score: {pre:.4f}')
print(f'Recall score: {rec:.4f}')
print(f'F1 score: {f1:.4f}')

19
# import scikit-learn K-Means
from sklearn.cluster import KMeans
# Buat model KMeans
clt = KMeans(n_clusters=3, max_iter=300, random_state=0)
# Cocokkan model dengan data
clt.fit(X)
# Dapatkan prediksi
y_pred = clt.predict(X)
# Dapatkan prediksi sentroid
centers_pred = clt.cluster_centers_
# Visualisasikan prediksi
fig, ax = plt.subplots(figsize=(10,8))
sc = ax.scatter(X[:,0],X[:,1],c=y_pred)
sc_centers =
ax.scatter(centers_pred[:,0],centers_pred[:,1],c='r')
plt.xlabel('x1')
plt.ylabel('x2')
plt.title('Distribution of Data with Scikit-learn Predicted
Cluster Assignments')
ax.legend(*sc.legend_elements(), title='clusters')
plt.show()

# Seberapa akurat estimasi sentroid yang dihasilkan?

20
print(f'The mean absolute error between the predicted and true
centroids
is:{mean_absolute_error(centers,centers_pred[[1,0,2]])}')
# Kalibrasikan pelabelan (if needed)
idx_0 = y_pred == 0
idx_1 = y_pred == 1
idx_2 = y_pred == 2
y_pred[idx_0] = 1
y_pred[idx_1] = 0
y_pred[idx_2] = 2
# Seberapa akurat penempatan klasterisasi yang dihasilkan?
acc = accuracy_score(y,y_pred)
pre = precision_score(y,y_pred,average='weighted')
rec = recall_score(y,y_pred,average='weighted')
f1 = f1_score(y,y_pred,average='weighted')
print(f'Accuracy score: {acc:.4f}')
print(f'Precision score: {pre:.4f}')
print(f'Recall score: {rec:.4f}')
print(f'F1 score: {f1:.4f}')

#NOMOR_2
# imports
# imports
import numpy as np
import pandas as pd

21
from typing import Tuple, Dict
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_absolute_error, \
accuracy_score, \
precision_score, \
recall_score, \
f1_score
from sklearn.cluster import KMeans
from sklearn import metrics
from scipy.spatial.distance import cdist
from sklearn.metrics import silhouette_score
class KMeans(object):
"""
Class to encapsulate the K-Means algorithm
"""

def __init__(self, n_clusters: int = 3, n_init: int = 10,


max_iters: int = 100, random_state = 42):
"""
Initializer function for a class instance

Inputs:
n_clusters -> integer number of clusters to assign
n_init -> integer number of times the
algorithm will be applied when training

22
max_iters -> maximum number of iterations the
algorithm is allowed to run before stopping
"""
if n_clusters <= 0:
raise ValueError(f'n_clusters must be a positive
integer, got: {n_clusters}')
if n_init <= 0:
raise ValueError(f'n_init must be a positive
integer, got: {n_init}')
if max_iters <= 0:
raise ValueError(f'Input argument max_iters must be
a positive integer, got: {max_iters}')
self.n_clusters = n_clusters
self.n_init = n_init
self.centroids = np.array([])
self.total_wcss = np.inf
self.wcss_array = np.array([])
self.max_iters = max_iters

def __assign_samples(self, X: np.array, centroids: np.array)


-> np.array:
"""
Private function to assign samples to clusters

Inputs:
X -> numpy array of input features with shape:
[number_samples, number_features]
centroids -> numpy array of centroids with shape:
[n_clusters, number_features]
Output:

23
numpy array indicating cluster assignment per sample
with shape: [number_samples,]
"""
differences = X[:, np.newaxis] - centroids[np.newaxis]
euclid_dist = np.einsum('ijk,ijk->ij', differences,
differences)
return np.argmin(euclid_dist, axis=1)

def __update_centroids(self, X: np.array,


cluster_assignment: np.array) -> np.array:
X_clusters = self.__partition_data(X,
cluster_assignment)
return np.array([np.mean(x, axis=0) for x in
X_clusters])

def __partition_data(self, X: np.array, cluster_assignment:


np.array) -> list:
X_assigned = np.concatenate((X,
cluster_assignment.reshape(-1, 1)), axis=1)
X_assigned = X_assigned[X_assigned[:, -1].argsort()]
return np.split(X_assigned[:, :-1],
np.unique(X_assigned[:, -1], return_index=True)[1][1:])

def __compute_wcss(self, X: np.array, cluster_assignment:


np.array, centroids: np.array) -> Tuple[float, np.array]:
X_clusters = self.__partition_data(X,
cluster_assignment)
wcss_array = np.array([np.einsum('ij,ij', X_clusters[i]
- centroids[i, :],
X_clusters[i] -
centroids[i, :]) for i in range(self.n_clusters)])

24
return (np.sum(wcss_array), wcss_array)

def fit(self, X: np.array) -> None:


self.total_wcss = np.inf

for _ in range(self.n_init):
# Memastikan sentroid awal mencakup seluruh klaster
centroids = []
for i in range(self.n_clusters):
cluster_points = X[np.random.choice(X.shape[0],
1)]
while cluster_points.tolist() in centroids:
cluster_points =
X[np.random.choice(X.shape[0], 1)]
centroids.append(cluster_points.tolist()[0])

centroids = np.array(centroids)

old_centroids = np.copy(centroids)
centroid_diff = np.ones((self.n_clusters))
iteration = 0
while (not np.array_equal(centroid_diff,
np.zeros(self.n_clusters))) and iteration < self.max_iters:
cluster_assignment = self.__assign_samples(X,
centroids)
centroids = self.__update_centroids(X,
cluster_assignment)
centroid_diff = np.abs(old_centroids -
centroids)

25
iteration += 1
old_centroids = np.copy(centroids)

total_wcss, wcss_array = self.__compute_wcss(X,


cluster_assignment, centroids)
if total_wcss < self.total_wcss:
self.total_wcss = total_wcss
self.wcss_array = wcss_array
self.centroids = centroids

def predict(self, X: np.array) -> np.array:


if self.centroids.size == 0:
raise Exception("It doesn't look like you have
trained this model yet!")
return self.__assign_samples(X, self.centroids)

def return_wcss(self) -> Tuple[float, np.array]:


if self.centroids.size == 0:
raise Exception("It doesn't look like you have
trained this model yet!")
return (self.total_wcss, self.wcss_array)

def return_centroids(self) -> np.array:


if self.centroids.size == 0:
raise Exception("It doesn't look like you have
trained this model yet!")
return self.centroids
df = pd.read_excel("AirQualityUCI.xlsx")
dfB = df[["NMHC(GT)", "RH"]]

26
dfB
Scaler = StandardScaler()
dfB_scaled = Scaler.fit_transform(dfB)
clt = KMeans(n_clusters= 5)
clt.fit(dfB_scaled)
y_pred = clt.predict(dfB_scaled)
canters_pres = clt.return_centroids()
# visualise data
fig, ax = plt.subplots(figsize=(10,8))
sc = ax.scatter(dfB_scaled[:,0],dfB_scaled[:,1],c=y_pred)
sc_centers =
ax.scatter(canters_pres[:,0],canters_pres[:,1],c='r')
plt.xlabel('NMHC(GT)')
plt.ylabel('RH')
plt.title('Distribution of Data with True Cluster Assignments')
ax.legend(*sc.legend_elements(), title='clusters')
plt.show()
# compute WCSS for the resulting clusters
total_wcss, wcss_array = clt.return_wcss()
print(f'Inertia WCSS Score\t: {total_wcss}')
silhouette_avg = silhouette_score(dfB_scaled, y_pred)
print(f'Silhouette Score\t: {silhouette_avg}')

#nomer_3
#evaluasi dengan elbow methode
from sklearn.cluster import KMeans

27
wcss_values = []
k_values = range(1,11)

for k in k_values :
kmeans = KMeans(n_clusters=k, random_state=42)
kmeans.fit(dfB_scaled)
wcss_values.append(kmeans.inertia_)

#plot elbow method


plt.plot(range(1, 11), cs)
plt.title('Number of Clusters (k)')
plt.xlabel('Within.Sluster sum of Squares (WCSS)')
plt.ylabel('Elbow Method for Optimal k')
plt.show()

28

Anda mungkin juga menyukai