Data

df <- tibble::tribble(
  ~Kecamatan, ~Luas_km2, ~Jumlah_Penduduk, ~Sarana_Perdagangan, ~Sarana_Akomodasi,
  "Mijen", 56.52, 96357, 97, 5,
  "Gunungpati", 58.27, 102429, 101, 13,
  "Banyumanik", 29.74, 144087, 218, 35,
  "Gajahmungkur", 9.34, 56328, 133, 27,
  "Semarang Selatan", 5.95, 61981, 194, 40,
  "Candisari", 6.40, 75396, 107, 30,
  "Tembalang", 39.47, 204865, 174, 16,
  "Pedurungan", 21.11, 198452, 270, 18,
  "Genuk", 25.98, 141033, 75, 1,
  "Gayamsari", 6.22, 70381, 68, 6,
  "Semarang Timur", 5.42, 66482, 142, 27,
  "Semarang Utara", 11.39, 117865, 142, 20,
  "Semarang Tengah", 5.17, 55213, 296, 111,
  "Semarang Barat", 21.68, 149357, 187, 48,
  "Tugu", 28.13, 34398, 39, 0,
  "Ngaliyan", 42.99, 147797, 133, 10
)

kable(df, caption = "Data Kecamatan Kota Semarang")
Data Kecamatan Kota Semarang
Kecamatan Luas_km2 Jumlah_Penduduk Sarana_Perdagangan Sarana_Akomodasi
Mijen 56.52 96357 97 5
Gunungpati 58.27 102429 101 13
Banyumanik 29.74 144087 218 35
Gajahmungkur 9.34 56328 133 27
Semarang Selatan 5.95 61981 194 40
Candisari 6.40 75396 107 30
Tembalang 39.47 204865 174 16
Pedurungan 21.11 198452 270 18
Genuk 25.98 141033 75 1
Gayamsari 6.22 70381 68 6
Semarang Timur 5.42 66482 142 27
Semarang Utara 11.39 117865 142 20
Semarang Tengah 5.17 55213 296 111
Semarang Barat 21.68 149357 187 48
Tugu 28.13 34398 39 0
Ngaliyan 42.99 147797 133 10

Statistika Deskriptif

num <- df %>% select(-Kecamatan)

stat <- tibble(
  Variabel = names(num),
  Min = sapply(num, min),
  Mean = sapply(num, mean),
  SD = sapply(num, sd),
  Max = sapply(num, max)
)

kable(stat, digits = 2, caption = "Statistik Deskriptif")
Statistik Deskriptif
Variabel Min Mean SD Max
Luas_km2 5.17 23.36 18.11 58.27
Jumlah_Penduduk 34398.00 107651.31 52094.42 204865.00
Sarana_Perdagangan 39.00 148.50 71.47 296.00
Sarana_Akomodasi 0.00 25.44 26.79 111.00

Standarisasi (Z-score)

Rumus Z-Score :
\[ Z_{np} = \frac{X_{np} - \bar{X}_{p}}{S_{p}} \]

X <- df %>% select(-Kecamatan)
X_scaled <- scale(X)

# cek sekilas hasil standardisasi
head(X_scaled)
##        Luas_km2 Jumlah_Penduduk Sarana_Perdagangan Sarana_Akomodasi
## [1,]  1.8311724      -0.2168046         -0.7205793      -0.76286462
## [2,]  1.9278151      -0.1002471         -0.6646120      -0.46425094
## [3,]  0.3522627       0.6994163          0.9724323       0.35693666
## [4,] -0.7743152      -0.9851978         -0.2168734       0.05832298
## [5,] -0.9615260      -0.8766833          0.6366283       0.54357020
## [6,] -0.9366750      -0.6191702         -0.5806610       0.17030311

Menentukan Jumlah Klaster (Silhouette)

Rumus Silhouette: \[ \mathrm{Silhouette} = \frac{b_i - a_i}{\max\{a_i,\, b_i\}} \]

set.seed(102)

k_range <- 2:6
sil <- numeric(length(k_range))

for(i in seq_along(k_range)){
  k <- k_range[i]
  km <- kmeans(X_scaled, centers = k, nstart = 25)
  s <- silhouette(km$cluster, dist(X_scaled))
  sil[i] <- mean(s[, 3])
}

