Analisis ini menggunakan metode K-Means Clustering untuk mengelompokkan data berdasarkan enam aspek penilaian layanan WESGO. Variabel yang digunakan adalah skor rata-rata setiap aspek, yaitu usabilitas, ketersediaan akses, keamanan berkendara, kenyamanan sepeda, kecepatan respons layanan, dan kepuasan keseluruhan.
packages <- c(
"readxl",
"dplyr",
"writexl",
"factoextra",
"cluster",
"ggplot2",
"knitr"
)
for (p in packages) {
if (!requireNamespace(p, quietly = TRUE)) {
install.packages(p)
}
}
library(readxl)
library(dplyr)
library(writexl)
library(factoextra)
library(cluster)
library(ggplot2)
library(knitr)
folder <- "D:/STATISTIKA/SEM 5/Analisis Perancangan Survey"
file_input <- file.path(folder, "wesgo_dengan_skor_aspek.xlsx")
data <- read_excel(file_input)
# Enam variabel yang digunakan dalam clustering
variabel_X <- c(
"Skor_X1_Usabilitas",
"Skor_X2_Ketersediaan_Akses",
"Skor_X3_Keamanan_Berkendara",
"Skor_X4_Kenyamanan_Sepeda",
"Skor_X5_Kecepatan_Respons",
"Skor_X6_Kepuasan_Keseluruhan"
)
# Memastikan seluruh kolom tersedia
if (!all(variabel_X %in% names(data))) {
stop("Satu atau lebih kolom skor aspek tidak ditemukan. Periksa nama kolom pada file Excel.")
}
# Memilih baris dengan enam skor aspek yang lengkap
data_analisis <- data %>%
filter(if_all(all_of(variabel_X), ~ !is.na(.x)))
X <- as.data.frame(data_analisis[, variabel_X])
cat("Jumlah baris pada file:", nrow(data), "\n")
## Jumlah baris pada file: 157
cat("Jumlah baris dengan enam skor lengkap:", nrow(data_analisis), "\n")
## Jumlah baris dengan enam skor lengkap: 157
Statistik deskriptif digunakan untuk melihat rata-rata, simpangan baku, nilai minimum, dan nilai maksimum dari setiap aspek.
deskriptif <- data.frame(
Variabel = variabel_X,
Rata_rata = sapply(X, mean),
Simpangan_Baku = sapply(X, sd),
Minimum = sapply(X, min),
Maksimum = sapply(X, max)
)
knitr::kable(
deskriptif,
digits = 3,
caption = "Statistik deskriptif enam aspek WESGO"
)
| Variabel | Rata_rata | Simpangan_Baku | Minimum | Maksimum | |
|---|---|---|---|---|---|
| Skor_X1_Usabilitas | Skor_X1_Usabilitas | 3.354 | 0.850 | 1.00 | 5 |
| Skor_X2_Ketersediaan_Akses | Skor_X2_Ketersediaan_Akses | 3.328 | 0.745 | 1.25 | 5 |
| Skor_X3_Keamanan_Berkendara | Skor_X3_Keamanan_Berkendara | 3.538 | 0.848 | 1.20 | 5 |
| Skor_X4_Kenyamanan_Sepeda | Skor_X4_Kenyamanan_Sepeda | 3.428 | 0.808 | 1.00 | 5 |
| Skor_X5_Kecepatan_Respons | Skor_X5_Kecepatan_Respons | 3.306 | 0.792 | 1.25 | 5 |
| Skor_X6_Kepuasan_Keseluruhan | Skor_X6_Kepuasan_Keseluruhan | 3.427 | 0.792 | 1.00 | 5 |
Keenam variabel distandardisasi agar perbedaan variasi antaraspek tidak mendominasi proses pengelompokan.
X_std <- scale(X)
# Pemeriksaan singkat hasil standardisasi
knitr::kable(
data.frame(
Variabel = colnames(X_std),
Rata_rata_Standar = colMeans(X_std),
SD_Standar = apply(X_std, 2, sd)
),
digits = 3,
caption = "Pemeriksaan hasil standardisasi"
)
| Variabel | Rata_rata_Standar | SD_Standar | |
|---|---|---|---|
| Skor_X1_Usabilitas | Skor_X1_Usabilitas | 0 | 1 |
| Skor_X2_Ketersediaan_Akses | Skor_X2_Ketersediaan_Akses | 0 | 1 |
| Skor_X3_Keamanan_Berkendara | Skor_X3_Keamanan_Berkendara | 0 | 1 |
| Skor_X4_Kenyamanan_Sepeda | Skor_X4_Kenyamanan_Sepeda | 0 | 1 |
| Skor_X5_Kecepatan_Respons | Skor_X5_Kecepatan_Respons | 0 | 1 |
| Skor_X6_Kepuasan_Keseluruhan | Skor_X6_Kepuasan_Keseluruhan | 0 | 1 |
Jumlah cluster dievaluasi menggunakan metode Elbow dan Silhouette. Nilai K yang dibandingkan adalah 2 sampai 8 untuk evaluasi numerik.
Metode Elbow membandingkan jumlah cluster dengan total within-cluster sum of squares (WSS). Titik siku dipertimbangkan ketika penurunan WSS mulai melandai.
set.seed(123)
grafik_elbow <- fviz_nbclust(
X_std,
FUNcluster = kmeans,
method = "wss",
k.max = 8,
nstart = 50
) +
labs(
title = "Metode Elbow - Data WESGO",
x = "Jumlah cluster (K)",
y = "Total within-cluster sum of squares"
) +
theme_minimal()
print(grafik_elbow)
Grafik Elbow untuk menentukan jumlah cluster
Nilai Silhouette digunakan untuk mengevaluasi seberapa baik suatu observasi sesuai dengan cluster-nya dibandingkan dengan cluster lain. Nilai rata-rata yang lebih tinggi menunjukkan pemisahan relatif yang lebih baik pada kandidat K yang dibandingkan.
grafik_silhouette <- fviz_nbclust(
X_std,
FUNcluster = kmeans,
method = "silhouette",
k.max = 8,
nstart = 50
) +
labs(
title = "Metode Silhouette - Data WESGO",
x = "Jumlah cluster (K)",
y = "Rata-rata silhouette width"
) +
theme_minimal()
print(grafik_silhouette)
Grafik Silhouette untuk menentukan jumlah cluster
daftar_k <- 2:8
evaluasi_k <- data.frame(
K = daftar_k,
WSS = NA_real_,
Silhouette = NA_real_
)
jarak <- dist(X_std)
for (i in seq_along(daftar_k)) {
k <- daftar_k[i]
model <- kmeans(
X_std,
centers = k,
nstart = 50,
iter.max = 100
)
evaluasi_k$WSS[i] <- model$tot.withinss
evaluasi_k$Silhouette[i] <- mean(
silhouette(model$cluster, jarak)[, 3]
)
}
knitr::kable(
evaluasi_k,
digits = 3,
caption = "Perbandingan WSS dan Silhouette untuk K = 2 sampai K = 8"
)
| K | WSS | Silhouette |
|---|---|---|
| 2 | 423.482 | 0.464 |
| 3 | 321.011 | 0.346 |
| 4 | 271.557 | 0.325 |
| 5 | 229.638 | 0.292 |
| 6 | 194.908 | 0.313 |
| 7 | 174.663 | 0.308 |
| 8 | 164.328 | 0.284 |
K_optimal <- evaluasi_k$K[which.max(evaluasi_k$Silhouette)]
cat("K dengan nilai Silhouette tertinggi:", K_optimal)
## K dengan nilai Silhouette tertinggi: 2
Berdasarkan aturan pemilihan nilai Silhouette tertinggi di antara K yang diuji, kode memilih K secara otomatis. Keputusan akhir sebaiknya tetap mempertimbangkan grafik Elbow, ukuran setiap cluster, dan kemudahan interpretasi.
Model K-Means dibangun menggunakan jumlah cluster terpilih dan 100
inisialisasi acak (nstart = 100) untuk mengurangi
ketergantungan pada satu inisialisasi.
set.seed(123)
model_kmeans <- kmeans(
X_std,
centers = K_optimal,
nstart = 100,
iter.max = 100
)
data_analisis$Cluster <- factor(model_kmeans$cluster)
cat("Jumlah cluster terpilih:", K_optimal, "\n")
## Jumlah cluster terpilih: 2
cat("Total within-cluster sum of squares:", round(model_kmeans$tot.withinss, 3), "\n")
## Total within-cluster sum of squares: 423.482
jumlah_cluster <- data_analisis %>%
count(Cluster, name = "Jumlah") %>%
mutate(
Persentase = round(Jumlah / sum(Jumlah) * 100, 2)
)
knitr::kable(
jumlah_cluster,
digits = 2,
caption = "Jumlah dan persentase data pada setiap cluster"
)
| Cluster | Jumlah | Persentase |
|---|---|---|
| 1 | 104 | 66.24 |
| 2 | 53 | 33.76 |
Rata-rata enam aspek digunakan untuk menggambarkan karakteristik setiap cluster. Label seperti “penilaian relatif tinggi” atau “penilaian relatif rendah” baru diberikan setelah profil seluruh aspek diperiksa; nomor cluster itu sendiri tidak menunjukkan tingkat kepuasan.
profil_cluster <- data_analisis %>%
group_by(Cluster) %>%
summarise(
across(all_of(variabel_X), ~ mean(.x)),
.groups = "drop"
)
knitr::kable(
profil_cluster,
digits = 3,
caption = "Rata-rata enam aspek pada setiap cluster"
)
| Cluster | Skor_X1_Usabilitas | Skor_X2_Ketersediaan_Akses | Skor_X3_Keamanan_Berkendara | Skor_X4_Kenyamanan_Sepeda | Skor_X5_Kecepatan_Respons | Skor_X6_Kepuasan_Keseluruhan |
|---|---|---|---|---|---|---|
| 1 | 3.796 | 3.666 | 3.996 | 3.875 | 3.712 | 3.880 |
| 2 | 2.486 | 2.665 | 2.638 | 2.552 | 2.509 | 2.538 |
Grafik berikut menampilkan proyeksi data ke dua dimensi untuk membantu melihat pola pemisahan. Dimensi pada grafik merupakan proyeksi dan bukan variabel aspek asli.
grafik_cluster <- fviz_cluster(
list(
data = X_std,
cluster = model_kmeans$cluster
),
geom = "point",
ellipse.type = "norm",
ggtheme = theme_minimal()
) +
labs(
title = paste("K-Means WESGO: K =", K_optimal),
subtitle = "Proyeksi dua dimensi dari enam skor aspek terstandardisasi"
)
print(grafik_cluster)
Visualisasi hasil K-Means pada dua dimensi
Hasil analisis disimpan sebagai file Excel dengan beberapa sheet: data beserta label cluster, statistik deskriptif, evaluasi jumlah cluster, jumlah anggota, dan profil cluster.
file_output <- file.path(folder, "hasil_analisis_kmeans_wesgo.xlsx")
write_xlsx(
list(
Data_Cluster = data_analisis,
Deskriptif = deskriptif,
Evaluasi_K = evaluasi_k,
Jumlah_Cluster = jumlah_cluster,
Profil_Cluster = profil_cluster
),
path = file_output
)
cat("File hasil tersimpan di:", file_output)
## File hasil tersimpan di: D:/STATISTIKA/SEM 5/Analisis Perancangan Survey/hasil_analisis_kmeans_wesgo.xlsx