Modul 2: Analisis Klaster

Objectives Praktikum

  1. Praktikan mampu memahami dan melakukan analisis klaster
  2. Praktikan mampu melakukan interpretasi terhadap hasil analisis klaster dalam konteks perencanaan wilayah dan kota

Review Teori

Analisis klaster adalah teknik statistik yang berguna untuk mengelompokkan objek ke dalam beberapa kelompok tertentu dimana setiap objek yang terbentuk memiliki sifat dan karakteristik yang berdekatan.

Tujuan dari analisis klaster adalah mengelompokkan objek berdasarkan kesamaan karakteristik di antara objek-objek tersebut. Dengan demikian, ciri-ciri suatu klaster yang baik yaitu memiliki:

  • Homogenitas internal (within cluster) yaitu kesamaan antar anggota dalam satu klaster

  • Heterogenitas eksternal (between cluster) yaitu perbedaan antara klaster yang satu dengan klaster yang lain

Pada analisis klaster, data mentah diubah ke dalam matriks similarity, selanjutnya dirumuskan formasi kelompok dengan prinsip variasi dalam kelompok lebih kecil daripada variasi antar kelompok.

Adapun metode pengelompokan dalam analisis klaster meliputi:
Adapun metode pengelompokan dalam analisis klaster meliputi:
  • Metode Hirarki (Hierarchical Cluster Analysis)

    Pengelompokan dimulai dengan dua atau lebih obyek yang mempunyai kesamaan paling dekat. Metode hirarki ini terdiri dari dua cara, yaitu:

    • Penggabungan (Agglomerative)

      Cara ini digunakan jika masing-masing objek dianggap satu kelompok kemudian antar objek yang jaraknya berdekatan bergabung menjadi satu kelompok. Pada metode ini, dapat digunakan tiga pendekatan yaitu single linkage, average linkage, dan complete linkage.

    • Pemecahan (Divisive)

      Cara ini digunakan jika pada awalnya semua objek berada dalam satu kelompok. Setelah itu, objek dengan sifat paling beda dipisahkan dan membentuk satu kelompok yang lain. Proses tersebut berlanjut sampai semua objek tersebut masing masing membentuk satu kelompok. Metode ini juga disebut sebagai metode splinter average distance karena pemisahan tersebut didasarkan pada rata-rata jarak dengan kelompok lain dan dengan kelompok sendiri.

  • Metode Non-Hirarki (K-Means Clustering)

    Metode Non-Hirarki dilakukan dengan pendekatan K-Means. K-means cluster sangat efektif dan efisien jika digunakan untuk mengelompokkan objek yang berjumlah besar. Metode ini didasarkan optimasi kriteria formal dan telah didefinisikan dengan jumlah obyek yang besar. Pada metode K-Means sudah diasumsikan terlebih dahulu jumlah kelompok yang akan terbentuk. Penentuan kelompok pada metode ini tidak final, jika tidak tepat (tingkat errornya tinggi) maka hasil pengelompokkan dapat diubah dengan memindahkan objek ke klaster lainnya. Adapun tahapan dalam metode K-Means sebagai berikut:

    1. Tentukan kelompok awal berdasarkan perkiraan (hiportesis)

    2. Membuat tabel karakteristik setiap kelompok, berdasarkan rata-rata setiap variabel pada setiap kelompok

    3. Hitung jarak antara invididu dengan kelompok dimana invidu tersebut berada,

    4. Hitung kesalahan pengelompokkan

    5. Menguji penurunan nilai kesalahan dengan adanya pemindahan invidu ke kelompok lain.

Hands-on Praktikum

Kasus

Contoh kasus:
Provinsi Jawa Barat yang merupakan provinsi dengan jumlah penduduk terbesar di Indonesia. Setiap daerah memiliki kewajiban untuk menyediakan pelayanan pendidikan dan kesehatan. Pembangunan bidang kesehatan dan pendidikan bertujuan agar semua lapisan masyarakat dapat meperoleh pelayanan kesehatan dan pendidikan secara mudah dan merata. Selain fasilitas kesehatan skala kecamatan dan kota/kabupaten, diperlukan juga pengembangan sarana dan prasarana maupun program di sektor kesehatan dan pendidikan yang melayani beberapa kota/kabupaten. Oleh karena itu, Pemprov Jawa Barat ingin merancang kebijakan terkait pelayanan kesehatan dan pendidikan. Untuk efektivitas dan efisiensi kebijakan tersebut tidak dimungkinkan membuat kebijakan khusus untuk setiap kota/kabupaten sehingga perlu adanya pengelompokkan kota/kabupaten menjadi 5 kelompok berdasarkan karakteristik yang dimilikinya menggunakan data yang tertera pada data di bawah ini.

Data

Data ini juga dapat diunduh pada link ini: Data

Berikut adalah tabel data sarana kesehatan dan pendidikan di kota/kabupaten Jawa Barat (Sumber: Provinsi Jawa Barat dalam Angka, 2021)

data <- read.csv("data02.csv")
head(data)
##       KabKota JmlSMP JmlSD JmlSMA JmlRS JmlPuskesmas JmlPosyandu JmlKlinik
## 1       Bogor    639  1788    348    25          101        4804       153
## 2    Sukabumi    311  1205    147     7           58        3451        54
## 3     Cianjur    268  1254    164     3           45        2896         6
## 4     Bandung    302  1431    130     7           62        4198       131
## 5       Garut    339  1583    159     6           65        3963        96
## 6 Tasikmalaya    240  1090    116     1           40        2278        29

Rumusan Masalah

Masalah yang akan diteliti adalah sebegai berikut:

  • Berapa klaster yang terbentuk?

  • Bagaimana karakteristik setiap klaster berdasarkan variabel penentunya?

  • Bagaimana interpretasi pembentukan klaster tersebut dalam konteks perencanaan wilayah dan kota?

Preprocessing before clustering

Sebelum melakukan analisis klaster, ada beberapa step yang harus dilakukan (hal ini biasanya berlaku di banyak jenis analisis), yaitu missing value imputation dan scaling.

  • Missing Value Imputation

    Penting juga untuk menangani nilai yang hilang/null/inf dalam kumpulan data Anda sebelumnya. Ada banyak cara untuk menangani nilai-nilai tersebut, salah satunya adalah dengan menghapusnya atau mengimputasinya dengan mean, median, modus, atau menggunakan beberapa teknik regresi tingkat lanjut. R memiliki banyak paket dan fungsi untuk menangani imputasi nilai yang hilang seperti impute(), Amelia, Mice, Hmisc, dll. Dalam kasus praktikum ini tidak terdapat missing value.

    # check missing values in data
    missing_values <- colSums(is.na(data))
    
    # menampilkan missing values
    print("Missing values:")
    ## [1] "Missing values:"
    print(missing_values)
    ##      KabKota       JmlSMP        JmlSD       JmlSMA        JmlRS JmlPuskesmas 
    ##            0            0            0            0            0            0 
    ##  JmlPosyandu    JmlKlinik 
    ##            0            0

    Tidak ada missing values.

  • Scaling

    Sama seperti praktikum sebelumnya, scaling melalui `scale()` dilakukan untuk menyamakan range pada setiap kolom. Hal ini karena nilai fitur dari setiap pengamatan direpresentasikan sebagai koordinat dalam ruang n-dimensi (n adalah jumlah fitur) dan kemudian jarak antara koordinat ini dihitung. Jika koordinat ini tidak dinormalisasi, maka hal ini dapat menyebabkan hasil yang salah.

    # semua data adalah numerical kecuali nama kab/kota
    # simpan kolom kab/kota
    kabKota <- data$KabKota
    # hapus kabkota
    num_data <- data[, -1]
    # melakukan scaling
    scaled_data <- as.data.frame(scale(num_data))
    # penggabungan dengan kolom kab/kota
    normalized_data <- cbind(KabKota=kabKota, scaled_data)
    head(normalized_data)
    ##       KabKota    JmlSMP     JmlSD    JmlSMA      JmlRS JmlPuskesmas JmlPosyandu
    ## 1       Bogor 3.4887296 2.2838748 3.5808450  1.1585236   2.97449528   2.4035309
    ## 2    Sukabumi 0.9942851 1.0493119 0.6734174 -0.4186262   0.91522932   1.2935569
    ## 3     Cianjur 0.6672695 1.1530744 0.9193193 -0.7691039   0.29266054   0.8382460
    ## 4     Bandung 0.9258400 1.5278903 0.4275156 -0.4186262   1.10678894   1.9063807
    ## 5       Garut 1.2072255 1.8497661 0.8469952 -0.5062456   1.25045866   1.7135914
    ## 6 Tasikmalaya 0.4543291 0.8057874 0.2250082 -0.9443428   0.05321101   0.3312512
    ##    JmlKlinik
    ## 1  1.4486412
    ## 2 -0.2125420
    ## 3 -1.0179641
    ## 4  1.0794894
    ## 5  0.4922024
    ## 6 -0.6320327

Hierarchical Cluster Analysis

Jangan lupa untuk melakukan instalasi dan load library untuk analisis klaster

# install.packages("cluster")
# install.packages("stats")
library(cluster)
library(stats)

Sebelum melakukan analisis klaster (hirarki) berdasarkan jenis-jenisnya, perhitungan distance matrix menjadi hal yang umum untuk dilakukan. Hal ini untuk melihat overview “jarak” antar data secara keseluruhan.

Hasil matriks ini juga yang menjadi dasar melakukan analsis cluster.

Jarak yang digunakan adalah euclidean distance. Ada yang tahu apa itu euclidean distance?

Distance Matrix

# untuk mempermudah interpretasi, kolom kabKota dijadikan index dataframe
new_normalized_data <- normalized_data
rownames(new_normalized_data) <- new_normalized_data[, "KabKota"]
# menghapus kolom kabKota sebelumnya
new_normalized_data <- new_normalized_data[, -which(names(new_normalized_data) == "KabKota")]

