PENERAPAN METODE K-MEANS DALAM PENGELOMPOKAN PUSKESMAS DI KABUPATEN KENDAL BERDASARKAN INDIKATOR STATUS GIZI BALITA DAN KETERSEDIAAN LAYANAN KEBIDANAN
Pembangunan kesehatan merupakan prioritas nasional yang berdampak langsung pada kualitas sumber daya manusia dan produktivitas ekonomi. Namun, permasalahan gizi balita seperti stunting, wasting, dan underweight masih menjadi tantangan besar yang memerlukan penanganan strategis melalui Puskesmas sebagai fasilitas kesehatan tingkat pertama. Di Kabupaten Kendal, keragaman karakteristik wilayah memicu variasi kondisi gizi balita dan ketersediaan layanan kesehatan, sehingga diperlukan pemetaan yang akurat. Penggunaan metode K-Means clustering dalam penelitian ini bertujuan untuk mengelompokkan Puskesmas berdasarkan kemiripan karakteristik tersebut guna mendukung pengambilan kebijakan dan penentuan prioritas intervensi yang lebih tepat sasaran.
Status Gizi Balita
Status gizi balita merupakan indikator penting kesehatan masyarakat yang memengaruhi perkembangan fisik, kognitif, dan daya tahan tubuh anak, sehingga pemantauannya dilakukan secara komprehensif melalui tiga indikator antropometri utama menurut WHO, yaitu stunting, wasting, dan underweight.
Stunting : kondisi gagal tumbuh pada balita yang ditandai dengan panjang atau tinggi badan menurut umur berada di bawah standar yang ditetapkan.
Wasting : kondisi balita dengan berat badan menurut tinggi badan yang rendah, yang menunjukkan adanya kekurangan gizi akut.
Underweight : kondisi berat badan menurut umur yang berada di bawah standar. Indikator ini mencerminkan kombinasi antara kekurangan gizi kronis dan akut.
Ketersediaan Tenaga Kebidanan
Tenaga kebidanan merupakan bagian penting dalam pelayanan kesehatan ibu dan anak yang memiliki kompetensi memberikan pelayanan sejak masa kehamilan, persalinan, nifas, hingga pemantauan tumbuh kembang anak. Ketersediaan dan pemerataan tenaga kebidanan berperan dalam meningkatkan kualitas pelayanan kesehatan, menurunkan angka kematian ibu dan bayi, serta mendukung pencegahan dan penanganan masalah gizi balita melalui edukasi gizi, pemantauan pertumbuhan, dan deteksi dini masalah gizi.
library(readxl)
## Warning: package 'readxl' was built under R version 4.3.3
data <- read_excel("D:/DATA STATUS GIZI DAN LAYANAN KEBIDANAN.xlsx")
data
## # A tibble: 30 × 5
## Puskesmas Stunting Wasting Underweight Tenaga
## <chr> <dbl> <dbl> <dbl> <dbl>
## 1 Plantungan 8.47 4.11 7.8 19
## 2 Sukorejo 01 18.5 5.61 11.6 22
## 3 Sukorejo 02 9.39 4.02 6.6 17
## 4 Pageruyung 6.56 3.94 7.8 20
## 5 Patean 12.5 7.04 12.7 24
## 6 Singorojo 01 12.4 8.08 12.8 22
## 7 Singorojo 02 7.34 7.98 9.6 17
## 8 Limbangan 13.2 9.37 10.9 24
## 9 Boja 01 4.69 6.01 5.3 29
## 10 Boja 02 12.4 9.03 11.6 20
## # ℹ 20 more rows
summary(data)
## Puskesmas Stunting Wasting Underweight
## Length:30 Min. : 4.690 Min. : 3.320 Min. : 3.40
## Class :character 1st Qu.: 8.283 1st Qu.: 7.275 1st Qu.:10.93
## Mode :character Median :11.215 Median :10.395 Median :11.85
## Mean :11.546 Mean : 9.086 Mean :11.44
## 3rd Qu.:13.540 3rd Qu.:11.068 3rd Qu.:13.40
## Max. :18.810 Max. :13.050 Max. :15.30
## Tenaga
## Min. :10.00
## 1st Qu.:17.00
## Median :19.50
## Mean :20.27
## 3rd Qu.:23.75
## Max. :34.00
Berdasarkan statistik deskriptif, rata-rata persentase stunting sebesar 11,55%, wasting 9,08%, dan underweight 11,44% dengan variasi yang berbeda antar puskesmas. Nilai minimum dan maksimum masing-masing variabel menunjukkan adanya perbedaan kondisi gizi balita di setiap wilayah. Sementara itu, jumlah tenaga kebidanan memiliki rata-rata 20,27 orang dengan rentang 10–34 orang, yang menunjukkan adanya perbedaan ketersediaan tenaga kebidanan antar puskesmas.
# Membuat Boxplot untuk variabel numerik (kolom 2 sampai 5)
boxplot(data[, 2:5],
main = "Deteksi Outlier Menggunakan Boxplot",
col = "orange",
border = "brown")
Berdasarkan boxplot, variabel stunting, wasting, dan tenaga kebidanan tidak menunjukkan pencilan yang signifikan. Namun, pada variabel underweight terdapat beberapa data di bawah lower whisker yang menunjukkan adanya puskesmas dengan persentase underweight jauh lebih rendah dibandingkan wilayah lainnya di Kabupaten Kendal.
# Pilih hanya kolom numerik (Stunting s/d Tenaga)
kolom_numerik <- data[, 2:5]
# Loop untuk mengecek setiap variabel satu per satu
for (col in names(kolom_numerik)) {
# Hitung batas outlier
nilai <- data[[col]]
outlier_values <- boxplot.stats(nilai)$out
# Jika ditemukan outlier, tampilkan datanya
if (length(outlier_values) > 0) {
cat("\n--------------------------------------\n")
cat("Outlier ditemukan pada variabel:", col, "\n")
cat("Nilai Outlier:", paste(outlier_values, collapse = ", "), "\n")
# Menampilkan baris data yang mengandung outlier tersebut
print(data[data[[col]] %in% outlier_values, c("Puskesmas", col)])
}
}
##
## --------------------------------------
## Outlier ditemukan pada variabel: Underweight
## Nilai Outlier: 6.6, 5.3, 3.4
## # A tibble: 3 × 2
## Puskesmas Underweight
## <chr> <dbl>
## 1 Sukorejo 02 6.6
## 2 Boja 01 5.3
## 3 Kaliwungu 3.4
Meskipun secara statistik tergolong pencilan, data tersebut tetap dipertahankan karena merupakan data riil dan bukan kesalahan pencatatan. Nilai underweight yang rendah mencerminkan keberhasilan penanganan gizi di wilayah tersebut, sehingga tetap digunakan agar hasil K-Means clustering dapat menggambarkan variasi kondisi kesehatan secara lebih akurat.
Uji Kaiser–Meyer–Olkin (KMO) digunakan untuk menilai apakah sampel yang digunakan sudah mewakili populasi. Namun, apabila data yang dianalisis mencakup seluruh populasi, maka pengujian ini tidak diperlukan karena tidak ada proses generalisasi dari sampel ke populasi.
\[ KMO = \frac{\sum_{i=1}^{p} \sum_{j=1}^{p} r_{ij}^{2}} {\sum_{i=1}^{p} \sum_{j=1}^{p} r_{ij}^{2} + \sum_{i=1}^{p} \sum_{j=1}^{p} a_{ij}^{2}} \]
Dengan:
\(p\) : banyaknya variabel
\(r_{ij}\) : koefisien korelasi
terobservasi antara variabel ke-\(i\)
dan ke-\(j\)
\(a_{ij}\) : koefisien korelasi parsial antara variabel ke-\(i\) dan ke-\(j\)
Dikarenakan data yang digunakan adalah data seluruh puskesmas di Kabupaten Kendal, maka data tersebut berupa populasi sehingga tidak perlu diuji KMO.
Menurut Gujarati (1978), multikolinearitas merupakan kondisi adanya hubungan linear yang kuat atau sempurna di antara dua atau lebih variabel independen. Kondisi ini dapat dideteksi menggunakan nilai Variance Inflation Factor (VIF), di mana multikolinearitas dianggap terjadi apabila nilai VIF lebih dari 10.
\[ VIF_j = \frac{1}{1 - R_j^2} \]
Keterangan:
\(VIF_j\) : nilai Variance
Inflation Factor pada variabel ke-\(j\)
\(R_j^2\) : koefisien determinasi dari regresi variabel ke-\(j\) terhadap variabel bebas lainnya
Puskesmas <- data$Puskesmas
X1 <- data$Stunting
X2 <- data$Wasting
X3 <- data$Underweight
X4 <- data$Tenaga
predictors <- c("X1", "X2", "X3", "X4")
df_data <- data.frame(X1, X2, X3, X4)
vif_results <- data.frame(
Variable = character(),
R_Squared = numeric(),
VIF_Value = numeric(),
stringsAsFactors = FALSE
)
for (i in seq_along(predictors)) {
y_var <- predictors[i]
x_vars <- predictors[-i]
formula_reg <- as.formula(paste(y_var, "~", paste(x_vars, collapse = " + ")))
model <- lm(formula_reg, data = df_data)
r_sq <- summary(model)$r.squared
vif_val <- 1 / (1 - r_sq)
vif_results[i, ] <- c(y_var, r_sq, vif_val)
}
vif_results$R_Squared <- as.numeric(vif_results$R_Squared)
vif_results$VIF_Value <- as.numeric(vif_results$VIF_Value)
print(vif_results)
## Variable R_Squared VIF_Value
## 1 X1 0.4161803 1.712858
## 2 X2 0.6570037 2.915483
## 3 X3 0.7508973 4.014408
## 4 X4 0.1129287 1.127305
Berdasarkan hasil perhitungan VIF, seluruh variabel memiliki nilai kurang dari 10 sehingga tidak terdeteksi multikolinearitas. Dengan demikian, semua variabel dinyatakan valid dan dapat digunakan dalam analisis selanjutnya.
Data yang digunakan dalam penelitian ini memiliki satuan yang berbeda setiap variabelnya. Sehingga, perlu dilakukan standarisasi agar skala variabel sama, menambah akurasi dalam perhitungan jarak, serta mencegah klasterisasi yang tidak akurat
Standarisasi data dengan metode Z-score dilakukan untuk mengubah data agar memiliki rata-rata 0 dan standar deviasi 1. Proses ini bertujuan menyamakan skala antar variabel sehingga perbedaan satuan tidak memengaruhi hasil analisis.
\[ Z_{ij} = \frac{X_{ij} - \bar{X}_j}{s_j} \]
Keterangan:
\(Z_{ij}\) : nilai hasil standardisasi pada observasi ke-\(i\) dan variabel ke-\(j\)
\(X_{ij}\) : nilai asli data pada observasi ke-\(i\) dan variabel ke-\(j\)
\(\bar{X}_j\) : nilai rata-rata dari variabel ke-\(j\)
\(s_j\) : simpangan baku dari variabel ke-\(j\)
data_select <- data[, 2:5]
data_scaled <- scale(data_select)
row.names(data_scaled) <- data$Puskesmas
print(data_scaled)
## Stunting Wasting Underweight Tenaga
## Plantungan -0.765294692 -1.75720572 -1.28113622 -0.20972291
## Sukorejo 01 1.729852916 -1.22746593 0.05509003 0.28698924
## Sukorejo 02 -0.536427713 -1.78899010 -1.70310240 -0.54086435
## Pageruyung -1.240442442 -1.81724289 -1.28113622 -0.04415219
## Patean 0.247192922 -0.72244734 0.44189236 0.61813068
## Singorojo 01 0.224803761 -0.35516109 0.47705621 0.28698924
## Singorojo 02 -1.046403046 -0.39047708 -0.64818694 -0.54086435
## Limbangan 0.406404733 0.10041512 -0.19105691 0.61813068
## Boja 01 -1.705639453 -1.08620199 -2.16023244 1.44598427
## Boja 02 0.212365338 -0.01965923 0.05509003 -0.04415219
## Kaliwungu -1.364826669 -2.03620200 -2.82834556 1.77712571
## Kaliwungu Selatan -0.068743017 0.68666048 -0.36687615 -0.04415219
## Brangsong 01 1.020862818 0.85264561 0.33640082 -1.36871794
## Brangsong 02 -0.969284825 1.07866792 0.30123697 -0.37529363
## Pegandon 0.199926915 0.54892813 0.75836700 2.27383786
## Ngampel -0.969284825 0.70078687 0.23090927 1.11484284
## Gemuh 01 -0.242880935 0.45710657 0.44189236 -0.37529363
## Gemuh 02 1.070616509 0.51714375 0.82869470 -0.54086435
## Ringinarum -0.096107547 1.40004338 1.35615243 0.45255996
## Weleri 01 -0.404580431 0.78907683 -0.05040152 -1.03757650
## Weleri 02 -0.827486806 -0.18917596 -0.15589306 -0.54086435
## Rowosari 01 -0.553841505 1.10338911 1.14516934 -0.37529363
## Rowosari 02 1.806971137 -0.92728006 -0.05040152 -0.70643506
## Kangkung 01 1.782094292 -0.14679678 1.00451394 -0.70643506
## Kangkung 02 1.744779024 0.79614003 1.07484164 -1.69985937
## Cepiring -0.332437579 1.24818465 0.30123697 1.94269643
## Patebon 01 0.008375205 0.69725527 0.05509003 -1.36871794
## Patebon 02 1.117882516 0.46770137 0.89902240 0.12141853
## Kendal 01 0.525813592 0.52420694 -0.12072921 0.78370140
## Kendal 02 -0.974260194 0.49595416 1.07484164 -1.20314722
## attr(,"scaled:center")
## Stunting Wasting Underweight Tenaga
## 11.546333 9.085667 11.443333 20.266667
## attr(,"scaled:scale")
## Stunting Wasting Underweight Tenaga
## 4.019802 2.831579 2.843830 6.039715
Davies–Bouldin Index (DBI) merupakan metode evaluasi internal pada analisis cluster yang digunakan untuk menilai kualitas hasil pengelompokan berdasarkan kedekatan data dalam cluster dan pemisahan antar cluster.
Langkah-langkah Davies-Bouldin Index (DBI)
Menghitung jarak Rata-rata dalam cluster
\[ S_k = \frac{1}{n_k}\sum_{i=1}^{n_k} d(x_i,\mu_k) \]
Keterangan:
\(S_k\) : jarak rata-rata dalam cluster ke-\(k\)
\(n_k\) : jumlah data dalam cluster ke-\(k\)
\(x_i\) : data ke-\(i\) dalam cluster ke-\(k\)
\(\mu_k\) : pusat centroid cluster ke-\(k\)
\(d(x_i,\mu_k)\) : jarak euclidean antara data ke-\(i\) dan centroid
Jarak antar centroid cluster
\[ M_{kj} = d(\mu_k,\mu_j) \]
Keterangan:
\(M_{kj}\) : jarak antar centroid cluster ke-\(k\) dan ke-\(j\)
\(\mu_k\) : vektor pusat (centroid) cluster ke-\(k\)
\(\mu_j\) : vektor pusat (centroid) cluster ke-\(j\)
Rasio antar cluster
\[ R_{kj} = \frac{S_k + S_j}{M_{kj}} \]
Keterangan:
\(R_{kj}\) : rasio cluster ke-\(k\) dan cluster ke-\(j\)
\(S_k\) : rata-rata jarak di dalam cluster ke-\(k\)
\(S_j\) : rata-rata jarak di dalam cluster ke-\(j\)
\(M_{kj}\) : jarak antara centroid cluster ke-\(k\) (\(\mu_k\)) dan centroid cluster ke-\(j\) (\(\mu_j\))
Nilai maksimum rasio tiap cluster\[ D_k = \max_{j \ne k} (R_{kj}) \]
Keterangan:
\(D_k\) : nilai rasio maksimal dari cluster ke-\(k\) dengan cluster lain (\(j\))
\(R_{kj}\) : rasio cluster ke-\(k\) dan cluster ke-\(j\)
Nilai Davies-Bouldin Index
\[ DBI = \frac{1}{K} \sum_{k=1}^{K} D_k \]
Keterangan:
\(D_k\) : nilai rasio maksimal dari cluster ke-\(k\) dengan cluster lain (\(j\))
\(K\) : jumlah cluster yang terbentuk
# Fungsi untuk menghitung Davies-Bouldin Index sesuai langkah di gambar
hitung_DBI_manual <- function(data, hasil_kmeans) {
# Persiapan Data
k <- nrow(hasil_kmeans$centers)
centroids <- hasil_kmeans$centers
cluster_labels <- hasil_kmeans$cluster
# --- LANGKAH 1: Hitung Intra-Cluster Distance (Si) ---
# Mengukur kepadatan dalam satu klaster (Average distance to centroid)
#
S <- numeric(k)
for (i in 1:k) {
# Ambil data milik klaster i
data_i <- data[cluster_labels == i, , drop = FALSE]
if(nrow(data_i) > 0) {
# Hitung jarak setiap titik ke centroid-nya
distances <- sqrt(rowSums((t(t(data_i) - centroids[i, ]))^2))
# Hitung rata-ratanya (1/ni * Sigma)
S[i] <- mean(distances)
} else {
S[i] <- 0
}
}
# --- LANGKAH 2: Hitung Inter-Cluster Distance (Mij) ---
# Mengukur jarak antar pusat klaster (Centroid Distance)
#
M <- as.matrix(dist(centroids))
# --- LANGKAH 3: Hitung Rasio Kemiripan (Rij) ---
# Rumus: (Si + Sj) / Mij
#
R <- matrix(0, nrow = k, ncol = k)
for (i in 1:k) {
for (j in 1:k) {
if (i != j) {
R[i, j] <- (S[i] + S[j]) / M[i, j]
}
}
}
# --- LANGKAH 4: Ambil Nilai Maksimum Rasio Tiap Klaster (Ri) ---
# Cari "musuh" terdekat atau rasio terburuk untuk setiap klaster
#
R_max <- apply(R, 1, max)
# --- LANGKAH 5: Hitung Rata-Rata Keseluruhan (DBI) ---
# Rumus: 1/k * Sigma(Ri)
#
DBI <- mean(R_max)
return(DBI)
}
# Kita akan coba uji dari 2 klaster sampai 5 klaster
k_range <- 2:5
nilai_dbi <- c()
# Looping pengujian
for (k in k_range) {
set.seed(123) # Kunci agar hasil konsisten
# 1. Lakukan K-Means
km_model <- kmeans(data_scaled, centers = k, nstart = 25)
# 2. Hitung DBI pakai rumus manual tadi
dbi_score <- hitung_DBI_manual(data_scaled, km_model)
# 3. Simpan hasil
nilai_dbi <- c(nilai_dbi, dbi_score)
}
# Gabungkan hasil dalam tabel
hasil_dbi <- data.frame(Jumlah_Klaster = k_range, Nilai_DBI = nilai_dbi)
print("=== HASIL AKHIR DAVIES-BOULDIN INDEX ===")
## [1] "=== HASIL AKHIR DAVIES-BOULDIN INDEX ==="
print(hasil_dbi)
## Jumlah_Klaster Nilai_DBI
## 1 2 0.8736294
## 2 3 1.0693266
## 3 4 1.0308101
## 4 5 0.9293725
Berdasarkan hasil perhitungan DBI, nilai terkecil diperoleh pada k = 2. Karena nilai DBI yang lebih kecil menunjukkan kualitas pengelompokan yang lebih baik, maka jumlah cluster optimal adalah 2.
library(factoextra)
## Warning: package 'factoextra' was built under R version 4.3.3
## Loading required package: ggplot2
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
kmeans_data = kmeans(data_scaled, centers = 2)
fviz_cluster(kmeans_data, data = data_scaled)
Penetapan Profil (Profiling)
Adapun kriteria yang digunakan dalam menginterpretasikan profil Cluster adalah sebagai berikut:
Cluster dengan rata-rata variabel rendah maka dikategorikan sebagai kelompok puskesmas dengan status gizi balita dan ketersediaan layanan kebidanan yang sedikit.
Cluster dengan rata-rata variabel tinggi maka dikategorikan sebagai kelompok puskesmas dengan status gizi balita dan ketersediaan layanan kebidanan yang banyak.
# Menggabungkan hasil cluster
hasil_kmeans = data.frame(data$Puskesmas, data_scaled, kmeans_data$cluster)
hasil_kmeans[order(hasil_kmeans$kmeans_data.cluster),]
## data.Puskesmas Stunting Wasting Underweight
## Plantungan Plantungan -0.765294692 -1.75720572 -1.28113622
## Sukorejo 02 Sukorejo 02 -0.536427713 -1.78899010 -1.70310240
## Pageruyung Pageruyung -1.240442442 -1.81724289 -1.28113622
## Singorojo 02 Singorojo 02 -1.046403046 -0.39047708 -0.64818694
## Boja 01 Boja 01 -1.705639453 -1.08620199 -2.16023244
## Kaliwungu Kaliwungu -1.364826669 -2.03620200 -2.82834556
## Sukorejo 01 Sukorejo 01 1.729852916 -1.22746593 0.05509003
## Patean Patean 0.247192922 -0.72244734 0.44189236
## Singorojo 01 Singorojo 01 0.224803761 -0.35516109 0.47705621
## Limbangan Limbangan 0.406404733 0.10041512 -0.19105691
## Boja 02 Boja 02 0.212365338 -0.01965923 0.05509003
## Kaliwungu Selatan Kaliwungu Selatan -0.068743017 0.68666048 -0.36687615
## Brangsong 01 Brangsong 01 1.020862818 0.85264561 0.33640082
## Brangsong 02 Brangsong 02 -0.969284825 1.07866792 0.30123697
## Pegandon Pegandon 0.199926915 0.54892813 0.75836700
## Ngampel Ngampel -0.969284825 0.70078687 0.23090927
## Gemuh 01 Gemuh 01 -0.242880935 0.45710657 0.44189236
## Gemuh 02 Gemuh 02 1.070616509 0.51714375 0.82869470
## Ringinarum Ringinarum -0.096107547 1.40004338 1.35615243
## Weleri 01 Weleri 01 -0.404580431 0.78907683 -0.05040152
## Weleri 02 Weleri 02 -0.827486806 -0.18917596 -0.15589306
## Rowosari 01 Rowosari 01 -0.553841505 1.10338911 1.14516934
## Rowosari 02 Rowosari 02 1.806971137 -0.92728006 -0.05040152
## Kangkung 01 Kangkung 01 1.782094292 -0.14679678 1.00451394
## Kangkung 02 Kangkung 02 1.744779024 0.79614003 1.07484164
## Cepiring Cepiring -0.332437579 1.24818465 0.30123697
## Patebon 01 Patebon 01 0.008375205 0.69725527 0.05509003
## Patebon 02 Patebon 02 1.117882516 0.46770137 0.89902240
## Kendal 01 Kendal 01 0.525813592 0.52420694 -0.12072921
## Kendal 02 Kendal 02 -0.974260194 0.49595416 1.07484164
## Tenaga kmeans_data.cluster
## Plantungan -0.20972291 1
## Sukorejo 02 -0.54086435 1
## Pageruyung -0.04415219 1
## Singorojo 02 -0.54086435 1
## Boja 01 1.44598427 1
## Kaliwungu 1.77712571 1
## Sukorejo 01 0.28698924 2
## Patean 0.61813068 2
## Singorojo 01 0.28698924 2
## Limbangan 0.61813068 2
## Boja 02 -0.04415219 2
## Kaliwungu Selatan -0.04415219 2
## Brangsong 01 -1.36871794 2
## Brangsong 02 -0.37529363 2
## Pegandon 2.27383786 2
## Ngampel 1.11484284 2
## Gemuh 01 -0.37529363 2
## Gemuh 02 -0.54086435 2
## Ringinarum 0.45255996 2
## Weleri 01 -1.03757650 2
## Weleri 02 -0.54086435 2
## Rowosari 01 -0.37529363 2
## Rowosari 02 -0.70643506 2
## Kangkung 01 -0.70643506 2
## Kangkung 02 -1.69985937 2
## Cepiring 1.94269643 2
## Patebon 01 -1.36871794 2
## Patebon 02 0.12141853 2
## Kendal 01 0.78370140 2
## Kendal 02 -1.20314722 2
\[ d(x_i,\mu_k) = \sqrt{\sum_{j=1}^{p} (x_{ij} - \mu_{k(j)})^2} \]
dimana:
\(d(x_i,\mu_k)\) : jarak antara \(x_i\) dan \(\mu_k\)
\(x_{ij}\) : data pada objek ke-\(i\) pada variabel ke-\(j\)
\(\mu_{k(j)}\) : pusat cluster ke-\(k\) pada variabel ke-\(j\)
\(p\) : banyaknya variabel yang diukur
data_final <- data_scaled
cluster_assignments <- kmeans_data$cluster
centroids <- kmeans_data$centers
# Rumus hitung jarak per baris (Sesuai syntax Anda)
jarak_ke_centroid <- sapply(1:nrow(data_final), function(i) {
sqrt(sum((data_final[i, ] - centroids[cluster_assignments[i], ])^2))
})
# Masukkan ke tabel hasil
hasil_kmeans$Jarak_Centroid <- jarak_ke_centroid
hasil_kmeans[order(hasil_kmeans$kmeans_data.cluster),]
## data.Puskesmas Stunting Wasting Underweight
## Plantungan Plantungan -0.765294692 -1.75720572 -1.28113622
## Sukorejo 02 Sukorejo 02 -0.536427713 -1.78899010 -1.70310240
## Pageruyung Pageruyung -1.240442442 -1.81724289 -1.28113622
## Singorojo 02 Singorojo 02 -1.046403046 -0.39047708 -0.64818694
## Boja 01 Boja 01 -1.705639453 -1.08620199 -2.16023244
## Kaliwungu Kaliwungu -1.364826669 -2.03620200 -2.82834556
## Sukorejo 01 Sukorejo 01 1.729852916 -1.22746593 0.05509003
## Patean Patean 0.247192922 -0.72244734 0.44189236
## Singorojo 01 Singorojo 01 0.224803761 -0.35516109 0.47705621
## Limbangan Limbangan 0.406404733 0.10041512 -0.19105691
## Boja 02 Boja 02 0.212365338 -0.01965923 0.05509003
## Kaliwungu Selatan Kaliwungu Selatan -0.068743017 0.68666048 -0.36687615
## Brangsong 01 Brangsong 01 1.020862818 0.85264561 0.33640082
## Brangsong 02 Brangsong 02 -0.969284825 1.07866792 0.30123697
## Pegandon Pegandon 0.199926915 0.54892813 0.75836700
## Ngampel Ngampel -0.969284825 0.70078687 0.23090927
## Gemuh 01 Gemuh 01 -0.242880935 0.45710657 0.44189236
## Gemuh 02 Gemuh 02 1.070616509 0.51714375 0.82869470
## Ringinarum Ringinarum -0.096107547 1.40004338 1.35615243
## Weleri 01 Weleri 01 -0.404580431 0.78907683 -0.05040152
## Weleri 02 Weleri 02 -0.827486806 -0.18917596 -0.15589306
## Rowosari 01 Rowosari 01 -0.553841505 1.10338911 1.14516934
## Rowosari 02 Rowosari 02 1.806971137 -0.92728006 -0.05040152
## Kangkung 01 Kangkung 01 1.782094292 -0.14679678 1.00451394
## Kangkung 02 Kangkung 02 1.744779024 0.79614003 1.07484164
## Cepiring Cepiring -0.332437579 1.24818465 0.30123697
## Patebon 01 Patebon 01 0.008375205 0.69725527 0.05509003
## Patebon 02 Patebon 02 1.117882516 0.46770137 0.89902240
## Kendal 01 Kendal 01 0.525813592 0.52420694 -0.12072921
## Kendal 02 Kendal 02 -0.974260194 0.49595416 1.07484164
## Tenaga kmeans_data.cluster Jarak_Centroid
## Plantungan -0.20972291 1 0.7791765
## Sukorejo 02 -0.54086435 1 1.0766752
## Pageruyung -0.04415219 1 0.6294599
## Singorojo 02 -0.54086435 1 1.7105218
## Boja 01 1.44598427 1 1.4316464
## Kaliwungu 1.77712571 1 1.9752841
## Sukorejo 01 0.28698924 2 2.2186366
## Patean 0.61813068 2 1.2962943
## Singorojo 01 0.28698924 2 0.8162439
## Limbangan 0.61813068 2 0.9690751
## Boja 02 -0.04415219 2 0.5338048
## Kaliwungu Selatan -0.04415219 2 0.9104852
## Brangsong 01 -1.36871794 2 1.5671098
## Brangsong 02 -0.37529363 2 1.4687405
## Pegandon 2.27383786 2 2.3857545
## Ngampel 1.11484284 2 1.7667249
## Gemuh 01 -0.37529363 2 0.6059927
## Gemuh 02 -0.54086435 2 1.0186185
## Ringinarum 0.45255996 2 1.5405679
## Weleri 01 -1.03757650 2 1.3322315
## Weleri 02 -0.54086435 2 1.4388297
## Rowosari 01 -0.37529363 2 1.3615505
## Rowosari 02 -0.70643506 2 2.1518416
## Kangkung 01 -0.70643506 2 1.8097899
## Kangkung 02 -1.69985937 2 2.3241477
## Cepiring 1.94269643 2 2.2894710
## Patebon 01 -1.36871794 2 1.4041702
## Patebon 02 0.12141853 2 0.9962576
## Kendal 01 0.78370140 2 1.0552622
## Kendal 02 -1.20314722 2 1.8126740
\[ \mu_{k(j)} = \frac{1}{N_k}\sum_{i=1}^{N_k} x_{ij}, \quad j = 1,2,\ldots,p \]
Keterangan:
\(\mu_{k(j)}\) : pusat cluster ke-\(k\) pada variabel ke-\(j\)
\(N_k\) : jumlah data dalam cluster ke-\(k\)
\(x_{ij}\) : nilai data pada objek ke-\(i\) pada variabel ke-\(j\)
# Mengambil centroid hasil K-Means
centroids <- kmeans_data$centers
# Menghitung jarak antar centroid
jarak_centroid <- dist(centroids)
# Menampilkan hasil
jarak_centroid
## 1
## 2 3.123241
Berdasarkan hasil perhitungan, jarak centroid antara Cluster 1 dan Cluster 2 sebesar 3,123241. Nilai ini menunjukkan adanya perbedaan karakteristik yang cukup jelas antar cluster, sehingga hasil pengelompokan K-Means mampu memisahkan data dengan baik.
Profiling cluster merupakan tahap untuk menggambarkan karakteristik dari setiap cluster yang terbentuk. Proses ini dilakukan dengan menganalisis statistik deskriptif pada masing-masing variabel dalam setiap cluster, seperti nilai rata-rata. Hasil perbandingan antar cluster digunakan untuk mengidentifikasi variabel yang paling membedakan karakteristik setiap cluster sehingga memudahkan interpretasi terhadap pola yang terbentuk.
\[ \bar{x}_{kj} = \frac{1}{n_k}\sum_{i=1}^{n_k} x_{ij} \]
dimana:
\(\bar{x}_{kj}\) : nilai rata-rata variabel ke-\(j\) pada cluster ke-\(k\)
\(n_k\) : jumlah objek atau anggota pada cluster ke-\(k\)
\(x_{ij}\) : nilai variabel ke-\(j\) pada objek ke-\(i\) dalam cluster ke-\(k\)
data <- data[complete.cases(data), ]
k2 <- kmeans(data_scaled, centers = 2, nstart = 25)
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.3.3
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
# Menghitung rata-rata karakteristik tiap klaster
mean.klaster <- data %>%
mutate(Klaster = k2$cluster) %>%
group_by(Klaster) %>%
summarise(
Mean_Stunting = mean(Stunting),
Mean_Wasting = mean(Wasting),
Mean_Underweight = mean(Underweight),
Mean_Tenaga = mean(Tenaga)
) %>%
mutate(
Total_Mean = Mean_Stunting + Mean_Wasting + Mean_Underweight + Mean_Tenaga
) %>%
arrange(Klaster)
# Tampilkan hasil
mean.klaster
## # A tibble: 2 × 6
## Klaster Mean_Stunting Mean_Wasting Mean_Underweight Mean_Tenaga Total_Mean
## <int> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1 7.08 4.90 6.75 22.2 40.9
## 2 2 12.7 10.1 12.6 19.8 55.2
Profiling Cluster