ANALISIS CLUSTERING NON-HIERARKI MENGGUNAKAN ALGORITMA K-MEANS

LIBRARY

library(cluster)
library(factoextra)
## Warning: package 'factoextra' was built under R version 4.4.3
## Loading required package: ggplot2
## Warning: package 'ggplot2' was built under R version 4.4.3
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
library(clusterCrit)
## Warning: package 'clusterCrit' was built under R version 4.4.3
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.4.3
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggplot2)
library(tidyr)
## Warning: package 'tidyr' was built under R version 4.4.2
library(scales)
## Warning: package 'scales' was built under R version 4.4.2
library(readxl)
## Warning: package 'readxl' was built under R version 4.4.3
library(RColorBrewer)

IMPORT DATA

data <- read_excel("C:/Users/USER/OneDrive/Documents/Semester 5/TPG/Kesejahteraan Makro.xlsx")
provinsi <- data$provinsi

data_numerik <- data %>% 
  dplyr::select(IPM, P0, TPT, PDRB_ADHB) %>%  
  na.omit()

data_scaled <- scale(data_numerik)

rownames(data_scaled) <- provinsi

head(data_scaled)
##                          IPM          P0         TPT   PDRB_ADHB
## ACEH              0.31873916  0.31024649  0.96891650 -0.65214773
## SUMATERA UTARA    0.31679750 -0.54576267  0.86285112 -0.17313872
## SUMATERA BARAT    0.40805562 -0.82376931  0.96891650 -0.43887433
## RIAU              0.46630548 -0.67612737 -0.48064362  1.30241096
## JAMBI             0.20223944 -0.53476806  0.07089633  0.03823749
## SUMATERA SELATAN -0.01716838 -0.02430388 -0.36750722 -0.14810542

Data yang digunakan merupakan data yang mencerminakan kesejahteraan makro berdasarkan variabel IPM, P0 (persentase penduduk miskin), Tingkat Pengangguran Terbuka, dan Produk Domestik Regional Bruto per Kapita Atas Dasar Harga Berlaku. Data bersumber dari Badan Pusat Statistik Nasional dengan amatan perprovinsi tahun 2024.

Tujuan dilakukannya Clustering adalah untuk:

  1. Mengelompokkan 38 provinsi di Indonesia ke dalam beberapa kelompok (cluster) berdasarkan kemiripan karakteristik kesejahteraan makro
  2. Mengidentifikasi pola kesenjangan kesejahteraan antar wilayah di Indonesia berdasarkan 4 indikator kunci:
  • IPM (Indeks Pembangunan Manusia): Mengukur capaian pembangunan manusia meliputi kesehatan, pendidikan, dan standar hidup
  • P0 (Tingkat Kemiskinan): Persentase penduduk miskin
  • TPT (Tingkat Pengangguran Terbuka): Persentase angkatan kerja yang menganggur
  • PDRB ADHB (Produk Domestik Regional Bruto Atas Dasar Harga Berlaku): Mengukur nilai ekonomi regional

ELBOW METHOD

fviz_nbclust(data_scaled, kmeans, method = "wss") +
labs(title = "Elbow Method")

SILHOUETTE METHOD

fviz_nbclust(data_scaled, kmeans, method = "silhouette") +
labs(title = "Silhouette Method")

Walaupun Silhouette Method memberikan nilai optimal pada k = 9, jumlah klaster tersebut menghasilkan rata-rata hanya 4 provinsi per klaster, sehingga terlalu kecil dan kurang representatif. Sebaliknya, Elbow Method dengan k = 3 memberikan pembagian yang lebih stabil, seimbang, dan mudah diinterpretasikan, serta sesuai dengan tujuan analisis klaster antarprovinsi di Indonesia.

PENERAPAN ALGORITMA K-MEANS