dist_mat <- dist(new_normalized_data, method = 'euclidean') # scaled_data digunakan karena matriks ini dihitung hanya untuk kolom numerik (tidak termasuk KabKota)
dist_mat
##                       Bogor   Sukabumi    Cianjur    Bandung      Garut
## Sukabumi          5.1883604                                            
## Cianjur           5.9804105  1.2428246                                 
## Bandung           4.8417519  1.5413575  2.6028982                      
## Garut             4.4723816  1.2285558  2.1944172  0.8770045           
## Tasikmalaya       6.6508244  1.6350491  1.0686680  2.7534541  2.6160490
## Ciamis            7.8742544  2.9144206  2.6049130  3.6860491  3.8450714
## Kuningan          8.2356850  3.2748639  2.8823666  4.1777603  4.2891056
## Cirebon           6.4655520  1.5712265  1.6102891  2.6420212  2.6182829
## Majalengka        8.2106516  3.2055412  2.7574948  4.0775139  4.1964772
## Sumedang          7.8553348  3.0470071  2.8268966  3.6594547  3.9085002
## Indramayu         6.6710163  1.6850179  1.3365366  2.8795362  2.7948141
## Subang            6.9748183  2.2561819  2.1745212  2.9122469  3.0901192
## Purwakarta        8.1917398  3.6466118  3.4481228  4.3121113  4.5598825
## Karawang          6.4585462  3.1501656  3.7644888  2.8241324  3.3784094
## Bekasi            5.7762627  4.7243516  5.3999719  4.3330640  4.7049309
## Bandung Barat     7.3235078  2.4511711  2.2464650  3.1851467  3.3891680
## Pangandaran       9.5730218  4.6614530  4.1171707  5.5136253  5.6675970
## Kota Bogor        8.0390859  3.8685132  3.7617652  4.4914641  4.7624541
## Kota Sukabumi     9.5725620  4.7988629  4.3356767  5.6333160  5.8236835
## Kota Bandung      5.7661506  3.1908127  3.8493595  3.4588212  3.6569982
## Kota Cirebon      9.3586316  4.6915596  4.3218278  5.4986183  5.7029475
## Kota Bekasi       7.1952804  3.8886765  3.7627540  4.8693534  4.8330948
## Kota Depok        7.2094286  3.5231466  3.5986228  4.1050977  4.3366096
## Kota Cimahi       9.6500536  4.9037025  4.4778947  5.6836991  5.9035770
## Kota Tasikmalaya  8.9002577  4.2533659  3.8985496  5.0687391  5.2737383
## Kota Banjar      10.0260130  5.2034816  4.7024093  6.0160357  6.2103887
##                  Tasikmalaya     Ciamis   Kuningan    Cirebon Majalengka
## Sukabumi                                                                
## Cianjur                                                                 
## Bandung                                                                 
## Garut                                                                   
## Tasikmalaya                                                             
## Ciamis             1.6632120                                            
## Kuningan           2.0361567  0.6958917                                 
## Cirebon            1.3035350  1.6950518  1.8905142                      
## Majalengka         1.8370829  0.4861467  0.4969874  1.9696245           
## Sumedang           1.8915075  0.7486932  1.3187631  2.0511812  0.9929975
## Indramayu          0.8395222  1.4649031  1.7017712  0.6211703  1.6652772
## Subang             1.3610396  1.0407546  1.6093979  1.3956948  1.4457408
## Purwakarta         2.5453957  1.4891950  1.6130577  2.6647333  1.4932276
## Karawang           3.2873196  2.9758054  3.4300348  2.8570893  3.4103846
## Bekasi             5.2848346  5.3817946  5.7055025  4.9303223  5.7234635
## Bandung Barat      1.4081310  0.9192546  1.4031373  1.5622840  1.1643638
## Pangandaran        3.2193283  1.9055209  1.6378053  3.4321336  1.5186659
## Kota Bogor         3.0288135  2.0576158  2.1625435  2.8829935  2.1316996
## Kota Sukabumi      3.4672395  2.1012088  1.8138336  3.5356914  1.7769246
## Kota Bandung       3.6932195  3.6353686  3.7870377  2.8083647  3.9706136
## Kota Cirebon       3.4630031  2.0272644  1.7028874  3.3661745  1.7868932
## Kota Bekasi        3.6531976  3.5740519  3.3723025  3.1926608  3.5855673
## Kota Depok         3.0186382  2.5275032  2.7297293  2.8367536  2.7024288
## Kota Cimahi        3.5910324  2.1877780  1.9336679  3.6521913  1.8972002
## Kota Tasikmalaya   3.0847582  1.7603877  1.4928766  2.9862906  1.5518208
## Kota Banjar        3.8104556  2.4457159  2.1677909  3.9559420  2.1008364
##                    Sumedang  Indramayu     Subang Purwakarta   Karawang
## Sukabumi                                                               
## Cianjur                                                                
## Bandung                                                                
## Garut                                                                  
## Tasikmalaya                                                            
## Ciamis                                                                 
## Kuningan                                                               
## Cirebon                                                                
## Majalengka                                                             
## Sumedang                                                               
## Indramayu         1.7911099                                            
## Subang            0.9766328  1.2262644                                 
## Purwakarta        1.3047047  2.4412752  1.6898192                      
## Karawang          2.7186449  3.0934144  2.2105288  2.9168782           
## Bekasi            5.1445367  5.1455330  4.5333427  4.8403523  2.8899686
## Bandung Barat     0.7904309  1.2986353  0.7148718  1.4512676  2.5999337
## Pangandaran       1.9924096  3.1027072  2.7581333  1.8165915  4.4298844
## Kota Bogor        1.7484906  2.7397883  1.9668002  1.0440715  2.6895948
## Kota Sukabumi     2.0984319  3.2538914  2.8384285  1.6697068  4.3009988
## Kota Bandung      3.6657544  3.1855775  2.9911986  3.5999728  2.2179349
## Kota Cirebon      2.0776240  3.1623683  2.7019025  1.5194302  3.9924399
## Kota Bekasi       3.7544106  3.2234800  3.3496841  3.1330356  3.9431884
## Kota Depok        2.2270178  2.7456923  2.0506759  1.6811949  2.3589570
## Kota Cimahi       2.1484741  3.3901003  2.8963854  1.6365632  4.2507973
## Kota Tasikmalaya  1.7740935  2.7790849  2.3158784  1.1419668  3.6339403
## Kota Banjar       2.4416097  3.6566020  3.2332855  2.0537269  4.6971416
##                      Bekasi Bandung Barat Pangandaran Kota Bogor Kota Sukabumi
## Sukabumi                                                                      
## Cianjur                                                                       
## Bandung                                                                       
## Garut                                                                         
## Tasikmalaya                                                                   
## Ciamis                                                                        
## Kuningan                                                                      
## Cirebon                                                                       
## Majalengka                                                                    
## Sumedang                                                                      
## Indramayu                                                                     
## Subang                                                                        
## Purwakarta                                                                    
## Karawang                                                                      
## Bekasi                                                                        
## Bandung Barat     4.8100394                                                   
## Pangandaran       6.5820487     2.4093177                                     
## Kota Bogor        4.3668607     1.8546041   2.3877272                         
## Kota Sukabumi     6.3190965     2.4931432   0.6392547  2.0225595              
## Kota Bandung      3.0022931     3.3575158   5.0198869  3.1731555     4.7937609
## Kota Cirebon      5.9750283     2.4487410   1.0674296  1.7461402     0.5852155
## Kota Bekasi       4.3146560     3.2863393   4.1685049  2.8086175     3.8870125
## Kota Depok        3.6479125     2.1328409   3.2428727  1.0146594     2.9308194
## Kota Cimahi       6.2514059     2.5618919   0.7794930  1.9823840     0.2596385
## Kota Tasikmalaya  5.5384124     1.9989082   1.2638496  1.3355339     0.8641087
## Kota Banjar       6.7450073     2.8867320   0.6570437  2.4690788     0.5130001
##                  Kota Bandung Kota Cirebon Kota Bekasi Kota Depok Kota Cimahi
## Sukabumi                                                                     
## Cianjur                                                                      
## Bandung                                                                      
## Garut                                                                        
## Tasikmalaya                                                                  
## Ciamis                                                                       
## Kuningan                                                                     
## Cirebon                                                                      
## Majalengka                                                                   
## Sumedang                                                                     
## Indramayu                                                                    
## Subang                                                                       
## Purwakarta                                                                   
## Karawang                                                                     
## Bekasi                                                                       
## Bandung Barat                                                                
## Pangandaran                                                                  
## Kota Bogor                                                                   
## Kota Sukabumi                                                                
## Kota Bandung                                                                 
## Kota Cirebon        4.3680198                                                
## Kota Bekasi         2.9148146    3.5727992                                   
## Kota Depok          2.5332035    2.6423059   2.5606821                       
## Kota Cimahi         4.8095451    0.5707801   3.9426300  2.9176361            
## Kota Tasikmalaya    4.0139733    0.6126700   3.1286783  2.2403784   0.8815505
## Kota Banjar         5.2749245    0.9825656   4.3475305  3.3827332   0.5170647
##                  Kota Tasikmalaya
## Sukabumi                         
## Cianjur                          
## Bandung                          
## Garut                            
## Tasikmalaya                      
## Ciamis                           
## Kuningan                         
## Cirebon                          
## Majalengka                       
## Sumedang                         
## Indramayu                        
## Subang                           
## Purwakarta                       
## Karawang                         
## Bekasi                           
## Bandung Barat                    
## Pangandaran                      
## Kota Bogor                       
## Kota Sukabumi                    
## Kota Bandung                     
## Kota Cirebon                     
## Kota Bekasi                      
## Kota Depok                       
## Kota Cimahi                      
## Kota Tasikmalaya                 
## Kota Banjar             1.3509546

Data diatas menjadi gambaran jarak antar kab/kota untuk aspek kesehatan dan pendidikan ini. Namun untuk mendalami lebih lanjut dalam mengetahui kelompok-kelompoknya, mari kita lakukan analisis klaster.

Single Lingkage

Single Linkage: menghitung jarak minimum antara klaster sebelum penggabungan. Hubungan ini dapat digunakan untuk mendeteksi nilai tinggi dalam dataset Anda yang mungkin merupakan outlier karena akan digabungkan di bagian akhir.

hclust_single <- hclust(dist_mat, method = 'single')
plot(hclust_single)

Bagaimana cara membaca dendogram?

Dalam pengelompokan hierarki, Anda mengkategorikan objek ke dalam hierarki yang mirip dengan diagram seperti pohon yang disebut dendogram. Jarak pemisahan atau penggabungan (disebut tinggi) ditunjukkan pada sumbu y pada dendogram di bawah ini.

Pada gambar di atas, pertama-tama 4 dan 6 digabungkan ke dalam satu cluster, katakanlah cluster 1, karena jaraknya paling dekat, diikuti oleh titik 1 dan 2, katakanlah cluster 2. Setelah itu 5 digabungkan dalam cluster 1 yang sama diikuti oleh 3 yang menghasilkan dua cluster. Akhirnya kedua cluster tersebut digabungkan menjadi satu cluster dan di sinilah proses pengelompokan berhenti.

Satu pertanyaan yang mungkin membuat Anda penasaran adalah bagaimana Anda memutuskan kapan harus berhenti menggabungkan cluster? Hal ini tergantung pada domain knowledge yang Anda miliki tentang data. Misalnya, jika Anda mengelompokkan pemain sepak bola di lapangan berdasarkan posisi mereka di lapangan yang akan mewakili koordinat mereka untuk penghitungan jarak, Anda sudah tahu bahwa Anda harus mengakhiri dengan hanya 2 cluster karena hanya ada dua tim yang memainkan pertandingan sepak bola.

Namun terkadang Anda juga tidak memiliki informasi tersebut. Pada kasus seperti itu, Anda dapat memanfaatkan hasil dari dendogram untuk memperkirakan jumlah cluster. Anda memotong pohon dendogram dengan garis horizontal pada ketinggian di mana garis tersebut dapat melintasi jarak maksimum ke atas dan ke bawah tanpa memotong titik penggabungan. Pada kasus di atas, ketinggiannya adalah antara 1,5 dan 2,5 seperti yang ditunjukkan:

Jika Anda melakukan pemotongan seperti yang ditunjukkan, Anda hanya akan mendapatkan dua klaster.

Perhatikan bahwa Anda tidak perlu melakukan pemotongan hanya pada tempat tersebut, Anda dapat memilih titik mana pun sebagai titik potong tergantung pada berapa banyak cluster yang Anda inginkan. Sebagai contoh, pemotongan di bawah 1,5 dan di atas 1 akan memberikan Anda 3 cluster.

Perhatikan bahwa ini bukanlah aturan yang baku untuk menentukan jumlah cluster. Anda juga dapat mempertimbangkan plot seperti plot Silhouette, plot siku, atau beberapa ukuran numerik seperti indeks Dunn, gamma Hubert, dll. yang menunjukkan variasi kesalahan dengan jumlah cluster (k), dan Anda memilih nilai k di mana kesalahannya terkecil.

Mari kita coba untuk memilih jumlah kluster sebanyak 5 pada single linkage ini.

plot(hclust_single)
rect.hclust(hclust_single , k = 5, border = 2:6)
abline(h = 5, col = 'red')

Bisa terlihat ke-5 kluster yang terbentuk pada dendrogram di atas.

Kalian juga bisa melakukannya dengan visualisasi yang lebih jelas, yaitu dengan dendextend.

library(dendextend)
## 
## ---------------------
## Welcome to dendextend version 1.17.1
## Type citation('dendextend') for how to cite the package.
## 
## Type browseVignettes(package = 'dendextend') for the package vignette.
## The github page is: https://github.com/talgalili/dendextend/
## 
## Suggestions and bug-reports can be submitted at: https://github.com/talgalili/dendextend/issues
## You may ask questions at stackoverflow, use the r and dendextend tags: 
##   https://stackoverflow.com/questions/tagged/dendextend
## 
##  To suppress this message use:  suppressPackageStartupMessages(library(dendextend))
## ---------------------
## 
## Attaching package: 'dendextend'
## The following object is masked from 'package:stats':
## 
##     cutree
sing_dend_obj <- as.dendrogram(hclust_single)
sing_col_dend <- color_branches(sing_dend_obj, k = 5)
plot(sing_col_dend)

Visuaslisasi diatas bisa dilihat lebih mudah terkait pembentukan klasternya melalui warna branches yang dihasilkan. Mari kita melihat bagaimana karakteristik klaster yang terbentuk.

Melakukan cutree klaster terlebih dahulu.

# Menentukan klaster dengan cutree
num_clusters <- 5
clusters_single <- cutree(hclust_single, k = num_clusters)

Menambahkan kolom klaster pada setiap data. Untuk step ini kita kembali menggunakan data awal (bukan dalam bentuk scaled). Namun sebelumnya kita ubah terlebih dahulu KabKota menjadi index dataframenya.

