Analisis cluster merupakan salah satu metode statistika multivariat yang digunakan untuk mengelompokkan objek berdasarkan tingkat kemiripan karakteristiknya. Objek yang berada dalam satu cluster diharapkan memiliki karakteristik yang relatif mirip, sedangkan objek yang berada pada cluster berbeda memiliki karakteristik yang relatif berbeda. Pada analisis ini digunakan metode K-Means Clustering.
K-Means merupakan metode clustering non-hierarkis yang membagi sejumlah objek ke dalam K kelompok berdasarkan kedekatan objek terhadap pusat cluster (centroid). Tujuan utama K-Means adalah meminimumkan jumlah kuadrat jarak antara setiap objek dengan centroid cluster tempat objek tersebut berada.
Secara umum, fungsi objektif K-Means dapat dituliskan sebagai:
\[ J = \sum_{k=1}^{K} \sum_{i=1}^{n} \left\|x_i - \mu_k\right\|^2 \]
dengan:
Algoritma K-Means secara umum dilakukan melalui beberapa tahapan, yaitu:
Karena K-Means menggunakan jarak dalam menentukan kedekatan antarobjek, perbedaan skala antarvariabel dapat memengaruhi hasil clustering.
Oleh karena itu, data numerik akan distandardisasi menggunakan:
\[ Z = \frac{X-\bar{X}}{s} \]
sehingga setiap variabel memiliki rata-rata mendekati 0 dan standar deviasi mendekati 1.
Salah satu pendekatan yang dapat digunakan untuk menentukan jumlah cluster adalah Elbow Method.
Elbow Method melihat perubahan nilai Within-Cluster Sum of Squares (WSS) untuk beberapa nilai K. Nilai K dipilih pada titik ketika penurunan WSS mulai melandai.
Selain Elbow Method, evaluasi juga dapat dilakukan menggunakan Silhouette Coefficient. Nilai silhouette yang semakin besar menunjukkan bahwa objek semakin sesuai dengan cluster tempatnya berada.
Dataset yang digunakan adalah dataset iris yang merupakan dataset bawaan R.
Dataset iris terdiri dari 150 observasi dan 5 variabel, yaitu:
Empat variabel pertama merupakan variabel numerik yang digunakan dalam proses clustering. Variabel Species tidak digunakan sebagai input model karena merupakan variabel kategorik.
Dataset iris berisi pengukuran karakteristik bunga iris yang terdiri atas tiga spesies, yaitu setosa, versicolor, dan virginica.
data(iris)
kable(
head(iris),
caption = "Lima Data Pertama Dataset Iris",
digits = 2,
align = "c"
)
| Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
|---|---|---|---|---|
| 5.1 | 3.5 | 1.4 | 0.2 | setosa |
| 4.9 | 3.0 | 1.4 | 0.2 | setosa |
| 4.7 | 3.2 | 1.3 | 0.2 | setosa |
| 4.6 | 3.1 | 1.5 | 0.2 | setosa |
| 5.0 | 3.6 | 1.4 | 0.2 | setosa |
| 5.4 | 3.9 | 1.7 | 0.4 | setosa |
tipe_data<-data.frame(
variabel = names(iris),
Tipe_Data = sapply(iris,class)
)
kable(
tipe_data,
caption = "Tipe Data Variabel Dataset Iris",
align = "c"
)
| variabel | Tipe_Data | |
|---|---|---|
| Sepal.Length | Sepal.Length | numeric |
| Sepal.Width | Sepal.Width | numeric |
| Petal.Length | Petal.Length | numeric |
| Petal.Width | Petal.Width | numeric |
| Species | Species | factor |
dim(iris)
## [1] 150 5
Berdasarkan output tersebut, dataset iris terdiri dari 150 observasi dan 5 variabel.
statistik_deskriptif <- data.frame(
Variabel = c(
"Sepal Length",
"Sepal Width",
"Petal Length",
"Petal Width"
),
Minimum = c(
min(iris$Sepal.Length),
min(iris$Sepal.Width),
min(iris$Petal.Length),
min(iris$Petal.Width)
),
Q1 = c(
quantile(iris$Sepal.Length, 0.25),
quantile(iris$Sepal.Width, 0.25),
quantile(iris$Petal.Length, 0.25),
quantile(iris$Petal.Width, 0.25)
),
Median = c(
median(iris$Sepal.Length),
median(iris$Sepal.Width),
median(iris$Petal.Length),
median(iris$Petal.Width)
),
Mean = c(
mean(iris$Sepal.Length),
mean(iris$Sepal.Width),
mean(iris$Petal.Length),
mean(iris$Petal.Width)
),
Q3 = c(
quantile(iris$Sepal.Length, 0.75),
quantile(iris$Sepal.Width, 0.75),
quantile(iris$Petal.Length, 0.75),
quantile(iris$Petal.Width, 0.75)
),
Maksimum = c(
max(iris$Sepal.Length),
max(iris$Sepal.Width),
max(iris$Petal.Length),
max(iris$Petal.Width)
)
)
kable(
statistik_deskriptif,
caption = "Statistik Deskriptif Variabel Numerik Dataset Iris",
digits = 3,
align = "c"
)
| Variabel | Minimum | Q1 | Median | Mean | Q3 | Maksimum |
|---|---|---|---|---|---|---|
| Sepal Length | 4.3 | 5.1 | 5.80 | 5.843 | 6.4 | 7.9 |
| Sepal Width | 2.0 | 2.8 | 3.00 | 3.057 | 3.3 | 4.4 |
| Petal Length | 1.0 | 1.6 | 4.35 | 3.758 | 5.1 | 6.9 |
| Petal Width | 0.1 | 0.3 | 1.30 | 1.199 | 1.8 | 2.5 |
species_table <- as.data.frame(table(iris$Species))
colnames(species_table) <- c("Species", "Jumlah")
kable(
species_table,
caption = "Jumlah Observasi Berdasarkan Species"
)
| Species | Jumlah |
|---|---|
| setosa | 50 |
| versicolor | 50 |
| virginica | 50 |
Distribusi masing-masing variabel numerik dapat dilihat melalui boxplot.
iris_long <- data.frame(
Value = c(
iris$Sepal.Length,
iris$Sepal.Width,
iris$Petal.Length,
iris$Petal.Width
),
Variable = rep(
c(
"Sepal Length",
"Sepal Width",
"Petal Length",
"Petal Width"
),
each = nrow(iris)
)
)
ggplot(iris_long, aes(x = Variable, y = Value)) +
geom_boxplot() +
labs(
title = "Boxplot Variabel Numerik Dataset Iris",
x = "Variabel",
y = "Nilai"
) +
theme_minimal()
Hubungan antarvariabel numerik dapat divisualisasikan menggunakan scatter plot.
ggplot(iris, aes(x = Petal.Length, y = Petal.Width, color = Species)) +
geom_point(size = 2.5) +
labs(
title = "Hubungan Petal Length dan Petal Width",
x = "Petal Length",
y = "Petal Width",
color = "Species"
) +
theme_minimal()
Variabel yang digunakan dalam proses K-Means adalah:
Variabel Species tidak digunakan dalam pembentukan cluster karena merupakan variabel kategorik.
# Mengambil variabel numerik
data_cluster <- iris[, 1:4]
# Melihat data
head(data_cluster)
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## 1 5.1 3.5 1.4 0.2
## 2 4.9 3.0 1.4 0.2
## 3 4.7 3.2 1.3 0.2
## 4 4.6 3.1 1.5 0.2
## 5 5.0 3.6 1.4 0.2
## 6 5.4 3.9 1.7 0.4
# Standardisasi data
data_scaled <- scale(data_cluster)
# Melihat beberapa data hasil standardisasi
head(data_scaled)
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## [1,] -0.8976739 1.01560199 -1.335752 -1.311052
## [2,] -1.1392005 -0.13153881 -1.335752 -1.311052
## [3,] -1.3807271 0.32731751 -1.392399 -1.311052
## [4,] -1.5014904 0.09788935 -1.279104 -1.311052
## [5,] -1.0184372 1.24503015 -1.335752 -1.311052
## [6,] -0.5353840 1.93331463 -1.165809 -1.048667
Statistik hasil standardisasi:
round(
cbind(
Mean = apply(data_scaled, 2, mean),
SD = apply(data_scaled, 2, sd)
),
4
)
## Mean SD
## Sepal.Length 0 1
## Sepal.Width 0 1
## Petal.Length 0 1
## Petal.Width 0 1
Hasil standardisasi menunjukkan bahwa variabel memiliki rata-rata mendekati 0 dan standar deviasi mendekati 1.
Untuk menentukan jumlah cluster, dilakukan perhitungan WSS untuk beberapa nilai K, yaitu K=1 sampai K=10.
set.seed(123)
wss <- numeric(10)
for (k in 1:10) {
km <- kmeans(
data_scaled,
centers = k,
nstart = 25
)
wss[k] <- km$tot.withinss
}
wss_data <- data.frame(
K = 1:10,
WSS = wss
)
kable(
wss_data,
digits = 3,
caption = "Nilai Within-Cluster Sum of Squares"
)
| K | WSS |
|---|---|
| 1 | 596.000 |
| 2 | 220.879 |
| 3 | 138.888 |
| 4 | 113.332 |
| 5 | 90.202 |
| 6 | 79.465 |
| 7 | 70.188 |
| 8 | 62.376 |
| 9 | 54.935 |
| 10 | 48.120 |
Visualisasi Elbow Method:
ggplot(wss_data, aes(x = K, y = WSS)) +
geom_line() +
geom_point(size = 3) +
labs(
title = "Elbow Method",
x = "Jumlah Cluster (K)",
y = "Within-Cluster Sum of Squares"
) +
theme_minimal()
Berdasarkan grafik Elbow Method, jumlah cluster dipilih dengan melihat titik ketika penurunan nilai WSS mulai melandai.
Dalam analisis ini digunakan 2 cluster karena jumlah tersebut memberikan pembagian kelompok yang cukup representatif terhadap karakteristik data iris.
Selain Elbow Method, nilai silhouette dihitung untuk K=2 sampai K=10.
set.seed(123)
silhouette_values <- numeric(9)
for (k in 2:10) {
km <- kmeans(
data_scaled,
centers = k,
nstart = 25
)
sil <- silhouette(
km$cluster,
dist(data_scaled)
)
silhouette_values[k - 1] <- mean(sil[, 3])
}
silhouette_data <- data.frame(
K = 2:10,
Silhouette = silhouette_values
)
kable(
silhouette_data,
digits = 4,
caption = "Nilai Rata-rata Silhouette"
)
| K | Silhouette |
|---|---|
| 2 | 0.5818 |
| 3 | 0.4599 |
| 4 | 0.3839 |
| 5 | 0.3419 |
| 6 | 0.3229 |
| 7 | 0.3254 |
| 8 | 0.3185 |
| 9 | 0.3297 |
| 10 | 0.3440 |
Visualisasi nilai silhouette:
ggplot(silhouette_data, aes(x = K, y = Silhouette)) +
geom_line() +
geom_point(size = 3) +
labs(
title = "Silhouette Analysis",
x = "Jumlah Cluster (K)",
y = "Average Silhouette Width"
) +
theme_minimal()
Nilai silhouette digunakan sebagai informasi tambahan dalam menentukan jumlah cluster. Semakin besar nilai silhouette, semakin baik pemisahan antarcluster.
Berdasarkan pertimbangan hasil Elbow Method dan tujuan analisis, digunakan K=2.
set.seed(123)
kmeans_model <- kmeans(
data_scaled,
centers = 2,
nstart = 25
)
kmeans_model
## K-means clustering with 2 clusters of sizes 50, 100
##
## Cluster means:
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## 1 -1.0111914 0.8504137 -1.300630 -1.2507035
## 2 0.5055957 -0.4252069 0.650315 0.6253518
##
## Clustering vector:
## [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
## [38] 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
## [75] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
## [112] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
## [149] 2 2
##
## Within cluster sum of squares by cluster:
## [1] 47.35062 173.52867
## (between_SS / total_SS = 62.9 %)
##
## Available components:
##
## [1] "cluster" "centers" "totss" "withinss" "tot.withinss"
## [6] "betweenss" "size" "iter" "ifault"
Parameter nstart = 25 digunakan agar algoritma mencoba
beberapa centroid awal sehingga hasil clustering lebih stabil dan tidak
terlalu bergantung pada pemilihan centroid awal.
cluster_size <- as.data.frame(
table(kmeans_model$cluster)
)
colnames(cluster_size) <- c(
"Cluster",
"Jumlah_Observasi"
)
kable(
cluster_size,
caption = "Jumlah Observasi pada Setiap Cluster"
)
| Cluster | Jumlah_Observasi |
|---|---|
| 1 | 50 |
| 2 | 100 |
centroid_scaled <- as.data.frame(
kmeans_model$centers
)
centroid_scaled$Cluster <- rownames(centroid_scaled)
centroid_scaled <- centroid_scaled[, c(
"Cluster",
"Sepal.Length",
"Sepal.Width",
"Petal.Length",
"Petal.Width"
)]
kable(
centroid_scaled,
digits = 3,
caption = "Centroid Setiap Cluster dalam Skala Standardisasi"
)
| Cluster | Sepal.Length | Sepal.Width | Petal.Length | Petal.Width |
|---|---|---|---|---|
| 1 | -1.011 | 0.850 | -1.301 | -1.251 |
| 2 | 0.506 | -0.425 | 0.650 | 0.625 |
Karena model dibangun menggunakan data yang telah distandardisasi, centroid di atas berada dalam skala standardisasi.Untuk interpretasi yang lebih mudah, centroid dapat dikembalikan ke skala aslinya.
centroid_original <- sweep(
kmeans_model$centers,
2,
attr(data_scaled, "scaled:scale"),
"*"
)
centroid_original <- sweep(
centroid_original,
2,
attr(data_scaled, "scaled:center"),
"+"
)
centroid_original <- as.data.frame(centroid_original)
centroid_original$Cluster <- rownames(centroid_original)
centroid_original <- centroid_original[, c(
"Cluster",
"Sepal.Length",
"Sepal.Width",
"Petal.Length",
"Petal.Width"
)]
kable(
centroid_original,
digits = 3,
caption = "Centroid Setiap Cluster pada Skala Asli"
)
| Cluster | Sepal.Length | Sepal.Width | Petal.Length | Petal.Width |
|---|---|---|---|---|
| 1 | 5.006 | 3.428 | 1.462 | 0.246 |
| 2 | 6.262 | 2.872 | 4.906 | 1.676 |
hasil_cluster <- iris
hasil_cluster$Cluster <- factor(
kmeans_model$cluster
)
head(hasil_cluster)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species Cluster
## 1 5.1 3.5 1.4 0.2 setosa 1
## 2 4.9 3.0 1.4 0.2 setosa 1
## 3 4.7 3.2 1.3 0.2 setosa 1
## 4 4.6 3.1 1.5 0.2 setosa 1
## 5 5.0 3.6 1.4 0.2 setosa 1
## 6 5.4 3.9 1.7 0.4 setosa 1
jumlah_cluster <- as.data.frame(
table(hasil_cluster$Cluster)
)
colnames(jumlah_cluster) <- c(
"Cluster",
"Jumlah"
)
kable(
jumlah_cluster,
caption = "Distribusi Observasi Berdasarkan Cluster"
)
| Cluster | Jumlah |
|---|---|
| 1 | 50 |
| 2 | 100 |
Visualisasi cluster berdasarkan Petal Length dan Petal Width:
ggplot(
hasil_cluster,
aes(
x = Petal.Length,
y = Petal.Width,
color = Cluster
)
) +
geom_point(size = 2.8) +
labs(
title = "Hasil K-Means Clustering",
x = "Petal Length",
y = "Petal Width",
color = "Cluster"
) +
theme_minimal()
ggplot(
hasil_cluster,
aes(
x = Sepal.Length,
y = Sepal.Width,
color = Cluster
)
) +
geom_point(size = 2.8) +
labs(
title = "Hasil Clustering Berdasarkan Sepal",
x = "Sepal Length",
y = "Sepal Width",
color = "Cluster"
) +
theme_minimal()
sil_final <- silhouette(
kmeans_model$cluster,
dist(data_scaled)
)
mean_silhouette <- mean(sil_final[, 3])
mean_silhouette
## [1] 0.58175
Nilai rata-rata silhouette model:
## Nilai rata-rata silhouette model K-Means adalah 0.5818 .
Nilai silhouette yang semakin mendekati 1 menunjukkan bahwa observasi semakin sesuai dengan cluster yang ditempatinya, sedangkan nilai yang mendekati 0 menunjukkan adanya observasi yang berada di sekitar batas antarcluster.
Visualisasi silhouette:
plot(
sil_final,
main = "Silhouette Plot K-Means dengan 2 Cluster"
)
Berdasarkan hasil analisis K-Means, data iris berhasil dikelompokkan menjadi tiga cluster berdasarkan empat karakteristik bunga, yaitu Sepal Length, Sepal Width, Petal Length, dan Petal Width.
Karakteristik masing-masing cluster dapat dilihat berdasarkan nilai centroid. Cluster dengan nilai centroid Petal Length dan Petal Width yang relatif rendah menunjukkan kelompok bunga dengan ukuran petal yang relatif kecil. Sebaliknya, cluster dengan nilai centroid Petal Length dan Petal Width yang lebih tinggi menunjukkan kelompok bunga dengan ukuran petal yang relatif besar.
Perbedaan karakteristik antarcluster dapat digunakan untuk mengetahui pola pengelompokan observasi berdasarkan kemiripan karakteristiknya. Selain itu, nilai silhouette digunakan untuk mengevaluasi kualitas hasil pengelompokan. Semakin tinggi nilai silhouette, semakin baik tingkat pemisahan antarcluster.
Variabel Species tidak digunakan dalam pembentukan model K-Means. Namun, variabel tersebut dapat digunakan setelah clustering untuk melihat apakah hasil cluster memiliki kesesuaian dengan kelompok species yang sebenarnya.
tabel_perbandingan <- table(
hasil_cluster$Cluster,
hasil_cluster$Species
)
kable(
tabel_perbandingan,
caption = "Tabulasi Silang Cluster dan Species"
)
| setosa | versicolor | virginica |
|---|---|---|
| 50 | 0 | 0 |
| 0 | 50 | 50 |
Visualisasi:
ggplot(
hasil_cluster,
aes(
x = Species,
fill = Cluster
)
) +
geom_bar(position = "dodge") +
labs(
title = "Perbandingan Cluster dengan Species",
x = "Species",
y = "Jumlah Observasi",
fill = "Cluster"
) +
theme_minimal()
Perbandingan ini hanya digunakan sebagai evaluasi tambahan karena variabel Species tidak digunakan dalam pembentukan cluster.
Berdasarkan hasil analisis yang telah dilakukan, dapat disimpulkan bahwa:
Secara keseluruhan, K-Means dapat digunakan untuk mengelompokkan data iris berdasarkan kemiripan karakteristik numeriknya dan memberikan gambaran mengenai struktur kelompok yang terdapat dalam dataset.