set.seed(123)
kmeans_result <- kmeans(data_scaled, centers = 3, nstart = 25)
kmeans_result
## K-means clustering with 3 clusters of sizes 5, 28, 5
## 
## Cluster means:
##          IPM         P0         TPT  PDRB_ADHB
## 1 -1.8042742  1.9914799 -0.93743183 -0.2165651
## 2  0.1436428 -0.2033029  0.08049272 -0.3403122
## 3  0.9998742 -0.8529836  0.48667260  2.1223133
## 
## Clustering vector:
##                 ACEH       SUMATERA UTARA       SUMATERA BARAT 
##                    2                    2                    2 
##                 RIAU                JAMBI     SUMATERA SELATAN 
##                    3                    2                    2 
##             BENGKULU              LAMPUNG KEP. BANGKA BELITUNG 
##                    2                    2                    2 
##            KEP. RIAU          DKI JAKARTA           JAWA BARAT 
##                    3                    3                    2 
##          JAWA TENGAH        DI YOGYAKARTA           JAWA TIMUR 
##                    2                    2                    2 
##               BANTEN                 BALI  NUSA TENGGARA BARAT 
##                    2                    2                    2 
##  NUSA TENGGARA TIMUR     KALIMANTAN BARAT    KALIMANTAN TENGAH 
##                    1                    2                    2 
##   KALIMANTAN SELATAN     KALIMANTAN TIMUR     KALIMANTAN UTARA 
##                    2                    3                    3 
##       SULAWESI UTARA      SULAWESI TENGAH     SULAWESI SELATAN 
##                    2                    2                    2 
##    SULAWESI TENGGARA            GORONTALO       SULAWESI BARAT 
##                    2                    2                    2 
##               MALUKU         MALUKU UTARA          PAPUA BARAT 
##                    2                    2                    1 
##     PAPUA BARAT DAYA                PAPUA        PAPUA SELATAN 
##                    2                    2                    1 
##         PAPUA TENGAH     PAPUA PEGUNUNGAN 
##                    1                    1 
## 
## Within cluster sum of squares by cluster:
## [1] 13.98463 44.50711 11.27173
##  (between_SS / total_SS =  52.9 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"
table(kmeans_result$cluster)
## 
##  1  2  3 
##  5 28  5

HASIL CLUSTERING

# Data dengan cluster
data_with_cluster <- data.frame(
  Provinsi = provinsi,
  Cluster = kmeans_result$cluster,
  IPM = data$IPM,
  P0 = data$P0,
  TPT = data$TPT,
  PDRB_ADHB = data$PDRB_ADHB
)

# Lihat provinsi per cluster
data_with_cluster %>% 
  arrange(Cluster, Provinsi)