# untuk mempermudah interpretasi, kolom kabKota dijadikan index dataframe
new_index_data <- data
rownames(new_index_data) <- new_index_data[, "KabKota"]
# menghapus kolom kabKota sebelumnya
new_index_data <- new_index_data[, -which(names(new_index_data) == "KabKota")]
new_index_data
##                  JmlSMP JmlSD JmlSMA JmlRS JmlPuskesmas JmlPosyandu JmlKlinik
## Bogor               639  1788    348    25          101        4804       153
## Sukabumi            311  1205    147     7           58        3451        54
## Cianjur             268  1254    164     3           45        2896         6
## Bandung             302  1431    130     7           62        4198       131
## Garut               339  1583    159     6           65        3963        96
## Tasikmalaya         240  1090    116     1           40        2278        29
## Ciamis              106   751     57     4           37        1586        45
## Kuningan             94   650     41     7           37        1417        13
## Cirebon             183   923    103    10           57        2591        28
## Majalengka          103   668     52     3           32        1461        24
## Sumedang            101   612     76     2           32        1644        78
## Indramayu           193   892    116     6           49        2311        20
## Subang              151   872    102     7           40        1836        80
## Purwakarta          165   429     55    11           20        1010        77
## Karawang            145   890     97    20           50        2271       187
## Bekasi              304   917    178    44           39        2457       240
## Bandung Barat       151   704     91     6           31        2209        64
## Pangandaran          47   295     24     1           15         520        11
## Kota Bogor          120   223     98    17           24         965        94
## Kota Sukabumi        41   104     32     6           15         447        22
## Kota Bandung        234   634    132    33           73        1973       118
## Kota Cirebon         43   134     29    11           22         330        31
## Kota Bekasi         254   441    143    38           31        1546         0
## Kota Depok          206   275    134    20           32        1003       113
## Kota Cimahi          36   101     24     7           13         398        33
## Kota Tasikmalaya     69   208     50    13           20         840        35
## Kota Banjar          22    82     14     3           10         199        18
# Menambahkan kolom klaster ke data frame
data_with_clusters_single <- cbind(data.frame(new_index_data), Cluster = clusters_single)
data_with_clusters_single
##                  JmlSMP JmlSD JmlSMA JmlRS JmlPuskesmas JmlPosyandu JmlKlinik
## Bogor               639  1788    348    25          101        4804       153
## Sukabumi            311  1205    147     7           58        3451        54
## Cianjur             268  1254    164     3           45        2896         6
## Bandung             302  1431    130     7           62        4198       131
## Garut               339  1583    159     6           65        3963        96
## Tasikmalaya         240  1090    116     1           40        2278        29
## Ciamis              106   751     57     4           37        1586        45
## Kuningan             94   650     41     7           37        1417        13
## Cirebon             183   923    103    10           57        2591        28
## Majalengka          103   668     52     3           32        1461        24
## Sumedang            101   612     76     2           32        1644        78
## Indramayu           193   892    116     6           49        2311        20
## Subang              151   872    102     7           40        1836        80
## Purwakarta          165   429     55    11           20        1010        77
## Karawang            145   890     97    20           50        2271       187
## Bekasi              304   917    178    44           39        2457       240
## Bandung Barat       151   704     91     6           31        2209        64
## Pangandaran          47   295     24     1           15         520        11
## Kota Bogor          120   223     98    17           24         965        94
## Kota Sukabumi        41   104     32     6           15         447        22
## Kota Bandung        234   634    132    33           73        1973       118
## Kota Cirebon         43   134     29    11           22         330        31
## Kota Bekasi         254   441    143    38           31        1546         0
## Kota Depok          206   275    134    20           32        1003       113
## Kota Cimahi          36   101     24     7           13         398        33
## Kota Tasikmalaya     69   208     50    13           20         840        35
## Kota Banjar          22    82     14     3           10         199        18
##                  Cluster
## Bogor                  1
## Sukabumi               2
## Cianjur                2
## Bandung                2
## Garut                  2
## Tasikmalaya            2
## Ciamis                 2
## Kuningan               2
## Cirebon                2
## Majalengka             2
## Sumedang               2
## Indramayu              2
## Subang                 2
## Purwakarta             2
## Karawang               2
## Bekasi                 3
## Bandung Barat          2
## Pangandaran            2
## Kota Bogor             2
## Kota Sukabumi          2
## Kota Bandung           4
## Kota Cirebon           2
## Kota Bekasi            5
## Kota Depok             2
## Kota Cimahi            2
## Kota Tasikmalaya       2
## Kota Banjar            2

Melihat keanggotaan setiap klasternya

# Jika nama kabkota adalah row names, Anda bisa mendapatkannya seperti ini:
kabkota_names <- rownames(data_with_clusters_single)
# Kemudian, Anda bisa melihat keanggotaan klaster dengan nama kabkota:
for(k in unique(data_with_clusters_single$Cluster)) {
  cat(paste("Klaster", k, ": \n"))
  cat(paste(kabkota_names[data_with_clusters_single$Cluster == k], collapse = ", "), "\n\n")
}
## Klaster 1 : 
## Bogor 
## 
## Klaster 2 : 
## Sukabumi, Cianjur, Bandung, Garut, Tasikmalaya, Ciamis, Kuningan, Cirebon, Majalengka, Sumedang, Indramayu, Subang, Purwakarta, Karawang, Bandung Barat, Pangandaran, Kota Bogor, Kota Sukabumi, Kota Cirebon, Kota Depok, Kota Cimahi, Kota Tasikmalaya, Kota Banjar 
## 
## Klaster 3 : 
## Bekasi 
## 
## Klaster 4 : 
## Kota Bandung 
## 
## Klaster 5 : 
## Kota Bekasi

Melihat karaktersitik setiap klaster menggunakan dplyr

# Melihat karakteristik setiap klaster
library(dplyr)
## 
## 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
cluster_summary_single <- data_with_clusters_single %>%
  group_by(Cluster) %>%
  summarize_all(list(mean = mean, sd = sd, median = median))

cluster_summary_single
## # A tibble: 5 × 22
##   Cluster JmlSMP_mean JmlSD_mean JmlSMA_mean JmlRS_mean JmlPuskesmas_mean
##     <int>       <dbl>      <dbl>       <dbl>      <dbl>             <dbl>
## 1       1        639       1788        348        25                101  
## 2       2        149.       669.        83.1       7.74              35.0
## 3       3        304        917        178        44                 39  
## 4       4        234        634        132        33                 73  
## 5       5        254        441        143        38                 31  
## # ℹ 16 more variables: JmlPosyandu_mean <dbl>, JmlKlinik_mean <dbl>,
## #   JmlSMP_sd <dbl>, JmlSD_sd <dbl>, JmlSMA_sd <dbl>, JmlRS_sd <dbl>,
## #   JmlPuskesmas_sd <dbl>, JmlPosyandu_sd <dbl>, JmlKlinik_sd <dbl>,
## #   JmlSMP_median <int>, JmlSD_median <int>, JmlSMA_median <int>,
## #   JmlRS_median <int>, JmlPuskesmas_median <int>, JmlPosyandu_median <int>,
## #   JmlKlinik_median <int>

Interpretasi

Klaster 1

  • Klaster ini memiliki jumlah SMP, SD, SMA, rumah sakit, puskesmas, posyandu, dan klinik yang sangat tinggi dibandingkan klaster lain. Ini mungkin menunjukkan wilayah yang lebih urban dengan akses yang lebih baik ke fasilitas pendidikan dan kesehatan.

Klaster 2

  • Klaster ini terdiri dari kota-kota dengan jumlah SMP, SD, SMA, rumah sakit, puskesmas, posyandu, dan klinik yang lebih sedikit daripada Klaster 1, tetapi mungkin masih cukup tinggi secara absolut atau relatif terhadap wilayah lain di luar klaster ini. Varians dalam data juga lebih tinggi, menunjukkan variasi yang lebih besar di antara kota-kota dalam klaster ini.

Klaster 3

  • Klaster ini mencakup kota dengan jumlah SMP, SD, SMA, rumah sakit, puskesmas, posyandu, dan klinik yang lebih sedikit daripada Klaster 1 tetapi lebih banyak daripada rata-rata Klaster 2. Hal ini mungkin menandakan kota-kota dengan level urbanisasi dan akses ke fasilitas yang tinggi namun tidak sepadat Klaster 1.

Klaster 4

  • Klaster ini mirip dengan Klaster 3 dalam hal jumlah fasilitas, tetapi dengan jumlah yang sedikit berkurang, khususnya untuk SMP, SD, dan SMA. Ini bisa menunjukkan kota-kota dengan urbanisasi moderat.

Klaster 5

  • Klaster ini menonjol karena memiliki jumlah klinik yang berarti 0. Dengan jumlah SMP, SD, SMA, rumah sakit, puskesmas, dan posyandu yang juga berada di sisi yang lebih rendah, ini mungkin mencerminkan kota-kota atau daerah yang lebih kecil dengan fasilitas kesehatan yang lebih terbatas.

Notes: Kolom yang memiliki nilai NaN untuk standar deviasi (sd) menunjukkan bahwa hanya ada satu elemen dalam klaster tersebut, sehingga tidak mungkin menghitung deviasi standar.

Dari hasil tersebut, bisa terlihat pengelompokkan mengumpul pada klaster 2 yang memiliki banyak anggota. Sedangkan pada klaster lain hanya memiliki 1 anggota masing-masing. Lalu, bagaimana kita bisa mendapatkan jumlah klaster yang tepat? Hal ini sangat bergantung pada tujuan penelitian dan domain knowledge. Apabila penelitian memang dituntut secara tegas untuk menentukan 5 klaster, maka klaster tersebut harus diikuti. Namun, jika ingin menemukan angka klaster optimum berdasarkan data yang dimiliki, maka kita bisa menggunakan analisis stopping rules untuk analisis klaster.

Stopping Rules

Library yang dibutuhkan

# install.packages('fpc') -> untuk cluster.stats Calinski-Harabasz
library(fpc)

# install.packages('clValid') -> untuk dunn
library(clValid)
  • Calinski-Harabasz

    Pada perhitungan Calinski-Harabasz Index, pendekatan looping digunakan untuk melakukan iterasi pehitungan index mulai dari jumlah klaster paling kecil hingga ke terbesar. Pada praktik umum, batas klaster yang digunakan biasanya adalah 10 klaster. Hal ini dinilai sebagai batas jumlah klaster yang masih bisa menyediakan insight signifikan, apalagi dengan data yang hanya ada 27 data.

    # Inisialisasi vektor untuk menyimpan skor Calinski-Harabasz
    ch_scores_single <- numeric(9)
    
    # menghitung index dengan iterasi 2-10 klaster
    for (k in 2:10) {
      clusters <- cutree(hclust_single, k)
      ch_score <- cluster.stats(dist_mat, clusters)$ch
      ch_scores_single[k-1] <- ch_score
      cat("k =", k, ": Calinski-Harabasz Index =", ch_score, "\n")
    }
    ## k = 2 : Calinski-Harabasz Index = 9.504155 
    ## k = 3 : Calinski-Harabasz Index = 7.732228 
    ## k = 4 : Calinski-Harabasz Index = 6.025049 
    ## k = 5 : Calinski-Harabasz Index = 5.369267 
    ## k = 6 : Calinski-Harabasz Index = 4.811465 
    ## k = 7 : Calinski-Harabasz Index = 10.80516 
    ## k = 8 : Calinski-Harabasz Index = 16.98808 
    ## k = 9 : Calinski-Harabasz Index = 14.87939 
    ## k = 10 : Calinski-Harabasz Index = 18.20564

    Perhatikan juga hasil pada saat k bernilai 5: 5.369267

  • Dunn Index

    # Inisialisasi vektor untuk menyimpan skor Dunn
    dunn_scores_single <- numeric(9) # Misalkan kita ingin mengevaluasi dari 2 sampai 10 klaster
    
    for (k in 2:10) {
      # Memotong pohon klaster untuk mendapatkan vektor klaster
      clusters <- cutree(hclust_single, k)
    
      # Menghitung indeks Dunn menggunakan matriks jarak dan klaster yang dihasilkan
      dunn_scores_single[k-1] <- dunn(dist_mat, clusters)
    
      # Mencetak skor Dunn untuk jumlah klaster k
      cat("Jumlah klaster:", k, "- Skor Dunn:", dunn_scores_single[k-1], "\n")
    }
    ## Jumlah klaster: 2 - Skor Dunn: 0.6630655 
    ## Jumlah klaster: 3 - Skor Dunn: 0.4653442 
    ## Jumlah klaster: 4 - Skor Dunn: 0.4123224 
    ## Jumlah klaster: 5 - Skor Dunn: 0.357133 
    ## Jumlah klaster: 6 - Skor Dunn: 0.3559405 
    ## Jumlah klaster: 7 - Skor Dunn: 0.3041904 
    ## Jumlah klaster: 8 - Skor Dunn: 0.3674025 
    ## Jumlah klaster: 9 - Skor Dunn: 0.3631844 
    ## Jumlah klaster: 10 - Skor Dunn: 0.362507

    Perhatikan hasil pada saat k bernilai 5: 0.357133

Visualisasi hasil keduanya

# Rentang jumlah klaster yang dievaluasi
k_range <- 2:10

# Plot untuk Indeks Calinski-Harabasz
plot(k_range, ch_scores_single, type = 'o', pch = 19, col = 'blue', xlab = 'Jumlah Klaster', ylab = 'Indeks Calinski-Harabasz',
     main = 'Indeks Calinski-Harabasz vs. Jumlah Klaster (Single Linkage)')
