K-Medoid Clustering adalah algoritma unsupervised learning yang digunakan untuk mengelompokkan data ke dalam K cluster. Berbeda dengan K-Means, K-Medoid memilih data aktual sebagai pusat cluster (medoid) sehingga lebih tahan terhadap outlier dan data yang memiliki distribusi tidak bulat.
library(readxl)
library(dplyr)
library(cluster)
library(factoextra)
library(car)
df <- read_excel("C:/Users/Rafi Reshad/OneDrive/PKL/Data/Data PKL.xlsx")
data_num <- df %>%
select(X1, X2, X3, X4)
df
## # A tibble: 23 × 6
## NO KELURAHAN X1 X2 X3 X4
## <dbl> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 1 Cebongan 52873 26 1773 52873
## 2 2 Kumpulrejo 519 35 2399 888
## 3 3 Ledok 161413 69 46 212056
## 4 4 Noborejo 344157 88 31 757596
## 5 5 Randuacir 42340 23 18526 1557332
## 6 6 Tegalrejo 2378 23 1397 534
## 7 7 Dukuh 3193 50 61 2364
## 8 8 Kalicacing 3531 27 83 195
## 9 9 Kecandran 2594 53 1720 405
## 10 10 Mangunsari 464927 110 49 1849121
## # ℹ 13 more rows
Data yang digunakan dalam analisis ini merupakan data sekunder yang bersumber dari portal resmi Dataku Kota Salatiga. Data yang digunakan adalah data tahun 2025 semester I yang disajikan dalam bentuk data per kelurahan di Kota Salatiga Variabel Yang digunakan dalam analisis ini meliputi :
Jumlah Nilai Produksi dan Investasi diukur dalam satuan jutaan rupiah, jumlah unit usaha diukur dalam satuan unit, dan jumlah tenaga diukur dalam satuan manusia
stat_deskriptif <- summary(data_num)
stat_deskriptif
## X1 X2 X3 X4
## Min. : 519 Min. : 23.00 Min. : 31.0 Min. : 195.0
## 1st Qu.: 3202 1st Qu.: 45.50 1st Qu.: 91.0 1st Qu.: 599.5
## Median : 6923 Median : 64.00 Median : 171.0 Median : 6628.0
## Mean : 72972 Mean : 71.57 Mean : 1336.2 Mean : 218597.5
## 3rd Qu.: 32584 3rd Qu.: 89.50 3rd Qu.: 946.5 3rd Qu.: 41725.0
## Max. :501020 Max. :190.00 Max. :18526.0 Max. :1849121.0
Standarisasi data merupakan tahap praproses yang dilakukan untuk menyetarakan skala antar variabel sehingga perbedaan satuan dan rentang nilai tidak memengaruhi hasil analisis statistik. Pada data multivariat, variabel dengan skala yang lebih besar berpotensi memberikan kontribusi yang lebih dominan dibandingkan variabel berskala kecil apabila tidak dilakukan penyesuaian skala, rumus yang digunakan sebagai berikut : \[ z_{ij} = \frac{x_{ij} - \bar{x}_j}{s_j} \]
data_std <- scale(data_num)
data_std <- as.data.frame(data_std)
Asumsi penting dalam analisis klaster adalah tidak adanya multikolinearitas tinggi antar variabel, multikolinearitas yaitu kondisi ketika dua atau lebih variabel memiliki hubungan linear yang kuat sehingga informasi menjadi tumpang tindih dan dapat memengaruhi pembentukan klaster, Nilai VIF dihitung dengan \[ VIF_{j}=\frac{1}{1-R_{j}^2} \]
vif_all <- function(data) {
sapply(colnames(data), function(var) {
independen <- setdiff(colnames(data), var)
model <- lm(
as.formula(paste(var, "~", paste(independen, collapse = "+"))),
data = data
)
max(vif(model))
})
}
vif_all(data_num)
## X1 X2 X3 X4
## 1.806782 4.829704 3.134741 1.698610
Silhouette Coefficient merupakan salah satu ukuran validasi internal yang digunakan untuk mengevaluasi kualitas hasil pengelompokan pada analisis klaster. Metode ini mengukur sejauh mana suatu objek memiliki kemiripan yang tinggi dengan klaster tempatnya berada dibandingkan dengan klaster lain.
k_values <- 2:10
silhouette_scores <- sapply(k_values, function(k) {
pam_fit <- pam(data_std, k)
pam_fit$silinfo$avg.width
})
data.frame(
K = k_values,
Silhouette = round(silhouette_scores, 4)
)
## K Silhouette
## 1 2 0.6308
## 2 3 0.6498
## 3 4 0.4383
## 4 5 0.4239
## 5 6 0.4058
## 6 7 0.4033
## 7 8 0.3727
## 8 9 0.4126
## 9 10 0.4416
fviz_nbclust(data_std, pam, method = "silhouette")
Berdasarkan hasil perhitungan nilai Silhouette, diperoleh bahwa nilai
tertinggi terdapat pada k = 3 dengan nilai sebesar 0,6498, sedangkan
nilai Silhouette pada k = 2 juga relatif tinggi yaitu 0,6308., Dengan
demikian, dapat disimpulkan bahwa jumlah klaster optimal dalam
penelitian ini adalah sebanyak 3 klaster
set.seed(123)
pam_final <- pam(data_std, k = 3)
df$cluster <- factor(pam_final$clustering)
table(df$cluster)
##
## 1 2 3
## 19 3 1
fviz_cluster(
pam_final,
data = data_std,
geom = "point",
ellipse.type = "convex",
show.clust.cent = TRUE,
ggtheme = theme_minimal()
)
medoid_index <- pam_final$id.med
medoid_data <- df[medoid_index, ]
medoid_data
## # A tibble: 3 × 7
## NO KELURAHAN X1 X2 X3 X4 cluster
## <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <fct>
## 1 18 Kalibening 5737 57 173 380 1
## 2 4 Noborejo 344157 88 31 757596 2
## 3 5 Randuacir 42340 23 18526 1557332 3
cluster_summary <- df %>%
group_by(cluster) %>%
summarise(
rata_X1 = mean(X1, na.rm = TRUE),
rata_X2 = mean(X2, na.rm = TRUE),
rata_X3 = mean(X3, na.rm = TRUE),
rata_X4 = mean(X4, na.rm = TRUE)
)
cluster_summary
## # A tibble: 3 × 5
## cluster rata_X1 rata_X2 rata_X3 rata_X4
## <fct> <dbl> <dbl> <dbl> <dbl>
## 1 1 17154. 65 629. 19088.
## 2 2 436701. 129. 85.7 1035912.
## 3 3 42340 23 18526 1557332