##                                  Provinsi Cluster   IPM    P0  TPT PDRB_ADHB
## NUSA TENGGARA TIMUR   NUSA TENGGARA TIMUR       1 67.39 19.02 3.02     24272
## PAPUA BARAT                   PAPUA BARAT       1 67.02 21.09 4.13    131636
## PAPUA PEGUNUNGAN         PAPUA PEGUNUNGAN       1 53.42 29.66 1.32     18105
## PAPUA SELATAN               PAPUA SELATAN       1 67.90 19.35 4.05     61583
## PAPUA TENGAH                 PAPUA TENGAH       1 59.75 27.60 2.75    118774
## ACEH                                 ACEH       2 74.03 12.64 5.75     43782
## BALI                                 BALI       2 77.76  3.80 1.79     67319
## BANTEN                             BANTEN       2 74.48  5.70 6.68     70276
## BENGKULU                         BENGKULU       2 73.39 12.52 3.11     49233
## DI YOGYAKARTA               DI YOGYAKARTA       2 81.55 10.40 3.48     51473
## GORONTALO                       GORONTALO       2 71.23 13.87 3.13     44433
## JAMBI                               JAMBI       2 73.43  7.26 4.48     86722
## JAWA BARAT                     JAWA BARAT       2 74.43  7.08 6.75     56080
## JAWA TENGAH                   JAWA TENGAH       2 73.88  9.58 4.78     47972
## JAWA TIMUR                     JAWA TIMUR       2 74.09  9.56 4.19     75770
## KALIMANTAN BARAT         KALIMANTAN BARAT       2 70.13  6.25 4.86     52703
## KALIMANTAN SELATAN     KALIMANTAN SELATAN       2 73.03  4.02 4.20     67117
## KALIMANTAN TENGAH       KALIMANTAN TENGAH       2 72.73  5.26 4.01     79320
## KEP. BANGKA BELITUNG KEP. BANGKA BELITUNG       2 73.33  5.08 4.63     70194
## LAMPUNG                           LAMPUNG       2 71.81 10.62 4.19     51370
## MALUKU                             MALUKU       2 71.57 15.78 6.11     32198
## MALUKU UTARA                 MALUKU UTARA       2 71.03  6.03 4.03     70660
## NUSA TENGGARA BARAT   NUSA TENGGARA BARAT       2 70.93 11.91 2.73     32282
## PAPUA                               PAPUA       2 73.00 18.09 6.48     81009
## PAPUA BARAT DAYA         PAPUA BARAT DAYA       2 68.63 16.95 6.48     59064
## SULAWESI BARAT             SULAWESI BARAT       2 68.20 10.71 2.68     42718
## SULAWESI SELATAN         SULAWESI SELATAN       2 74.05  7.77 4.19     73573
## SULAWESI TENGAH           SULAWESI TENGAH       2 71.56 11.04 2.94    120750
## SULAWESI TENGGARA       SULAWESI TENGGARA       2 73.48 10.63 3.09     67840
## SULAWESI UTARA             SULAWESI UTARA       2 75.03  6.70 5.85     69352
## SUMATERA BARAT             SUMATERA BARAT       2 74.49  5.42 5.75     57047
## SUMATERA SELATAN         SUMATERA SELATAN       2 72.30 10.51 3.86     75132
## SUMATERA UTARA             SUMATERA UTARA       2 74.02  7.19 5.60     73575
## DKI JAKARTA                   DKI JAKARTA       3 83.08  4.14 6.21    344350
## KALIMANTAN TIMUR         KALIMANTAN TIMUR       3 78.83  5.51 5.14    212175
## KALIMANTAN UTARA         KALIMANTAN UTARA       3 73.02  5.38 3.90    198429
## KEP. RIAU                       KEP. RIAU       3 77.97  4.78 6.39    161424
## RIAU                                 RIAU       3 74.79  6.36 3.70    165350

EVALUASI CLUSTERING

# Evaluasi clustering
cluster_km <- kmeans_result$cluster
dist_matrix <- dist(data_scaled, method = "euclidean")
sil <- mean(silhouette(cluster_km, dist_matrix)[, 3])
ch <- intCriteria(traj = as.matrix(data_scaled),
                  part = cluster_km,
                  crit = "Calinski_Harabasz")$calinski_harabasz
dunn <- intCriteria(traj = as.matrix(data_scaled),
                    part = cluster_km,
                    crit = "Dunn")$dunn

evaluasi <- data.frame(
  Silhouette = round(sil, 3),
  Calinski_Harabasz = round(ch, 2),
  Dunn = round(dunn, 3)
)
print(evaluasi)
##   Silhouette Calinski_Harabasz  Dunn
## 1      0.386             19.63 0.268
# Silhouette plot
fviz_silhouette(silhouette(cluster_km, dist_matrix),
                palette = "jco",
                ggtheme = theme_minimal()) +
  labs(title = "Silhouette Plot - K-Means (k=3)")
##   cluster size ave.sil.width
## 1       1    5          0.24
## 2       2   28          0.43
## 3       3    5          0.28

# Summary cluster
data_clustered <- data.frame(data, cluster = factor(cluster_km))
cluster_summary <- data_clustered %>%
  group_by(cluster) %>%
  summarise(across(where(is.numeric), mean, .names = "{.col}"))
print(cluster_summary)
## # A tibble: 3 × 5
##   cluster   IPM    P0   TPT PDRB_ADHB
##   <fct>   <dbl> <dbl> <dbl>     <dbl>
## 1 1        63.1 23.3   3.05    70874 
## 2 2        73.1  9.37  4.49    63177.
## 3 3        77.5  5.23  5.07   216346.
# Interpretasi cluster
cluster_interpretation <- data_with_cluster %>%
  group_by(Cluster) %>%
  summarise(
    Jumlah_Provinsi = n(),
    Rata_IPM = round(mean(IPM), 2),
    Rata_P0 = round(mean(P0), 2),
    Rata_TPT = round(mean(TPT), 2),
    Rata_PDRB = round(mean(PDRB_ADHB), 0)
  )