abline(v = which.max(ch_scores_single) + 1, col = "red", lwd = 2, lty = 2)

# Plot untuk Indeks Dunn
plot(k_range, dunn_scores_single, type = 'o', pch = 19, col = 'red', xlab = 'Jumlah Klaster', ylab = 'Skor Dunn',
     main = 'Skor Dunn vs. Jumlah Klaster (Single Linkage)')
abline(v = which.max(dunn_scores_single) + 1, col = "blue", lwd = 2, lty = 2)

Berdasarkan Indeks Calinski-Harabasz, klaster optimum (dalam iterasi hingga 10 klaster) adalah 10 klaster. Sedangkan Skor Dunn optimum pada 2 klaster. Mengapa berbeda?

Perbedaan dalam hasil yang kalian lihat antara indeks Calinski-Harabasz dan indeks Dunn bisa disebabkan oleh karakteristik metrik yang berbeda:

  1. Sensitivitas terhadap Struktur Data:
    • Indeks Calinski-Harabasz cenderung sensitif terhadap pemisahan antar-klaster. Jika ada pemisahan yang jelas dan jarak antara pusat klaster cukup besar, indeks ini akan memberikan nilai yang tinggi.
    • Indeks Dunn fokus pada rasio jarak antar-klaster yang minimal terhadap diameter klaster terbesar (intra-klaster). Ini bisa lebih sensitif terhadap outlier dan klaster yang tidak seragam, yang bisa menurunkan skor Dunn meskipun klaster terpisah dengan baik.
  2. Skala dan Normalisasi:
    • Kedua indeks mungkin tidak memiliki skala yang sama, yang bisa memengaruhi interpretasi visual langsung dari plot. Skala untuk Calinski-Harabasz bisa jauh lebih besar daripada Dunn, seperti yang terlihat pada visualisasi.
  3. Karakteristik Metode Klasterisasi:
    • Metode single yang digunakan dalam hclust cenderung menciptakan rantai klaster panjang, yang mungkin tidak ideal untuk menangkap struktur klaster yang alami. Ini bisa memengaruhi skor kedua metrik secara berbeda, tergantung pada bagaimana klaster yang dihasilkan cocok dengan asumsi masing-masing indeks.
  4. Konsistensi dalam Menemukan Jumlah Klaster Optimal:
    • Tidak ada metode yang pasti dalam menentukan jumlah klaster yang optimal. Beberapa metode mungkin menunjukkan jumlah yang berbeda berdasarkan kriteria yang digunakan. Dalam praktiknya, analis sering menggunakan beberapa metode dan menggabungkan hasilnya dengan pengetahuan domain untuk membuat keputusan.
  5. Data dan Pengaruh Outlier:
    • Distribusi data dan adanya outlier bisa berdampak besar pada penghitungan indeks. Outlier bisa sangat mempengaruhi indeks Dunn karena memperbesar diameter klaster, sementara indeks Calinski-Harabasz mungkin lebih tahan terhadap outlier karena berfokus pada rata-rata.

Pada akhirnya, pengambilan keputusan tentang jumlah klaster tidak harus bergantung pada satu indeks saja, melainkan kombinasi dari berbagai indeks, visualisasi, dan, yang paling penting, pengetahuan domain yang digunakan. Maka dari itu,iterasi 1 jenis klaster ini (single linkage) tidak lah cukup.

Complete Linkage

Complete Linkage: menghitung jarak maksimum antar klaster sebelum penggabungan.

hclust_complete <- hclust(dist_mat, method = 'complete')
plot(hclust_complete)

Selanjutnya, kita mengelompokkan dendrogram ke dalam 5 kelompok seperti tujuan awal modul ini.

plot(hclust_complete)
rect.hclust(hclust_complete , k = 5, border = 2:6)
abline(h = 5, col = 'red')

Melakukan bentuk visualisasi lainnya.

comp_dend_obj <- as.dendrogram(hclust_complete)
comp_col_dend <- color_branches(comp_dend_obj, k = 5)
plot(comp_col_dend)

Setelah itu, mari kita lihat karakteristik setiap klaster untuk melakukan interpretasi secara lengkap.

# Menentukan klaster dengan cutree
num_clusters <- 5
clusters_comp <- cutree(hclust_complete, k = num_clusters)

Lalu, kita gabungkan dengan data kita sebelumnya

# Menambahkan kolom klaster ke data frame
data_with_clusters_comp <- cbind(data.frame(new_index_data), Cluster = clusters_comp)
data_with_clusters_comp
##                  JmlSMP JmlSD JmlSMA JmlRS JmlPuskesmas JmlPosyandu JmlKlinik
## Bogor               639  1788    348    25          101        4804       153
## Sukabumi            311  1205    147     7           58        3451        54
## Cianjur             268  1254    164     3           45        2896         6
## Bandung             302  1431    130     7           62        4198       131
## Garut               339  1583    159     6           65        3963        96
## Tasikmalaya         240  1090    116     1           40        2278        29
## Ciamis              106   751     57     4           37        1586        45
## Kuningan             94   650     41     7           37        1417        13
## Cirebon             183   923    103    10           57        2591        28
## Majalengka          103   668     52     3           32        1461        24
## Sumedang            101   612     76     2           32        1644        78
## Indramayu           193   892    116     6           49        2311        20
## Subang              151   872    102     7           40        1836        80
## Purwakarta          165   429     55    11           20        1010        77
## Karawang            145   890     97    20           50        2271       187
## Bekasi              304   917    178    44           39        2457       240
## Bandung Barat       151   704     91     6           31        2209        64
## Pangandaran          47   295     24     1           15         520        11
## Kota Bogor          120   223     98    17           24         965        94
## Kota Sukabumi        41   104     32     6           15         447        22
## Kota Bandung        234   634    132    33           73        1973       118
## Kota Cirebon         43   134     29    11           22         330        31
## Kota Bekasi         254   441    143    38           31        1546         0
## Kota Depok          206   275    134    20           32        1003       113
## Kota Cimahi          36   101     24     7           13         398        33
## Kota Tasikmalaya     69   208     50    13           20         840        35
## Kota Banjar          22    82     14     3           10         199        18
##                  Cluster
## Bogor                  1
## Sukabumi               2
## Cianjur                2
## Bandung                2
## Garut                  2
## Tasikmalaya            2
## Ciamis                 3
## Kuningan               3
## Cirebon                2
## Majalengka             3
## Sumedang               3
## Indramayu              2
## Subang                 3
## Purwakarta             3
## Karawang               4
## Bekasi                 4
## Bandung Barat          3
## Pangandaran            3
## Kota Bogor             3
## Kota Sukabumi          3
## Kota Bandung           4
## Kota Cirebon           3
## Kota Bekasi            5
## Kota Depok             3
## Kota Cimahi            3
## Kota Tasikmalaya       3
## Kota Banjar            3

Melihat keanggotaan setiap klaster

# Jika nama kabkota adalah row names, Anda bisa mendapatkannya seperti ini:
kabkota_names <- rownames(data_with_clusters_comp)
# Kemudian, Anda bisa melihat keanggotaan klaster dengan nama kabkota:
for(k in unique(data_with_clusters_comp$Cluster)) {
  cat(paste("Klaster", k, ": \n"))
  cat(paste(kabkota_names[data_with_clusters_comp$Cluster == k], collapse = ", "), "\n\n")
}
## Klaster 1 : 
## Bogor 
## 
## Klaster 2 : 
## Sukabumi, Cianjur, Bandung, Garut, Tasikmalaya, Cirebon, Indramayu 
## 
## Klaster 3 : 
## Ciamis, Kuningan, Majalengka, Sumedang, Subang, Purwakarta, Bandung Barat, Pangandaran, Kota Bogor, Kota Sukabumi, Kota Cirebon, Kota Depok, Kota Cimahi, Kota Tasikmalaya, Kota Banjar 
## 
## Klaster 4 : 
## Karawang, Bekasi, Kota Bandung 
## 
## Klaster 5 : 
## Kota Bekasi

Melihat karakteristik setiap klaster melalui summary statistics.

cluster_summary_comp <- data_with_clusters_comp %>%
  group_by(Cluster) %>%
  summarize_all(list(mean = mean, sd = sd, median = median))

cluster_summary_comp
## # A tibble: 5 × 22
##   Cluster JmlSMP_mean JmlSD_mean JmlSMA_mean JmlRS_mean JmlPuskesmas_mean
##     <int>       <dbl>      <dbl>       <dbl>      <dbl>             <dbl>
## 1       1        639       1788        348        25                101  
## 2       2        262.      1197.       134.        5.71              53.7
## 3       3         97        407.        58.6       7.87              25.3
## 4       4        228.       814.       136.       32.3               54  
## 5       5        254        441        143        38                 31  
## # ℹ 16 more variables: JmlPosyandu_mean <dbl>, JmlKlinik_mean <dbl>,
## #   JmlSMP_sd <dbl>, JmlSD_sd <dbl>, JmlSMA_sd <dbl>, JmlRS_sd <dbl>,
## #   JmlPuskesmas_sd <dbl>, JmlPosyandu_sd <dbl>, JmlKlinik_sd <dbl>,
## #   JmlSMP_median <int>, JmlSD_median <int>, JmlSMA_median <int>,
## #   JmlRS_median <int>, JmlPuskesmas_median <int>, JmlPosyandu_median <int>,
## #   JmlKlinik_median <int>

Interpretasi

Klaster 1

  • Memiliki jumlah fasilitas pendidikan dan kesehatan tertinggi dibanding klaster lain. Ini termasuk SMP, SD, SMA, rumah sakit, puskesmas, dan posyandu dengan jumlah yang sangat tinggi. Juga memiliki jumlah klinik yang signifikan.
  • Klaster ini kemungkinan mewakili wilayah dengan infrastruktur pendidikan dan kesehatan yang sangat berkembang, mungkin area perkotaan dengan populasi besar.

Klaster 2

  • Menampilkan nilai rata-rata yang lebih rendah dibanding Klaster 1 untuk semua variabel, tetapi masih menunjukkan adanya fasilitas pendidikan dan kesehatan yang cukup. Variabilitas data (standar deviasi) menunjukkan adanya perbedaan yang signifikan di dalam klaster ini, meskipun tidak sebesar Klaster 1.
  • Klaster ini mungkin mewakili wilayah perkotaan atau pinggiran kota dengan akses yang baik terhadap fasilitas pendidikan dan kesehatan, tetapi tidak sepadat Klaster 1.

Klaster 3

  • Memiliki jumlah fasilitas paling sedikit di antara semua klaster untuk hampir semua variabel, menunjukkan wilayah dengan infrastruktur yang lebih terbatas. Variabilitas dalam klaster ini cukup tinggi, menunjukkan adanya perbedaan yang signifikan antar wilayah dalam klaster ini.
  • Mungkin mewakili wilayah non-perkotaan atau daerah dengan populasi lebih sedikit, memiliki akses terbatas ke fasilitas pendidikan dan kesehatan.

Klaster 4

  • Memiliki jumlah rumah sakit yang tinggi dibanding klaster lain dan jumlah puskesmas, posyandu, dan klinik yang cukup. Ini menunjukkan fokus yang lebih pada layanan kesehatan daripada pendidikan.
  • Mungkin mewakili wilayah yang memiliki spesialisasi atau fokus pada penyediaan layanan kesehatan, seperti daerah dengan pusat medis besar atau wilayah dengan kebutuhan kesehatan khusus.

Klaster 5

  • Mirip dengan Klaster 4 dalam hal jumlah fasilitas kesehatan, tetapi dengan jumlah klinik yang sangat sedikit (nol). Ini menunjukkan profil yang serupa dengan Klaster 4 tapi dengan penekanan yang sedikit berbeda.
  • Mungkin wilayah yang mirip dengan Klaster 4 tetapi dengan lebih sedikit fokus pada klinik sebagai bagian dari infrastruktur kesehatannya, mungkin lebih mengandalkan puskesmas dan posyandu.