sil_tbl <- tibble(K = k_range, Silhouette = sil)
kable(sil_tbl, digits = 4)
K Silhouette
2 0.3031
3 0.3245
4 0.3673
5 0.3477
6 0.3498
ggplot(sil_tbl, aes(x = K, y = Silhouette)) +
  geom_line() +
  geom_point(size = 2) +
  labs(title = "Silhouette Score vs K", x = "Jumlah Klaster (K)", y = "Silhouette Score")

best_k <- sil_tbl$K[which.max(sil_tbl$Silhouette)]

Jumlah klaster terbaik yang digunakan untuk klasterisasi adalah 4 klaster.

K-Means Clustering

Pengukuran kedekatan dalam K-Means umumnya menggunakan jarak Euclidean dengan rumus: \[ d_{ij} = \sqrt{\sum_{k=1}^{p} (x_{ik} - x_{jk})^2} \]

set.seed(102)
km_final <- kmeans(X_scaled, centers = best_k, nstart = 25)

hasil <- df %>%
  mutate(Cluster = as.factor(km_final$cluster)) %>%
  arrange(Cluster, Kecamatan)

kable(
  hasil,
  caption = "Hasil Klaster per Kecamatan",
  align = c("l","r","r","r","r","r")
)
Hasil Klaster per Kecamatan
Kecamatan Luas_km2 Jumlah_Penduduk Sarana_Perdagangan Sarana_Akomodasi Cluster
Banyumanik 29.74 144087 218 35 1
Pedurungan 21.11 198452 270 18 1
Semarang Barat 21.68 149357 187 48 1
Tembalang 39.47 204865 174 16 1
Semarang Tengah 5.17 55213 296 111 2
Genuk 25.98 141033 75 1 3
Gunungpati 58.27 102429 101 13 3
Mijen 56.52 96357 97 5 3
Ngaliyan 42.99 147797 133 10 3
Tugu 28.13 34398 39 0 3
Candisari 6.40 75396 107 30 4
Gajahmungkur 9.34 56328 133 27 4
Gayamsari 6.22 70381 68 6 4
Semarang Selatan 5.95 61981 194 40 4
Semarang Timur 5.42 66482 142 27 4
Semarang Utara 11.39 117865 142 20 4

Profiling Klaster (Rata-rata per Klaster)

profil <- hasil %>%
  group_by(Cluster) %>%
  summarise(
    Luas_km2 = mean(Luas_km2),
    Jumlah_Penduduk = mean(Jumlah_Penduduk),
    Sarana_Perdagangan = mean(Sarana_Perdagangan),
    Sarana_Akomodasi = mean(Sarana_Akomodasi),
    .groups = "drop"
  )

kable(profil, digits = 2, caption = "Rata-rata Variabel per Klaster (Profiling)")
Rata-rata Variabel per Klaster (Profiling)
Cluster Luas_km2 Jumlah_Penduduk Sarana_Perdagangan Sarana_Akomodasi
1 28.00 174190.25 212.25 29.25
2 5.17 55213.00 296.00 111.00
3 42.38 104402.80 89.00 5.80
4 7.45 74738.83 131.00 25.00

Klaster 1 memiliki rata-rata luas wilayah sekitar 28 km² dengan rata-rata jumlah penduduk sekitar 174190 jiwa. Rata-rata sarana perdagangan sebanyak 212 unit dan sarana akomodasi sekitar 29 unit. Klaster ini merepresentasikan kecamatan dengan aktivitas ekonomi yang cukup berkembang.

Klaster 2 memiliki rata-rata luas wilayah sekitar 5.17 km² dengan rata-rata jumlah penduduk sekitar 55213 jiwa. Rata-rata sarana perdagangan sekitar 296 unit dan sarana akomodasi sekitar 111 unit. Klaster ini menunjukkan kecamatan dengan aktivitas ekonomi paling tinggi.

Klaster 3 memiliki rata-rata luas wilayah sekitar 42.38 km² dengan rata-rata jumlah penduduk sekitar 104403 jiwa. Rata-rata sarana perdagangan sekitar 89 unit dan sarana akomodasi sekitar 6 unit. Klaster ini merepresentasikan kecamatan dengan aktivitas ekonomi relatif lebih rendah.

Klaster 4 memiliki rata-rata luas wilayah sekitar 7.45 km² dengan rata-rata jumlah penduduk sekitar 74739 jiwa. Rata-rata sarana perdagangan sekitar 131 unit dan sarana akomodasi sekitar 25 unit. Klaster ini menunjukkan kecamatan dengan aktivitas ekonomi sedang.