print(cluster_interpretation)
## # A tibble: 3 × 6
##   Cluster Jumlah_Provinsi Rata_IPM Rata_P0 Rata_TPT Rata_PDRB
##     <int>           <int>    <dbl>   <dbl>    <dbl>     <dbl>
## 1       1               5     63.1   23.3      3.05     70874
## 2       2              28     73.1    9.37     4.49     63177
## 3       3               5     77.5    5.23     5.07    216346

Cluster 3: Provinsi dengan Kesejahteraan Tinggi

Karakteristik:

  • IPM tinggi (> 75)
  • Tingkat kemiskinan rendah (< 7%)
  • PDRB tinggi
  • TPT relatif rendah-sedang

Interpretasi: Kelompok ini merupakan provinsi dengan tingkat kesejahteraan dan pembangunan ekonomi terbaik. Provinsi-provinsi ini memiliki infrastruktur yang baik, akses pendidikan dan kesehatan yang memadai, serta aktivitas ekonomi yang tinggi. Kelompok ini umumnya menjadi pusat pertumbuhan ekonomi nasional.

Cluster 2: Provinsi dengan Kesejahteraan Sedang

Karakteristik:

  • IPM menengah (70-75)
  • Tingkat kemiskinan sedang (7-11%)
  • PDRB menengah
  • TPT bervariasi

Interpretasi: Kelompok ini merupakan provinsi yang sedang dalam fase transisi pembangunan. Mereka memiliki potensi ekonomi yang cukup baik namun masih menghadapi tantangan dalam pemerataan kesejahteraan. Akses terhadap layanan dasar sudah cukup baik namun masih perlu ditingkatkan.

Cluster 1: Provinsi dengan Kesejahteraan Rendah

Karakteristik:

  • IPM rendah (< 70)
  • Tingkat kemiskinan tinggi (> 11%)
  • PDRB rendah
  • TPT bervariasi, cenderung tinggi

Interpretasi: Kelompok ini merupakan provinsi yang menghadapi tantangan pembangunan paling besar. Keterbatasan infrastruktur, rendahnya kualitas SDM, dan minimnya aktivitas ekonomi menjadi faktor utama. Provinsi-provinsi ini memerlukan perhatian dan intervensi pemerintah yang lebih intensif.

VISUALISASI

# Visualisasi cluster
fviz_cluster(kmeans_result, data = data_scaled,
             palette = "jco", geom = "point",
             ellipse.type = "convex",
             repel = TRUE,  # agar label tidak overlap
             main = "Visualisasi Hasil K-Means Clustering (3 Cluster)")

# Heatmap
heat_data <- cluster_summary %>%
  pivot_longer(-cluster, names_to = "Variabel", values_to = "Rata2")

ggplot(heat_data, aes(x = Variabel, y = cluster, fill = Rata2)) +
  geom_tile(color = "white") +
  scale_fill_gradientn(colors = c("#56B1F7", "white", "#FF6B6B")) +
  labs(title = "Heatmap Karakteristik Cluster",
       x = "Variabel", y = "Cluster") +
  theme_minimal(base_size = 12) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

# Gunakan data_scaled untuk heatmap dan barplot
cluster_summary_scaled <- data.frame(
  cluster = factor(kmeans_result$cluster),
  data_scaled
) %>%
  group_by(cluster) %>%
  summarise(across(everything(), mean))

# Pivot untuk visualisasi
heat_data_scaled <- cluster_summary_scaled %>%
  pivot_longer(-cluster, names_to = "Variabel", values_to = "Rata2")

# Barplot dengan data standardized
ggplot(heat_data_scaled, aes(x = Variabel, y = Rata2, fill = cluster)) +
  geom_bar(stat = "identity", position = "dodge") +
  scale_fill_brewer(palette = "Set2") +
  labs(title = "Perbandingan Karakteristik Cluster (Standardized)",
       x = "Variabel", 
       y = "Rata-rata Nilai (Z-score)") +
  theme_minimal(base_size = 12) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))