Stopping Rules
  • Calinski-Harabasz

    # Inisialisasi vektor untuk menyimpan skor Calinski-Harabasz 
    ch_scores_comp <- numeric(9)  # menghitung index dengan iterasi 2-10 klaster 
    for (k in 2:10) {   
      clusters <- cutree(hclust_complete, k)   
      ch_score <- cluster.stats(dist_mat, clusters)$ch   
      ch_scores_comp[k-1] <- ch_score   
      cat("k =", k, ": Calinski-Harabasz Index =", ch_score, "\n") 
    }
    ## k = 2 : Calinski-Harabasz Index = 9.504155 
    ## k = 3 : Calinski-Harabasz Index = 16.22964 
    ## k = 4 : Calinski-Harabasz Index = 19.06925 
    ## k = 5 : Calinski-Harabasz Index = 17.57447 
    ## k = 6 : Calinski-Harabasz Index = 20.67776 
    ## k = 7 : Calinski-Harabasz Index = 20.21964 
    ## k = 8 : Calinski-Harabasz Index = 24.45806 
    ## k = 9 : Calinski-Harabasz Index = 31.48063 
    ## k = 10 : Calinski-Harabasz Index = 33.62283

    Perhatikan hasil pada saat k bernilai 5: 17.57447

  • Dunn Index

    # Inisialisasi vektor untuk menyimpan skor Dunn
    dunn_scores_comp <- numeric(9) # Misalkan kita ingin mengevaluasi dari 2 sampai 10 klaster
    
    for (k in 2:10) {
      # Memotong pohon klaster untuk mendapatkan vektor klaster
      clusters <- cutree(hclust_complete, k)
    
      # Menghitung indeks Dunn menggunakan matriks jarak dan klaster yang dihasilkan
      dunn_scores_comp[k-1] <- dunn(dist_mat, clusters)
    
      # Mencetak skor Dunn untuk jumlah klaster k
      cat("Jumlah klaster:", k, "- Skor Dunn:", dunn_scores_comp[k-1], "\n")
    }
    ## Jumlah klaster: 2 - Skor Dunn: 0.6630655 
    ## Jumlah klaster: 3 - Skor Dunn: 0.2270872 
    ## Jumlah klaster: 4 - Skor Dunn: 0.2842091 
    ## Jumlah klaster: 5 - Skor Dunn: 0.362507 
    ## Jumlah klaster: 6 - Skor Dunn: 0.3803649 
    ## Jumlah klaster: 7 - Skor Dunn: 0.3965801 
    ## Jumlah klaster: 8 - Skor Dunn: 0.4183443 
    ## Jumlah klaster: 9 - Skor Dunn: 0.5148784 
    ## Jumlah klaster: 10 - Skor Dunn: 0.679259

    Perhatikan hasil pada saat k bernilai 5: 0.362507

Visualisasi hasil keduanya

# Rentang jumlah klaster yang dievaluasi
k_range <- 2:10

# Plot untuk Indeks Calinski-Harabasz
plot(k_range, ch_scores_comp, type = 'o', pch = 19, col = 'blue', xlab = 'Jumlah Klaster', ylab = 'Indeks Calinski-Harabasz',
     main = 'Indeks Calinski-Harabasz vs. Jumlah Klaster (Complete Linkage)')
abline(v = which.max(ch_scores_comp) + 1, col = "red", lwd = 2, lty = 2)

# Plot untuk Indeks Dunn
plot(k_range, dunn_scores_comp, type = 'o', pch = 19, col = 'red', xlab = 'Jumlah Klaster', ylab = 'Skor Dunn',
     main = 'Skor Dunn vs. Jumlah Klaster (Complete Linkage)')
abline(v = which.max(dunn_scores_comp) + 1, col = "blue", lwd = 2, lty = 2)

Keduanya memberikan jumlah klaster optimum pada 10 klaster. Hal ini bisa menjadi insight baru untuk mencoba iterasi pembentukan 10 klaster pada data. Pada kasus ini coba lakukan masing-masing secara mandiri.

Average Linkage

Average Linkage:menghitung jarak rata-rata antar klaster sebelum penggabungan.

hclust_avg <- hclust(dist_mat, method = 'average')
plot(hclust_avg)

Selanjutnya, kita mengelompokkan dendrogram ke dalam 5 kelompok seperti tujuan awal modul ini.

plot(hclust_avg)
rect.hclust(hclust_avg , k = 5, border = 2:6)
abline(h = 5, col = 'red')

Melakukan bentuk visualisasi lainnya.

avg_dend_obj <- as.dendrogram(hclust_avg)
avg_col_dend <- color_branches(avg_dend_obj, k = 5)
plot(avg_col_dend)

Setelah itu, mari kita lihat karakteristik setiap klaster untuk melakukan interpretasi secara lengkap.

# Menentukan klaster dengan cutree
num_clusters <- 5
clusters_avg <- cutree(hclust_avg, k = num_clusters)

Lalu, kita gabungkan dengan data kita sebelumnya

# Menambahkan kolom klaster ke data frame
data_with_clusters_avg <- cbind(data.frame(new_index_data), Cluster = clusters_avg)
data_with_clusters_avg
##                  JmlSMP JmlSD JmlSMA JmlRS JmlPuskesmas JmlPosyandu JmlKlinik
## Bogor               639  1788    348    25          101        4804       153
## Sukabumi            311  1205    147     7           58        3451        54
## Cianjur             268  1254    164     3           45        2896         6
## Bandung             302  1431    130     7           62        4198       131
## Garut               339  1583    159     6           65        3963        96
## Tasikmalaya         240  1090    116     1           40        2278        29
## Ciamis              106   751     57     4           37        1586        45
## Kuningan             94   650     41     7           37        1417        13
## Cirebon             183   923    103    10           57        2591        28
## Majalengka          103   668     52     3           32        1461        24
## Sumedang            101   612     76     2           32        1644        78
## Indramayu           193   892    116     6           49        2311        20
## Subang              151   872    102     7           40        1836        80
## Purwakarta          165   429     55    11           20        1010        77
## Karawang            145   890     97    20           50        2271       187
## Bekasi              304   917    178    44           39        2457       240
## Bandung Barat       151   704     91     6           31        2209        64
## Pangandaran          47   295     24     1           15         520        11
## Kota Bogor          120   223     98    17           24         965        94
## Kota Sukabumi        41   104     32     6           15         447        22
## Kota Bandung        234   634    132    33           73        1973       118
## Kota Cirebon         43   134     29    11           22         330        31
## Kota Bekasi         254   441    143    38           31        1546         0
## Kota Depok          206   275    134    20           32        1003       113
## Kota Cimahi          36   101     24     7           13         398        33
## Kota Tasikmalaya     69   208     50    13           20         840        35
## Kota Banjar          22    82     14     3           10         199        18
##                  Cluster
## Bogor                  1
## Sukabumi               2
## Cianjur                3
## Bandung                2
## Garut                  2
## Tasikmalaya            3
## Ciamis                 3
## Kuningan               3
## Cirebon                3
## Majalengka             3
## Sumedang               3
## Indramayu              3
## Subang                 3
## Purwakarta             3
## Karawang               4
## Bekasi                 4
## Bandung Barat          3
## Pangandaran            3
## Kota Bogor             3
## Kota Sukabumi          3
## Kota Bandung           4
## Kota Cirebon           3
## Kota Bekasi            5
## Kota Depok             3
## Kota Cimahi            3
## Kota Tasikmalaya       3
## Kota Banjar            3

Melihat keanggotaan setiap klaster

# Jika nama kabkota adalah row names, Anda bisa mendapatkannya seperti ini:
kabkota_names <- rownames(data_with_clusters_avg)
# Kemudian, Anda bisa melihat keanggotaan klaster dengan nama kabkota:
for(k in unique(data_with_clusters_avg$Cluster)) {
  cat(paste("Klaster", k, ": \n"))
  cat(paste(kabkota_names[data_with_clusters_avg$Cluster == k], collapse = ", "), "\n\n")
}
## Klaster 1 : 
## Bogor 
## 
## Klaster 2 : 
## Sukabumi, Bandung, Garut 
## 
## Klaster 3 : 
## Cianjur, Tasikmalaya, Ciamis, Kuningan, Cirebon, Majalengka, Sumedang, Indramayu, Subang, Purwakarta, Bandung Barat, Pangandaran, Kota Bogor, Kota Sukabumi, Kota Cirebon, Kota Depok, Kota Cimahi, Kota Tasikmalaya, Kota Banjar 
## 
## Klaster 4 : 
## Karawang, Bekasi, Kota Bandung 
## 
## Klaster 5 : 
## Kota Bekasi

Melihat karakteristik setiap klaster

cluster_summary_avg <- data_with_clusters_avg %>%
  group_by(Cluster) %>%
  summarize_all(list(mean = mean, sd = sd, median = median))

cluster_summary_avg
## # A tibble: 5 × 22
##   Cluster JmlSMP_mean JmlSD_mean JmlSMA_mean JmlRS_mean JmlPuskesmas_mean
##     <int>       <dbl>      <dbl>       <dbl>      <dbl>             <dbl>
## 1       1        639       1788        348        25                101  
## 2       2        317.      1406.       145.        6.67              61.7
## 3       3        123.       540.        72.5       7.26              30.1
## 4       4        228.       814.       136.       32.3               54  
## 5       5        254        441        143        38                 31  
## # ℹ 16 more variables: JmlPosyandu_mean <dbl>, JmlKlinik_mean <dbl>,
## #   JmlSMP_sd <dbl>, JmlSD_sd <dbl>, JmlSMA_sd <dbl>, JmlRS_sd <dbl>,
## #   JmlPuskesmas_sd <dbl>, JmlPosyandu_sd <dbl>, JmlKlinik_sd <dbl>,
## #   JmlSMP_median <int>, JmlSD_median <int>, JmlSMA_median <int>,
## #   JmlRS_median <int>, JmlPuskesmas_median <int>, JmlPosyandu_median <int>,
## #   JmlKlinik_median <int>

Interpretasi

Klaster 1 (Bogor)

Klaster ini menonjol dengan jumlah fasilitas pendidikan dan kesehatan yang sangat tinggi dibandingkan klaster lain, yang dapat menunjukkan karakteristik wilayah urban dengan aksesibilitas dan ketersediaan fasilitas yang luas. Keberadaan banyak sekolah menandakan fokus yang kuat pada pendidikan, sementara keberadaan rumah sakit, puskesmas, posyandu, dan klinik yang banyak mencerminkan sistem kesehatan yang berkembang dengan baik, menawarkan berbagai layanan kesehatan kepada masyarakat. Ini mungkin mengindikasikan penduduk yang besar dan kepadatan yang tinggi, dengan infrastruktur yang mendukung kebutuhan pendidikan dan kesehatan masyarakat secara komprehensif.

Klaster 2 (Sukabumi, Bandung, Garut)

Klaster ini memiliki jumlah fasilitas pendidikan dan kesehatan yang moderat, menunjukkan wilayah dengan perkembangan urban yang baik namun mungkin tidak sepadat Klaster 1. Variabilitas dalam jumlah fasilitas antar wilayah dalam klaster ini bisa mengindikasikan adanya perbedaan tingkat urbanisasi dan kepadatan penduduk. Meskipun demikian, ketersediaan fasilitas yang relatif tinggi ini menandakan akses yang baik ke pendidikan dan layanan kesehatan, mendukung kebutuhan dasar masyarakatnya.

Klaster 3 (Cianjur, Tasikmalaya, Ciamis, dst.)

Dengan jumlah entitas terbanyak dan variasi fasilitas kesehatan serta pendidikan yang signifikan, Klaster 3 mungkin mencakup wilayah dengan tingkat urbanisasi yang beragam, dari semi-urban hingga rural. Variabilitas tinggi dalam distribusi fasilitas menunjukkan perbedaan yang besar dalam aksesibilitas dan ketersediaan layanan antar wilayah. Klaster ini kemungkinan mencakup wilayah dengan tantangan geografis atau demografis yang mempengaruhi distribusi fasilitas, menunjukkan perluasan layanan yang belum merata.

Klaster 4 (Karawang, Bekasi, Kota Bandung)

Dengan jumlah rata-rata fasilitas kesehatan yang tinggi, khususnya rumah sakit dan klinik, Klaster 4 mungkin menunjukkan wilayah yang sangat urban dengan kepadatan penduduk tinggi dan kebutuhan kesehatan yang kompleks. Ketersediaan fasilitas pendidikan yang moderat bersama dengan fasilitas kesehatan yang luas mungkin mencerminkan fokus kuat pada kesejahteraan dan layanan kesehatan masyarakat. Variasi dalam jumlah fasilitas bisa menunjukkan perbedaan dalam prioritas atau kapasitas layanan antar kota dalam klaster.

Klaster 5 (Kota Bekasi)

Klaster ini, dengan jumlah fasilitas yang lebih terfokus, menunjukkan karakteristik wilayah urban dengan fokus yang lebih spesifik pada pendidikan dan kesehatan. Meskipun mungkin tidak memiliki keanekaragaman fasilitas sebanyak klaster lain, keberadaan fasilitas yang cukup tinggi di Kota Bekasi menunjukkan infrastruktur yang mendukung kebutuhan mendasar pendiduknya. Ketiadaan variasi data menunjukkan homogenitas dalam distribusi fasilitas, kemungkinan karena fokus pada pengembangan infrastruktur yang merata di seluruh wilayah.

Stopping Rules
  • Calinski-Harabasz

    # Inisialisasi vektor untuk menyimpan skor Calinski-Harabasz 
    ch_scores_avg <- numeric(9)  # menghitung index dengan iterasi 2-10 klaster 
    for (k in 2:10) {   
      clusters <- cutree(hclust_avg, k)   
      ch_score <- cluster.stats(dist_mat, clusters)$ch   
      ch_scores_avg[k-1] <- ch_score   
      cat("k =", k, ": Calinski-Harabasz Index =", ch_score, "\n") 
    }
    ## k = 2 : Calinski-Harabasz Index = 9.504155 
    ## k = 3 : Calinski-Harabasz Index = 14.47158 
    ## k = 4 : Calinski-Harabasz Index = 13.58756 
    ## k = 5 : Calinski-Harabasz Index = 12.29036 
    ## k = 6 : Calinski-Harabasz Index = 10.70125 
    ## k = 7 : Calinski-Harabasz Index = 18.70103 
    ## k = 8 : Calinski-Harabasz Index = 16.98808 
    ## k = 9 : Calinski-Harabasz Index = 22.5999 
    ## k = 10 : Calinski-Harabasz Index = 33.62283

    Perhatikan hasil pada saat k bernilai 5: 12.29036

  • Dunn Index

    # Inisialisasi vektor untuk menyimpan skor Dunn
    dunn_scores_avg <- numeric(9) # Misalkan kita ingin mengevaluasi dari 2 sampai 10 klaster
    
    for (k in 2:10) {
      # Memotong pohon klaster untuk mendapatkan vektor klaster
      clusters <- cutree(hclust_avg, k)
    
      # Menghitung indeks Dunn menggunakan matriks jarak dan klaster yang dihasilkan
      dunn_scores_avg[k-1] <- dunn(dist_mat, clusters)
    
      # Mencetak skor Dunn untuk jumlah klaster k
      cat("Jumlah klaster:", k, "- Skor Dunn:", dunn_scores_avg[k-1], "\n")
    }
    ## Jumlah klaster: 2 - Skor Dunn: 0.6630655 
    ## Jumlah klaster: 3 - Skor Dunn: 0.2630678 
    ## Jumlah klaster: 4 - Skor Dunn: 0.2642953 
    ## Jumlah klaster: 5 - Skor Dunn: 0.2642953 
    ## Jumlah klaster: 6 - Skor Dunn: 0.2642953 
    ## Jumlah klaster: 7 - Skor Dunn: 0.3674025 
    ## Jumlah klaster: 8 - Skor Dunn: 0.3674025 
    ## Jumlah klaster: 9 - Skor Dunn: 0.3961907 
    ## Jumlah klaster: 10 - Skor Dunn: 0.679259

    Perhatikan hasil pada saat k bernilai 5: 0.2642953

Visualisasi Keduanya

# Rentang jumlah klaster yang dievaluasi
k_range <- 2:10

# Plot untuk Indeks Calinski-Harabasz
plot(k_range, ch_scores_avg, type = 'o', pch = 19, col = 'blue', xlab = 'Jumlah Klaster', ylab = 'Indeks Calinski-Harabasz',
     main = 'Indeks Calinski-Harabasz vs. Jumlah Klaster (Average Linkage)')
abline(v = which.max(ch_scores_avg) + 1, col = "red", lwd = 2, lty = 2)

# Plot untuk Indeks Dunn
plot(k_range, dunn_scores_avg, type = 'o', pch = 19, col = 'red', xlab = 'Jumlah Klaster', ylab = 'Skor Dunn',
     main = 'Skor Dunn vs. Jumlah Klaster (Average Linkage)')
abline(v = which.max(dunn_scores_avg) + 1, col = "blue", lwd = 2, lty = 2)

Keduanya optimum pada 10 klaster.

K-Means Cluster Analysis

Di sisi kiri diagram di atas, kita dapat melihat 2 kumpulan titik yang berbeda yang tidak diberi label dan diwarnai sebagai titik data yang serupa. Memasukkan model k-means ke data ini (sisi kanan) dapat mengungkapkan 2 kelompok yang berbeda (ditunjukkan dalam lingkaran dan warna yang berbeda).

Dalam dua dimensi, mudah bagi manusia untuk membagi kelompok-kelompok ini, tetapi dengan lebih banyak dimensi, Anda perlu menggunakan model.

Algoritma

  1. Pilih jumlah cluster, k.
  2. Pilih k titik (cluster dengan ukuran 1) secara acak.
  3. Hitung jarak antara setiap titik dengan centroid dan tetapkan setiap titik data ke klaster terdekat.
  4. Hitung centroid (posisi rata-rata) untuk setiap cluster.
  5. Ulangi langkah 3-4 sampai cluster tidak berubah atau jumlah iterasi maksimum tercapai.

Karena k-means memilih secara acak pusat-pusat cluster, algoritma ini perlu dijalankan dalam jumlah tertentu, yang ditetapkan oleh pengguna. Dengan cara ini, solusi terbaik akan tercapai, dengan meminimalkan metrics kualitas model. Metrics ini disebut within-cluster sum of squares (WCSS), yaitu jumlah jarak antara titik data dan pusat data yang sesuai untuk setiap klaster. Memang, semakin kecil pengukuran kualitas model kita, semakin kita akan mencapai model terbaik.

Sekarang, kita coba melakukan k-means clustering dengan 5 klaster.

set.seed(123) # penting!
km.out <- kmeans(new_normalized_data, centers = 5, nstart = 20)
km.out
## K-means clustering with 5 clusters of sizes 9, 8, 5, 4, 1
## 
## Cluster means:
##       JmlSMP      JmlSD     JmlSMA      JmlRS JmlPuskesmas JmlPosyandu
## 1 -0.2537821  0.1827414 -0.2410802 -0.5841296    0.0266055  0.04238630
## 2 -0.8546838 -1.0852327 -0.8634690 -0.2762446   -1.0302981 -1.05467817
## 3  0.3676320 -0.1653456  0.5258763  1.6842402    0.2926605 -0.01987143
## 4  0.9486550  1.3950107  0.7168119 -0.5281505    0.8912844  1.43794372
## 5  3.4887296  2.2838748  3.5808450  1.1585236    2.9744953  2.40353090
##     JmlKlinik
## 1 -0.40830429
## 2 -0.44535930
## 3  1.08955719
## 4  0.08529644
## 5  1.44864123
## 
## Clustering vector:
##            Bogor         Sukabumi          Cianjur          Bandung 
##                5                4                4                4 
##            Garut      Tasikmalaya           Ciamis         Kuningan 
##                4                1                1                1 
##          Cirebon       Majalengka         Sumedang        Indramayu 
##                1                1                1                1 
##           Subang       Purwakarta         Karawang           Bekasi 
##                1                2                3                3 
##    Bandung Barat      Pangandaran       Kota Bogor    Kota Sukabumi 
##                1                2                2                2 
##     Kota Bandung     Kota Cirebon      Kota Bekasi       Kota Depok 
##                3                2                3                3 
##      Kota Cimahi Kota Tasikmalaya      Kota Banjar 
##                2                2                2 
## 
## Within cluster sum of squares by cluster:
## [1]  7.766899  6.559790 19.358442  4.447357  0.000000
##  (between_SS / total_SS =  79.0 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"

Catatan penting

set.seed adalah fungsi di R yang digunakan untuk menentukan titik awal dari pembangkitan bilangan acak, sehingga hasil yang diperoleh bisa diulang atau konsisten pada saat kode dijalankan berulang kali. Dalam konteks penggunaan set.seed sebelum melakukan clustering dengan k-means, fungsi ini memastikan bahwa hasil dari k-means clustering adalah sama setiap kali kode tersebut dijalankan, asalkan datasetnya tidak berubah.

K-means clustering adalah metode yang sensitif terhadap posisi awal dari centroid-cluster yang ditentukan secara acak pada awal algoritma. Oleh karena itu, titik awal yang berbeda bisa menghasilkan kelompok akhir yang berbeda. Untuk mengatasi hal ini, nstart digunakan dalam fungsi kmeans untuk menjalankan algoritma beberapa kali dengan titik awal yang berbeda, dan hasil terbaik (dengan total jarak terkecil dari titik ke pusat cluster mereka) dipilih. Penggunaan set.seed memastikan bahwa “keacakan” dalam pemilihan titik awal ini konsisten di setiap eksekusi, memungkinkan hasil yang dapat diulang.

Argumen nstart=20 memberitahu R untuk menjalankan algoritma k-means sebanyak 20 kali dengan titik awal yang berbeda. Tujuannya adalah untuk mengurangi kemungkinan hasil yang buruk karena pemilihan awal yang buruk untuk pusat cluster (centroid). Fungsi ini akan memilih hasil terbaik dari ke-20 run tersebut, yaitu yang memiliki total within-cluster sum of squares terkecil.

Interpretasi

  1. Ukuran Cluster:
    • Menunjukkan bahwa ada 5 cluster dengan jumlah elemen masing-masing adalah 9, 8, 5, 4, dan 1.
  2. Rata-rata Cluster (Cluster Means):
    • Tabel ini menunjukkan nilai rata-rata untuk setiap variabel pada setiap cluster. Variabel-variabel yang disertakan meliputi JmlSMP, JmlSD, JmlSMA, JmlRS, JmlPuskesmas, JmlPosyandu, dan JmlKlinik. Nilai-nilai ini menunjukkan karakteristik pusat dari setiap cluster.
  3. Vektor Clustering:
    • Bagian ini menampilkan penugasan setiap entitas (dalam hal ini, mungkin wilayah atau kota seperti Bogor, Sukabumi, Cianjur, dll.) ke dalam cluster tertentu. Misalnya, Bogor ditugaskan ke cluster 5, Sukabumi ke cluster 4, dan seterusnya.
  4. Within Cluster Sum of Squares by Cluster:
    • Ini menunjukkan total within cluster sum of squares (WCSS) untuk masing-masing cluster. WCSS adalah ukuran seberapa kompak cluster tersebut; semakin kecil nilainya, semakin dekat anggota dalam cluster tersebut satu sama lain. Angka-angka ini penting untuk mengevaluasi kualitas clustering. Terdapat juga cluster yang memiliki WCSS sebesar 0, yang menunjukkan bahwa hanya ada satu elemen dalam cluster tersebut, sehingga tidak ada variabilitas internal.
  5. Between_SS / Total_SS = 79.0%:
    • Rasio between cluster sum of squares (between_SS) terhadap total sum of squares (total_SS) menunjukkan persentase varians yang dijelaskan oleh pembagian ke dalam cluster. Dalam kasus ini, 79% varians dapat dijelaskan oleh model clustering ini, yang menunjukkan bahwa model memiliki kemampuan yang baik untuk membedakan antar cluster.
  6. Available Components:
    • Bagian ini mencantumkan komponen yang tersedia dari hasil output yang bisa Anda akses. Misalnya, cluster untuk melihat penugasan cluster, centers untuk melihat pusat cluster, withinss untuk sum of squares dalam setiap cluster, dan lain-lain. Ini berguna untuk analisis lebih lanjut terhadap hasil clustering.

Bisa berikan interpretasi dari hasil di atas?

Mari kita gabungkan hasil klaster ini ke dalam tabel utama (non-scaled).

data_with_clusters_kmeans <- new_index_data
data_with_clusters_kmeans$Cluster <- km.out$cluster
data_with_clusters_kmeans
##                  JmlSMP JmlSD JmlSMA JmlRS JmlPuskesmas JmlPosyandu JmlKlinik
## Bogor               639  1788    348    25          101        4804       153
## Sukabumi            311  1205    147     7           58        3451        54
## Cianjur             268  1254    164     3           45        2896         6
## Bandung             302  1431    130     7           62        4198       131
## Garut               339  1583    159     6           65        3963        96
## Tasikmalaya         240  1090    116     1           40        2278        29
## Ciamis              106   751     57     4           37        1586        45
## Kuningan             94   650     41     7           37        1417        13
## Cirebon             183   923    103    10           57        2591        28
## Majalengka          103   668     52     3           32        1461        24
## Sumedang            101   612     76     2           32        1644        78
## Indramayu           193   892    116     6           49        2311        20
## Subang              151   872    102     7           40        1836        80
## Purwakarta          165   429     55    11           20        1010        77
## Karawang            145   890     97    20           50        2271       187
## Bekasi              304   917    178    44           39        2457       240
## Bandung Barat       151   704     91     6           31        2209        64
## Pangandaran          47   295     24     1           15         520        11
## Kota Bogor          120   223     98    17           24         965        94
## Kota Sukabumi        41   104     32     6           15         447        22
## Kota Bandung        234   634    132    33           73        1973       118
## Kota Cirebon         43   134     29    11           22         330        31
## Kota Bekasi         254   441    143    38           31        1546         0
## Kota Depok          206   275    134    20           32        1003       113
## Kota Cimahi          36   101     24     7           13         398        33
## Kota Tasikmalaya     69   208     50    13           20         840        35
## Kota Banjar          22    82     14     3           10         199        18
##                  Cluster
## Bogor                  5
## Sukabumi               4
## Cianjur                4
## Bandung                4
## Garut                  4
## Tasikmalaya            1
## Ciamis                 1
## Kuningan               1
## Cirebon                1
## Majalengka             1
## Sumedang               1
## Indramayu              1
## Subang                 1
## Purwakarta             2
## Karawang               3
## Bekasi                 3
## Bandung Barat          1
## Pangandaran            2
## Kota Bogor             2
## Kota Sukabumi          2
## Kota Bandung           3
## Kota Cirebon           2
## Kota Bekasi            3
## Kota Depok             3
## Kota Cimahi            2
## Kota Tasikmalaya       2
## Kota Banjar            2

Melihat keanggotaan klaster

# Jika nama kabkota adalah row names, Anda bisa mendapatkannya seperti ini:
kabkota_names <- rownames(data_with_clusters_kmeans)
# Kemudian, Anda bisa melihat keanggotaan klaster dengan nama kabkota:
for(k in unique(data_with_clusters_kmeans$Cluster)) {
  cat(paste("Klaster", k, ": \n"))
  cat(paste(kabkota_names[data_with_clusters_kmeans$Cluster == k], collapse = ", "), "\n\n")
}
## Klaster 5 : 
## Bogor 
## 
## Klaster 4 : 
## Sukabumi, Cianjur, Bandung, Garut 
## 
## Klaster 1 : 
## Tasikmalaya, Ciamis, Kuningan, Cirebon, Majalengka, Sumedang, Indramayu, Subang, Bandung Barat 
## 
## Klaster 2 : 
## Purwakarta, Pangandaran, Kota Bogor, Kota Sukabumi, Kota Cirebon, Kota Cimahi, Kota Tasikmalaya, Kota Banjar 
## 
## Klaster 3 : 
## Karawang, Bekasi, Kota Bandung, Kota Bekasi, Kota Depok

Melihat karakteristik setiap klaster

cluster_summary_kmeans <- data_with_clusters_kmeans %>%
  group_by(Cluster) %>%
  summarize_all(list(mean = mean, sd = sd, median = median))

cluster_summary_kmeans
## # A tibble: 5 × 22
##   Cluster JmlSMP_mean JmlSD_mean JmlSMA_mean JmlRS_mean JmlPuskesmas_mean
##     <int>       <dbl>      <dbl>       <dbl>      <dbl>             <dbl>
## 1       1       147.        796.        83.8       5.11              39.4
## 2       2        67.9       197         40.8       8.62              17.4
## 3       3       229.        631.       137.       31                 45  
## 4       4       305        1368.       150         5.75              57.5
## 5       5       639        1788        348        25                101  
## # ℹ 16 more variables: JmlPosyandu_mean <dbl>, JmlKlinik_mean <dbl>,
## #   JmlSMP_sd <dbl>, JmlSD_sd <dbl>, JmlSMA_sd <dbl>, JmlRS_sd <dbl>,
## #   JmlPuskesmas_sd <dbl>, JmlPosyandu_sd <dbl>, JmlKlinik_sd <dbl>,
## #   JmlSMP_median <dbl>, JmlSD_median <dbl>, JmlSMA_median <dbl>,
## #   JmlRS_median <dbl>, JmlPuskesmas_median <dbl>, JmlPosyandu_median <dbl>,
## #   JmlKlinik_median <dbl>

Interpretasi

Klaster 1

  • Memiliki jumlah rata-rata SMP, SD, dan SMA yang moderat dibandingkan dengan klaster lain, namun jumlah rata-rata rumah sakit lebih rendah. Jumlah puskesmas dan posyandu yang moderat menunjukkan akses yang cukup baik ke layanan kesehatan primer.
  • Mungkin mencerminkan daerah dengan kepadatan penduduk yang moderat dan akses ke pendidikan dan kesehatan yang cukup memadai.

Klaster 2

  • Memiliki jumlah fasilitas pendidikan yang lebih rendah dibanding klaster lain, namun jumlah rata-rata rumah sakit lebih tinggi. Menunjukkan adanya fokus pada peningkatan fasilitas kesehatan.
  • Dapat diinterpretasikan sebagai daerah atau kota dengan fokus pada pengembangan fasilitas kesehatan, mungkin untuk melayani populasi yang lebih padat atau sebagai pusat rujukan kesehatan.

Klaster 3

  • Menunjukkan jumlah rata-rata fasilitas pendidikan dan kesehatan yang tinggi, terutama rumah sakit, puskesmas, dan klinik, yang mencerminkan daerah perkotaan dengan akses luas ke layanan kesehatan dan pendidikan.
  • Klaster ini kemungkinan mencakup daerah perkotaan dengan populasi yang besar dan kepadatan penduduk yang tinggi, serta infrastruktur pendidikan dan kesehatan yang berkembang baik.

Klaster 4

  • Memiliki jumlah fasilitas pendidikan tertinggi di antara klaster lain dan jumlah puskesmas dan posyandu yang tinggi, menunjukkan daerah dengan akses yang sangat baik ke pendidikan dan kesehatan primer.
  • Mungkin mencerminkan daerah dengan kepadatan penduduk yang tinggi dan/atau daerah yang telah berinvestasi secara signifikan dalam pendidikan dan kesehatan masyarakat.

Klaster 5

  • Klaster ini unik karena hanya terdiri dari satu entitas (Bogor) dengan jumlah fasilitas pendidikan dan kesehatan yang sangat tinggi, khususnya jumlah SMP, SD, dan SMA, serta jumlah rumah sakit.
  • Sebagai klaster tunggal, Bogor menunjukkan karakteristik daerah yang sangat berkembang dengan infrastruktur pendidikan dan kesehatan yang luas, mungkin mencerminkan statusnya sebagai daerah yang sangat prioritas dalam pengembangan sumber daya manusia dan kesehatan.

Stopping Rules

  • WCSS

    Meskipun kelihatannya hasilnya bagus, cara terbaik untuk menemukan model terbaik adalah dengan mencoba model yang berbeda dengan jumlah cluster yang berbeda. Jadi, kita perlu memulai dari model dengan satu cluster, setelah itu mencoba model dengan dua cluster dan seterusnya. Semua prosedur ini perlu dilacak dengan menggunakan representasi grafis, yang disebut scree plot, di mana jumlah cluster diplot pada sumbu x, sedangkan WCSS pada sumbu y.

    Dalam studi kasus ini, kami membangun 10 model k-means, yang masing-masing akan memiliki jumlah cluster yang berbeda, mencapai maksimum 10 cluster. Selain itu, kita hanya akan menggunakan sebagian dari dataset. Jadi, kami hanya menyertakan harga dan jumlah ulasan. Untuk memplot scree plot, kita perlu menyimpan jumlah kuadrat total dalam cluster dari semua model ke dalam variabel wss.

    # library for visualization
    library(ggplot2)
    
    # Decide how many clusters to look at
    n_clusters <- 10
    
    # Initialize total within sum of squares error: wss
    wss <- numeric(n_clusters)
    
    set.seed(123)
    
    # Look over 1 to n possible clusters
    for (i in 1:n_clusters) {
      # Fit the model: km.out
      km.out <- kmeans(new_normalized_data, centers = i, nstart = 20)
      # Save the within cluster sum of squares
      wss[i] <- km.out$tot.withinss
    }
    
    # Produce a scree plot
    wss_df <- tibble(clusters = 1:n_clusters, wss = wss)
    
    scree_plot <- ggplot(wss_df, aes(x = clusters, y = wss, group = 1)) +
        geom_point(size = 4)+
        geom_line() +
        scale_x_continuous(breaks = c(2, 4, 6, 8, 10)) +
        xlab('Number of clusters')
    scree_plot

    Dengan melihat scree plot, kita dapat melihat bagaimana jumlah kuadrat total dalam klaster menurun seiring dengan bertambahnya jumlah klaster. Kriteria untuk memilih jumlah cluster adalah dengan menemukan siku sedemikian rupa sehingga Anda dapat menemukan titik di mana WCSS menurun jauh lebih lambat setelah menambahkan cluster lain. Dalam kasus ini, hal ini tidak begitu jelas, jadi kita akan menambahkan garis horizontal untuk mendapatkan ide yang lebih baik:

    scree_plot +
        geom_hline(
            yintercept = wss, 
            linetype = 'dashed', 
            col = c(rep('#000000',3),'#FF0000', rep('#000000', 6)) # nambahin garis merah
        )

    Dari hasil di atas, terlihat bahwa patahan screeplot terbesar ada setelah klaster 4. Setelah itu, penurunan terjadi tidak begitu drastis seperti sebelumnya. Maka dari itu, berdasarkan screplot WCSS ini, 4 klaster menjadi model terbaik.

  • Calinski-Harabasz

    # Inisialisasi vektor untuk menyimpan skor Calinski-Harabasz 
    set.seed(123)
    ch_scores <- numeric(9)  # menghitung index dengan iterasi 2-10 klaster 
    for (k in 2:10) {   
      clust <- kmeans(new_normalized_data, centers = k, nstart = 20)   
      ch_score <- cluster.stats(dist_mat, clust$cluster)$ch   
      ch_scores[k-1] <- ch_score   
      cat("k =", k, ": Calinski-Harabasz Index =", ch_score, "\n") 
    }
    ## k = 2 : Calinski-Harabasz Index = 18.90029 
    ## k = 3 : Calinski-Harabasz Index = 16.49498 
    ## k = 4 : Calinski-Harabasz Index = 20.09877 
    ## k = 5 : Calinski-Harabasz Index = 20.75058 
    ## k = 6 : Calinski-Harabasz Index = 22.50812 
    ## k = 7 : Calinski-Harabasz Index = 24.00612 
    ## k = 8 : Calinski-Harabasz Index = 26.15942 
    ## k = 9 : Calinski-Harabasz Index = 31.48063 
    ## k = 10 : Calinski-Harabasz Index = 31.01886

    Perhatikan hasil pada saat k bernilai 5: 20.75058

  • Dunn Index

    # Inisialisasi vektor untuk menyimpan skor Dunn
    set.seed(123)
    dunn_scores <- numeric(9) # Misalkan kita ingin mengevaluasi dari 2 sampai 10 klaster
    
    for (k in 2:10) {
      # Memotong pohon klaster untuk mendapatkan vektor klaster
      clust <- kmeans(new_normalized_data, centers = k, nstart = 20)
    
      # Menghitung indeks Dunn menggunakan matriks jarak dan klaster yang dihasilkan
      dunn_scores[k-1] <- dunn(dist_mat, clust$cluster)
    
      # Mencetak skor Dunn untuk jumlah klaster k
      cat("Jumlah klaster:", k, "- Skor Dunn:", dunn_scores[k-1], "\n")
    }
    ## Jumlah klaster: 2 - Skor Dunn: 0.1654657 
    ## Jumlah klaster: 3 - Skor Dunn: 0.1323844 
    ## Jumlah klaster: 4 - Skor Dunn: 0.1656845 
    ## Jumlah klaster: 5 - Skor Dunn: 0.2351658 
    ## Jumlah klaster: 6 - Skor Dunn: 0.347758 
    ## Jumlah klaster: 7 - Skor Dunn: 0.347758 
    ## Jumlah klaster: 8 - Skor Dunn: 0.3803649 
    ## Jumlah klaster: 9 - Skor Dunn: 0.5148784 
    ## Jumlah klaster: 10 - Skor Dunn: 0.3375632

    Perhatikan hasil pada saat k bernilai 5: 0.2351658

Visualisasi keduanya

# Rentang jumlah klaster yang dievaluasi
k_range <- 2:10

# Plot untuk Indeks Calinski-Harabasz
plot(k_range, ch_scores, type = 'o', pch = 19, col = 'blue', xlab = 'Jumlah Klaster', ylab = 'Indeks Calinski-Harabasz',
     main = 'Indeks Calinski-Harabasz vs. Jumlah Klaster')
abline(v = which.max(ch_scores) + 1, col = "red", lwd = 2, lty = 2)

# Plot untuk Indeks Dunn
plot(k_range, dunn_scores, type = 'o', pch = 19, col = 'red', xlab = 'Jumlah Klaster', ylab = 'Skor Dunn',
     main = 'Skor Dunn vs. Jumlah Klaster')
abline(v = which.max(dunn_scores) + 1, col = "blue", lwd = 2, lty = 2)

Keduanya memberikan hasil 9 klaster.

Lalu, bagaimana memilihnya? kembali lagi semua harus tergantung iterasi. Untuk mendapatkan klaster terbaik akan sangat bergantung pada domain knowledge analis.

Menentukan model terbaik

Pada tahap ini kita akan menentukan model terbaik dengan membandingkan indeks Calinski-Harabasz dan Dunn pada seluruh analisis dengan 5 klaster.

ch_scores <- numeric(4)
dunn_scores <- numeric(4)


# 1. Single Linkage
clusters_single <- cutree(hclust_single, 5)
ch_scores[1] <- cluster.stats(dist_mat, clusters_single)$ch
dunn_scores[1] <- dunn(dist_mat, clusters_single)

# 2. Complete Linkage
clusters_complete <- cutree(hclust_complete, 5)
ch_scores[2] <- cluster.stats(dist_mat, clusters_complete)$ch
dunn_scores[2] <- dunn(dist_mat, clusters_complete)

# 3. Average Linkage
clusters_avg <- cutree(hclust_avg, 5)
ch_scores[3] <- cluster.stats(dist_mat, clusters_avg)$ch
dunn_scores[3] <- dunn(dist_mat, clusters_avg)

# 4. K-Means
set.seed(123)
clust <- kmeans(new_normalized_data, centers = 5, nstart = 20)   
ch_scores[4] <- cluster.stats(dist_mat, clust$cluster)$ch
dunn_scores[4] <- dunn(dist_mat, clust$cluster)

# Membuat dataframe
results_df <- data.frame(
  Method = c("Single Linkage", "Complete Linkage", "Average Linkage", "K-Means"),
  Calinski_Harabasz = ch_scores,
  Dunn = dunn_scores
)

# Menampilkan dataframe
results_df
##             Method Calinski_Harabasz      Dunn
## 1   Single Linkage          5.369267 0.3571330
## 2 Complete Linkage         17.574473 0.3625070
## 3  Average Linkage         12.290364 0.2642953
## 4          K-Means         20.750582 0.2351658

Berdasarkan Calinski-Harabasz, model K-Means menjadi model clustering terbaik. Sedangkan berdasarkan Dunn, model Complete Linkage menjadi yang terbaik. Dalam hal ini keduanya bisa dipilih sesuai kebutuhan. Untuk analisis selanjutnya, kita akan memilih hasil pengelompokkan dari Complete Linkage.

Mengidentifikasi fasilitas yang dibutuhkan

Melihat rentang setiap fasilitas untuk mengidentifikasi rentang “tinggi”, “sedang”, “rendang” jumlah fasilitasnya di setiap kab/kota.

data_with_clusters_comp
##                  JmlSMP JmlSD JmlSMA JmlRS JmlPuskesmas JmlPosyandu JmlKlinik
## Bogor               639  1788    348    25          101        4804       153
## Sukabumi            311  1205    147     7           58        3451        54
## Cianjur             268  1254    164     3           45        2896         6
## Bandung             302  1431    130     7           62        4198       131
## Garut               339  1583    159     6           65        3963        96
## Tasikmalaya         240  1090    116     1           40        2278        29
## Ciamis              106   751     57     4           37        1586        45
## Kuningan             94   650     41     7           37        1417        13
## Cirebon             183   923    103    10           57        2591        28
## Majalengka          103   668     52     3           32        1461        24
## Sumedang            101   612     76     2           32        1644        78
## Indramayu           193   892    116     6           49        2311        20
## Subang              151   872    102     7           40        1836        80
## Purwakarta          165   429     55    11           20        1010        77
## Karawang            145   890     97    20           50        2271       187
## Bekasi              304   917    178    44           39        2457       240
## Bandung Barat       151   704     91     6           31        2209        64
## Pangandaran          47   295     24     1           15         520        11
## Kota Bogor          120   223     98    17           24         965        94
## Kota Sukabumi        41   104     32     6           15         447        22
## Kota Bandung        234   634    132    33           73        1973       118
## Kota Cirebon         43   134     29    11           22         330        31
## Kota Bekasi         254   441    143    38           31        1546         0
## Kota Depok          206   275    134    20           32        1003       113
## Kota Cimahi          36   101     24     7           13         398        33
## Kota Tasikmalaya     69   208     50    13           20         840        35
## Kota Banjar          22    82     14     3           10         199        18
##                  Cluster
## Bogor                  1
## Sukabumi               2
## Cianjur                2
## Bandung                2
## Garut                  2
## Tasikmalaya            2
## Ciamis                 3
## Kuningan               3
## Cirebon                2
## Majalengka             3
## Sumedang               3
## Indramayu              2
## Subang                 3
## Purwakarta             3
## Karawang               4
## Bekasi                 4
## Bandung Barat          3
## Pangandaran            3
## Kota Bogor             3
## Kota Sukabumi          3
## Kota Bandung           4
## Kota Cirebon           3
## Kota Bekasi            5
## Kota Depok             3
## Kota Cimahi            3
## Kota Tasikmalaya       3
## Kota Banjar            3
df <- data_with_clusters_comp
# Mengubah row names menjadi kolom "Kab/Kota"
df <- cbind("Kab/Kota" = row.names(df), df)

# Memilih semua kolom kecuali "Kab/Kota" dan kolom terakhir
kolom_dipilih <- df[, 2:(ncol(df)-1)]

# Fungsi untuk klasifikasi berdasarkan persentil
klasifikasi_persentil <- function(kolom) {
  # Menghitung persentil 25 dan 75
  persentil25 <- quantile(kolom, probs = 0.25, na.rm = TRUE)
  persentil75 <- quantile(kolom, probs = 0.75, na.rm = TRUE)
  
  # Mengklasifikasikan nilai
  cut(kolom,
      breaks = c(-Inf, persentil25, persentil75, Inf),
      labels = c("rendah", "sedang", "tinggi"),
      include.lowest = TRUE)
}

# Mengklasifikasikan semua kolom numerik yang dipilih
df_kategorisasi <- lapply(kolom_dipilih, klasifikasi_persentil)

# Menggabungkan kembali ke dataframe asli, mengganti kolom numerik yang asli dengan hasil klasifikasi
# Menyertakan kolom "Kab/Kota" dan kolom terakhir yang tidak diubah
df <- cbind(df["Kab/Kota"], df_kategorisasi, df[ncol(df)])

# Menampilkan hasil
df
##                          Kab/Kota JmlSMP  JmlSD JmlSMA  JmlRS JmlPuskesmas
## Bogor                       Bogor tinggi tinggi tinggi tinggi       tinggi
## Sukabumi                 Sukabumi tinggi tinggi tinggi sedang       tinggi
## Cianjur                   Cianjur tinggi tinggi tinggi rendah       sedang
## Bandung                   Bandung tinggi tinggi sedang sedang       tinggi
## Garut                       Garut tinggi tinggi tinggi sedang       tinggi
## Tasikmalaya           Tasikmalaya sedang tinggi sedang rendah       sedang
## Ciamis                     Ciamis sedang sedang sedang rendah       sedang
## Kuningan                 Kuningan rendah sedang rendah sedang       sedang
## Cirebon                   Cirebon sedang tinggi sedang sedang       tinggi
## Majalengka             Majalengka sedang sedang sedang rendah       sedang
## Sumedang                 Sumedang sedang sedang sedang rendah       sedang
## Indramayu               Indramayu sedang sedang sedang sedang       sedang
## Subang                     Subang sedang sedang sedang sedang       sedang
## Purwakarta             Purwakarta sedang sedang sedang sedang       rendah
## Karawang                 Karawang sedang sedang sedang tinggi       tinggi
## Bekasi                     Bekasi tinggi sedang tinggi tinggi       sedang
## Bandung Barat       Bandung Barat sedang sedang sedang sedang       sedang
## Pangandaran           Pangandaran rendah sedang rendah rendah       rendah
## Kota Bogor             Kota Bogor sedang rendah sedang tinggi       sedang
## Kota Sukabumi       Kota Sukabumi rendah rendah rendah sedang       rendah
## Kota Bandung         Kota Bandung sedang sedang sedang tinggi       tinggi
## Kota Cirebon         Kota Cirebon rendah rendah rendah sedang       rendah
## Kota Bekasi           Kota Bekasi tinggi sedang tinggi tinggi       sedang
## Kota Depok             Kota Depok sedang rendah tinggi tinggi       sedang
## Kota Cimahi           Kota Cimahi rendah rendah rendah sedang       rendah
## Kota Tasikmalaya Kota Tasikmalaya rendah rendah rendah sedang       rendah
## Kota Banjar           Kota Banjar rendah rendah rendah rendah       rendah
##                  JmlPosyandu JmlKlinik Cluster
## Bogor                 tinggi    tinggi       1
## Sukabumi              tinggi    sedang       2
## Cianjur               tinggi    rendah       2
## Bandung               tinggi    tinggi       2
## Garut                 tinggi    tinggi       2
## Tasikmalaya           sedang    sedang       2
## Ciamis                sedang    sedang       3
## Kuningan              sedang    rendah       3
## Cirebon               tinggi    sedang       2
## Majalengka            sedang    sedang       3
## Sumedang              sedang    sedang       3
## Indramayu             sedang    rendah       2
## Subang                sedang    sedang       3
## Purwakarta            sedang    sedang       3
## Karawang              sedang    tinggi       4
## Bekasi                tinggi    tinggi       4
## Bandung Barat         sedang    sedang       3
## Pangandaran           rendah    rendah       3
## Kota Bogor            rendah    sedang       3
## Kota Sukabumi         rendah    rendah       3
## Kota Bandung          sedang    tinggi       4
## Kota Cirebon          rendah    sedang       3
## Kota Bekasi           sedang    rendah       5
## Kota Depok            sedang    tinggi       3
## Kota Cimahi           rendah    sedang       3
## Kota Tasikmalaya      rendah    sedang       3
## Kota Banjar           rendah    rendah       3

Setelah itu, melihat summary klasifikasi setiap klaster.

# Mengelompokkan dataframe berdasarkan klaster
list_df_by_klaster <- split(df, df$Cluster)

# Fungsi untuk membuat summary per klaster
create_summary <- function(df) {
  # Membuat summary untuk setiap kolom kecuali 'Kab/Kota' dan 'klaster'
  summary_list <- lapply(df[,2:(ncol(df)-1)], function(kolom) {
    summary(kolom)
  })
  
  # Mengembalikan summary dalam bentuk dataframe
  summary_df <- do.call(cbind, summary_list)
  return(summary_df)
}

# Menerapkan fungsi summary ke setiap klaster
summary_per_klaster <- lapply(list_df_by_klaster, create_summary)

# Menampilkan summary untuk setiap klaster (opsional)
summary_per_klaster
## $`1`
##        JmlSMP JmlSD JmlSMA JmlRS JmlPuskesmas JmlPosyandu JmlKlinik
## rendah      0     0      0     0            0           0         0
## sedang      0     0      0     0            0           0         0
## tinggi      1     1      1     1            1           1         1
## 
## $`2`
##        JmlSMP JmlSD JmlSMA JmlRS JmlPuskesmas JmlPosyandu JmlKlinik
## rendah      0     0      0     2            0           0         2
## sedang      3     1      4     5            3           2         3
## tinggi      4     6      3     0            4           5         2
## 
## $`3`
##        JmlSMP JmlSD JmlSMA JmlRS JmlPuskesmas JmlPosyandu JmlKlinik
## rendah      7     7      7     5            7           7         4
## sedang      8     8      7     8            8           8        10
## tinggi      0     0      1     2            0           0         1
## 
## $`4`
##        JmlSMP JmlSD JmlSMA JmlRS JmlPuskesmas JmlPosyandu JmlKlinik
## rendah      0     0      0     0            0           0         0
## sedang      2     3      2     0            1           2         0
## tinggi      1     0      1     3            2           1         3
## 
## $`5`
##        JmlSMP JmlSD JmlSMA JmlRS JmlPuskesmas JmlPosyandu JmlKlinik
## rendah      0     0      0     0            0           0         1
## sedang      0     1      0     0            1           1         0
## tinggi      1     0      1     1            0           0         0

Berikut ini adalah fasilitas yang masih dibutuhkan dalam masing-masing klaster karena kategorinya masih ‘rendah’:

  • Klaster 1: Tidak ada fasilitas yang masuk kategori ‘rendah’, yang berarti semua fasilitas sudah cukup atau melebihi kebutuhan di klaster ini.

  • Klaster 2:

    • JmlRS: Masih dibutuhkan karena jumlahnya rendah.
    • JmlKlinik: Masih dibutuhkan karena jumlahnya rendah.
  • Klaster 3 (Semua fasilitas di klaster ini memiliki jumlah ‘rendah’, yang berarti semua fasilitas ini masih dibutuhkan):

    • JmlSMP
    • JmlSD
    • JmlSMA
    • JmlRS
    • JmlPuskesmas
    • JmlPosyandu
    • JmlKlinik
  • Klaster 4: Tidak ada fasilitas yang masuk kategori ‘rendah’, yang berarti semua fasilitas sudah cukup atau melebihi kebutuhan di klaster ini.

  • Klaster 5:

    • JmlKlinik: Masih dibutuhkan karena jumlahnya rendah.

Dari hasil di atas kita bisa mengetahui fasilitas apa saja yang perlu dikembangkan untuk setiap klasternya.