Package yang diperlukan

library(MASS)
library(cluster)
library(mclust)
library(dplyr)
library(effectsize)
library(ggplot2)

Fungsi Pembangkit Data

generate_data <- function(n, sigma){

  n_per_cluster <- n / 3

  mu1 <- c(0, 0)
  mu2 <- c(5, 5)
  mu3 <- c(10, 0)

  Sigma <- matrix(
    c(sigma^2, 0,
      0, sigma^2),
    nrow = 2
  )

  cluster1 <- mvrnorm(
    n = n_per_cluster,
    mu = mu1,
    Sigma = Sigma
  )

  cluster2 <- mvrnorm(
    n = n_per_cluster,
    mu = mu2,
    Sigma = Sigma
  )

  cluster3 <- mvrnorm(
    n = n_per_cluster,
    mu = mu3,
    Sigma = Sigma
  )
  
  # Gabungkan menjadi satu dataset
  X <- rbind(
    cluster1,
    cluster2,
    cluster3
  )

  # Buat label cluster
  label_true <- c(
    rep(1, n_per_cluster),
    rep(2, n_per_cluster),
    rep(3, n_per_cluster)
  )

  # Simpan dalam fungsi list
  list(
    X = X,
    label_true = label_true
  )
}

Fungsi menghitung parameter alpha dan beta Silhoutte

compute_ab <- function(X, cluster_labels, D = NULL){

  if(is.null(D)){
    D <- as.matrix(dist(X))  # secara default menggunakan Euclidean Distance
  } else {
    D <- as.matrix(D)
  }
  
  n <- nrow(X)

  a <- numeric(n)
  b <- numeric(n)

  unique_clusters <- sort(unique(cluster_labels))

  
  for(i in 1:n){

    current_cluster <- cluster_labels[i]
    
    # Proses perhitungan parameter alpha
    same_cluster <- which(
      cluster_labels == current_cluster
    )

    same_cluster <- setdiff(
      same_cluster,
      i
    )

    if(length(same_cluster) > 0){

      a[i] <- mean(
        D[i, same_cluster]
      )

    } else {

      a[i] <- 0

    }

    # Proses perhitungan parameter beta
    other_clusters <- setdiff(
      unique_clusters,
      current_cluster
    )

    b_candidates <- c()

    for(cl in other_clusters){

      idx <- which(
        cluster_labels == cl
      )

      b_candidates <- c(
        b_candidates,
        mean(D[i, idx])
      )

    }

    b[i] <- min(b_candidates)

  }

  list(
    a = a,
    b = b
  )
}

Fungsi Setiap Replikasi Dalam Kombinasi Simulasi Tertentu

run_single_simulation <- function(
    n,
    sigma,
    k
){

  dat <- generate_data(
    n = n,
    sigma = sigma
  )

  X <- dat$X

  label_true <- dat$label_true

  km <- kmeans(
    X,
    centers = k,
    nstart = 25
  )

  label_pred <- km$cluster

  # Evaluasi ARI
  ari <- adjustedRandIndex(
    label_true,
    label_pred
  )

  # Evaluasi Silhoutte
  D <- dist(X)
  
  sil <- silhouette(
    label_pred,
    D
  )

  mean_sil <- mean(
    sil[, "sil_width"]
  )

  ab <- compute_ab(
    X,
    label_pred,
    D = D
  )

  mean_a <- mean(ab$a)

  sd_a <- sd(ab$a)

  mean_b <- mean(ab$b)

  sd_b <- sd(ab$b)

  # Buat dalam bentuk data frame
  data.frame(
    ARI = ari,
    Mean_Silhouette = mean_sil,
    Mean_a = mean_a,
    SD_a = sd_a,
    Mean_b = mean_b,
    SD_b = sd_b
  )
}

Desain Simulasi

# Ukuran sampel
sample_sizes <- c(
  45,
  180,
  450
)

# Tingkat noise
noise_levels <- c(
  0.5,
  1.5,
  3.0
)

# Jumlah klaster dalam algoritma k-means
k_values <- c(
  2,
  3,
  4
)

# Replikasi atau pengulangan
R <- 1000

Simulasi Monte Carlo

counter <- 1

# Banyaknya record dalam dataframe results
total_runs <-
  length(sample_sizes) *
  length(noise_levels) *
  length(k_values) *
  R

results_list <- vector("list", total_runs)  # alokasi sekali

for(n in sample_sizes){
  for(noise in noise_levels){
    for(k in k_values){
      for(rep in 1:R){

        temp <- run_single_simulation(n = n, sigma = noise, k = k)
        temp$n <- n
        temp$noise <- noise
        temp$k <- k
        temp$replication <- rep

        results_list[[counter]] <- temp  

        if(counter %% 100 == 0){
          cat("Progress:", counter, "/", total_runs, "\n")
        }

        counter <- counter + 1
      }
    }
  }
}
## Progress: 100 / 27000 
## Progress: 200 / 27000 
## Progress: 300 / 27000 
## Progress: 400 / 27000 
## Progress: 500 / 27000 
## Progress: 600 / 27000 
## Progress: 700 / 27000 
## Progress: 800 / 27000 
## Progress: 900 / 27000 
## Progress: 1000 / 27000 
## Progress: 1100 / 27000 
## Progress: 1200 / 27000 
## Progress: 1300 / 27000 
## Progress: 1400 / 27000 
## Progress: 1500 / 27000 
## Progress: 1600 / 27000 
## Progress: 1700 / 27000 
## Progress: 1800 / 27000 
## Progress: 1900 / 27000 
## Progress: 2000 / 27000 
## Progress: 2100 / 27000 
## Progress: 2200 / 27000 
## Progress: 2300 / 27000 
## Progress: 2400 / 27000 
## Progress: 2500 / 27000 
## Progress: 2600 / 27000 
## Progress: 2700 / 27000 
## Progress: 2800 / 27000 
## Progress: 2900 / 27000 
## Progress: 3000 / 27000 
## Progress: 3100 / 27000 
## Progress: 3200 / 27000 
## Progress: 3300 / 27000 
## Progress: 3400 / 27000 
## Progress: 3500 / 27000 
## Progress: 3600 / 27000 
## Progress: 3700 / 27000 
## Progress: 3800 / 27000 
## Progress: 3900 / 27000 
## Progress: 4000 / 27000 
## Progress: 4100 / 27000 
## Progress: 4200 / 27000 
## Progress: 4300 / 27000 
## Progress: 4400 / 27000 
## Progress: 4500 / 27000 
## Progress: 4600 / 27000 
## Progress: 4700 / 27000 
## Progress: 4800 / 27000 
## Progress: 4900 / 27000 
## Progress: 5000 / 27000 
## Progress: 5100 / 27000 
## Progress: 5200 / 27000 
## Progress: 5300 / 27000 
## Progress: 5400 / 27000 
## Progress: 5500 / 27000 
## Progress: 5600 / 27000 
## Progress: 5700 / 27000 
## Progress: 5800 / 27000 
## Progress: 5900 / 27000 
## Progress: 6000 / 27000 
## Progress: 6100 / 27000 
## Progress: 6200 / 27000 
## Progress: 6300 / 27000 
## Progress: 6400 / 27000 
## Progress: 6500 / 27000 
## Progress: 6600 / 27000 
## Progress: 6700 / 27000 
## Progress: 6800 / 27000 
## Progress: 6900 / 27000 
## Progress: 7000 / 27000 
## Progress: 7100 / 27000 
## Progress: 7200 / 27000 
## Progress: 7300 / 27000 
## Progress: 7400 / 27000 
## Progress: 7500 / 27000 
## Progress: 7600 / 27000 
## Progress: 7700 / 27000 
## Progress: 7800 / 27000 
## Progress: 7900 / 27000 
## Progress: 8000 / 27000 
## Progress: 8100 / 27000 
## Progress: 8200 / 27000 
## Progress: 8300 / 27000 
## Progress: 8400 / 27000 
## Progress: 8500 / 27000 
## Progress: 8600 / 27000 
## Progress: 8700 / 27000 
## Progress: 8800 / 27000 
## Progress: 8900 / 27000 
## Progress: 9000 / 27000 
## Progress: 9100 / 27000 
## Progress: 9200 / 27000 
## Progress: 9300 / 27000 
## Progress: 9400 / 27000 
## Progress: 9500 / 27000 
## Progress: 9600 / 27000 
## Progress: 9700 / 27000 
## Progress: 9800 / 27000 
## Progress: 9900 / 27000 
## Progress: 10000 / 27000 
## Progress: 10100 / 27000 
## Progress: 10200 / 27000 
## Progress: 10300 / 27000 
## Progress: 10400 / 27000 
## Progress: 10500 / 27000 
## Progress: 10600 / 27000 
## Progress: 10700 / 27000 
## Progress: 10800 / 27000 
## Progress: 10900 / 27000 
## Progress: 11000 / 27000 
## Progress: 11100 / 27000 
## Progress: 11200 / 27000 
## Progress: 11300 / 27000 
## Progress: 11400 / 27000 
## Progress: 11500 / 27000 
## Progress: 11600 / 27000 
## Progress: 11700 / 27000 
## Progress: 11800 / 27000 
## Progress: 11900 / 27000 
## Progress: 12000 / 27000 
## Progress: 12100 / 27000 
## Progress: 12200 / 27000 
## Progress: 12300 / 27000 
## Progress: 12400 / 27000 
## Progress: 12500 / 27000 
## Progress: 12600 / 27000 
## Progress: 12700 / 27000 
## Progress: 12800 / 27000 
## Progress: 12900 / 27000 
## Progress: 13000 / 27000 
## Progress: 13100 / 27000 
## Progress: 13200 / 27000 
## Progress: 13300 / 27000 
## Progress: 13400 / 27000 
## Progress: 13500 / 27000 
## Progress: 13600 / 27000 
## Progress: 13700 / 27000 
## Progress: 13800 / 27000 
## Progress: 13900 / 27000 
## Progress: 14000 / 27000 
## Progress: 14100 / 27000 
## Progress: 14200 / 27000 
## Progress: 14300 / 27000 
## Progress: 14400 / 27000 
## Progress: 14500 / 27000 
## Progress: 14600 / 27000 
## Progress: 14700 / 27000 
## Progress: 14800 / 27000 
## Progress: 14900 / 27000 
## Progress: 15000 / 27000 
## Progress: 15100 / 27000 
## Progress: 15200 / 27000 
## Progress: 15300 / 27000 
## Progress: 15400 / 27000 
## Progress: 15500 / 27000 
## Progress: 15600 / 27000 
## Progress: 15700 / 27000 
## Progress: 15800 / 27000 
## Progress: 15900 / 27000 
## Progress: 16000 / 27000 
## Progress: 16100 / 27000 
## Progress: 16200 / 27000 
## Progress: 16300 / 27000 
## Progress: 16400 / 27000 
## Progress: 16500 / 27000 
## Progress: 16600 / 27000 
## Progress: 16700 / 27000 
## Progress: 16800 / 27000 
## Progress: 16900 / 27000 
## Progress: 17000 / 27000 
## Progress: 17100 / 27000 
## Progress: 17200 / 27000 
## Progress: 17300 / 27000 
## Progress: 17400 / 27000 
## Progress: 17500 / 27000 
## Progress: 17600 / 27000 
## Progress: 17700 / 27000 
## Progress: 17800 / 27000 
## Progress: 17900 / 27000 
## Progress: 18000 / 27000 
## Progress: 18100 / 27000 
## Progress: 18200 / 27000 
## Progress: 18300 / 27000 
## Progress: 18400 / 27000 
## Progress: 18500 / 27000 
## Progress: 18600 / 27000 
## Progress: 18700 / 27000 
## Progress: 18800 / 27000 
## Progress: 18900 / 27000 
## Progress: 19000 / 27000 
## Progress: 19100 / 27000 
## Progress: 19200 / 27000 
## Progress: 19300 / 27000 
## Progress: 19400 / 27000 
## Progress: 19500 / 27000 
## Progress: 19600 / 27000 
## Progress: 19700 / 27000 
## Progress: 19800 / 27000 
## Progress: 19900 / 27000 
## Progress: 20000 / 27000 
## Progress: 20100 / 27000 
## Progress: 20200 / 27000 
## Progress: 20300 / 27000 
## Progress: 20400 / 27000 
## Progress: 20500 / 27000 
## Progress: 20600 / 27000 
## Progress: 20700 / 27000 
## Progress: 20800 / 27000 
## Progress: 20900 / 27000 
## Progress: 21000 / 27000 
## Progress: 21100 / 27000 
## Progress: 21200 / 27000 
## Progress: 21300 / 27000 
## Progress: 21400 / 27000 
## Progress: 21500 / 27000 
## Progress: 21600 / 27000 
## Progress: 21700 / 27000 
## Progress: 21800 / 27000 
## Progress: 21900 / 27000 
## Progress: 22000 / 27000 
## Progress: 22100 / 27000 
## Progress: 22200 / 27000 
## Progress: 22300 / 27000 
## Progress: 22400 / 27000 
## Progress: 22500 / 27000 
## Progress: 22600 / 27000 
## Progress: 22700 / 27000 
## Progress: 22800 / 27000 
## Progress: 22900 / 27000 
## Progress: 23000 / 27000 
## Progress: 23100 / 27000 
## Progress: 23200 / 27000 
## Progress: 23300 / 27000 
## Progress: 23400 / 27000 
## Progress: 23500 / 27000 
## Progress: 23600 / 27000 
## Progress: 23700 / 27000 
## Progress: 23800 / 27000 
## Progress: 23900 / 27000 
## Progress: 24000 / 27000 
## Progress: 24100 / 27000 
## Progress: 24200 / 27000 
## Progress: 24300 / 27000 
## Progress: 24400 / 27000 
## Progress: 24500 / 27000 
## Progress: 24600 / 27000 
## Progress: 24700 / 27000 
## Progress: 24800 / 27000 
## Progress: 24900 / 27000 
## Progress: 25000 / 27000 
## Progress: 25100 / 27000 
## Progress: 25200 / 27000 
## Progress: 25300 / 27000 
## Progress: 25400 / 27000 
## Progress: 25500 / 27000 
## Progress: 25600 / 27000 
## Progress: 25700 / 27000 
## Progress: 25800 / 27000 
## Progress: 25900 / 27000 
## Progress: 26000 / 27000 
## Progress: 26100 / 27000 
## Progress: 26200 / 27000 
## Progress: 26300 / 27000 
## Progress: 26400 / 27000 
## Progress: 26500 / 27000 
## Progress: 26600 / 27000 
## Progress: 26700 / 27000 
## Progress: 26800 / 27000 
## Progress: 26900 / 27000 
## Progress: 27000 / 27000
# Gabungkan setelah loop selesai
results <- do.call(rbind, results_list)  

Data Hasil Simulasi

# 5 data teratas
head(results, 5)
##    ARI Mean_Silhouette   Mean_a     SD_a   Mean_b     SD_b  n noise k
## 1 0.56       0.6347117 2.991542 1.406387 8.393465 1.277842 45   0.5 2
## 2 0.56       0.6370933 3.065425 1.460576 8.685343 1.218432 45   0.5 2
## 3 0.56       0.6474307 2.984535 1.590137 8.667263 1.146990 45   0.5 2
## 4 0.56       0.6438283 3.007406 1.519493 8.678134 1.283341 45   0.5 2
## 5 0.56       0.6520321 2.923109 1.591225 8.637578 1.236838 45   0.5 2
##   replication
## 1           1
## 2           2
## 3           3
## 4           4
## 5           5
# Lima Data Terakhir
tail(results, 5)
##             ARI Mean_Silhouette   Mean_a      SD_a   Mean_b     SD_b   n noise
## 26996 0.4625709       0.3573287 4.319339 1.0506216 7.063368 2.076418 450     3
## 26997 0.4350036       0.3450893 4.202897 1.0609528 6.686793 1.868579 450     3
## 26998 0.4555381       0.3544229 4.299147 1.1020370 6.931844 1.873224 450     3
## 26999 0.4509038       0.3597978 4.152608 1.0602755 6.761071 1.884506 450     3
## 27000 0.4261561       0.3588498 4.166830 0.9969918 6.793238 1.997229 450     3
##       k replication
## 26996 4         996
## 26997 4         997
## 26998 4         998
## 26999 4         999
## 27000 4        1000

Data Ringkasan Kombinasi

summary_results <-
  results %>%
  group_by(
    n,
    noise,
    k
  ) %>%
  summarise(
    Mean_ARI =
      mean(ARI),

    SD_ARI =
      sd(ARI),

    `Mean_mean(Silhouette)` =
      mean(Mean_Silhouette),

    `Mean_mean(a)` =
      mean(Mean_a),

    `Mean_mean(b)` =
      mean(Mean_b),

    .groups = "drop"
  )

readr::write_excel_csv(summary_results, file = "C:/Users/LENOVO/Documents/Output R/Ringkasan Kombinasi Perlakuan.csv")
summary_results
## # A tibble: 27 × 8
##        n noise     k Mean_ARI SD_ARI `Mean_mean(Silhouette)` `Mean_mean(a)`
##    <dbl> <dbl> <dbl>    <dbl>  <dbl>                   <dbl>          <dbl>
##  1    45   0.5     2    0.56  0                        0.642          3.00 
##  2    45   0.5     3    1     0                        0.873          0.885
##  3    45   0.5     4    0.877 0.0199                   0.726          0.798
##  4    45   1.5     2    0.519 0.0421                   0.511          4.18 
##  5    45   1.5     3    0.959 0.0530                   0.612          2.64 
##  6    45   1.5     4    0.821 0.0591                   0.539          2.35 
##  7    45   3       2    0.365 0.0758                   0.408          5.84 
##  8    45   3       3    0.531 0.132                    0.421          4.64 
##  9    45   3       4    0.436 0.108                    0.407          4.03 
## 10   180   0.5     2    0.569 0                        0.646          2.96 
## # ℹ 17 more rows
## # ℹ 1 more variable: `Mean_mean(b)` <dbl>

Berdasarkan ringkasan hasil simulasi, nilai rata-rata ARI berada pada rentang sekitar 0,367 hingga 1,00, sedangkan nilai double bar Silhouette berada pada rentang sekitar 0,363 hingga 0,873. Hal ini menunjukkan bahwa kualitas clustering yang dihasilkan K-Means sangat dipengaruhi oleh kondisi data dan parameter yang digunakan.

ANOVA dan Asumsinya

1. ANOVA ARI

anova_ari <- aov(
  ARI ~
    factor(n) *
    factor(noise) *
    factor(k),
  data = results
)

cat("Hasil ANOVA ARI: \n")
## Hasil ANOVA ARI:
summary(anova_ari)
##                                      Df Sum Sq Mean Sq   F value   Pr(>F)    
## factor(n)                             2    0.3     0.2 7.402e+01  < 2e-16 ***
## factor(noise)                         2  693.4   346.7 1.597e+05  < 2e-16 ***
## factor(k)                             2  573.8   286.9 1.321e+05  < 2e-16 ***
## factor(n):factor(noise)               4    0.2     0.0 2.217e+01  < 2e-16 ***
## factor(n):factor(k)                   4    0.1     0.0 7.406e+00 5.88e-06 ***
## factor(noise):factor(k)               4   77.8    19.5 8.962e+03  < 2e-16 ***
## factor(n):factor(noise):factor(k)     8    0.3     0.0 1.751e+01  < 2e-16 ***
## Residuals                         26973   58.6     0.0                       
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
cat("\n ", rep("=",80), "\n Partial eta squared: \n", sep = "")
## 
##  ================================================================================
##  Partial eta squared:
eta_squared(anova_ari, partial = TRUE)
## # Effect Size for ANOVA (Type I)
## 
## Parameter                         | Eta2 (partial) |       95% CI
## -----------------------------------------------------------------
## factor(n)                         |       5.46e-03 | [0.00, 1.00]
## factor(noise)                     |           0.92 | [0.92, 1.00]
## factor(k)                         |           0.91 | [0.91, 1.00]
## factor(n):factor(noise)           |       3.28e-03 | [0.00, 1.00]
## factor(n):factor(k)               |       1.10e-03 | [0.00, 1.00]
## factor(noise):factor(k)           |           0.57 | [0.57, 1.00]
## factor(n):factor(noise):factor(k) |       5.17e-03 | [0.00, 1.00]
## 
## - One-sided CIs: upper bound fixed at [1.00].

Hasil ANOVA menunjukkan bahwa seluruh faktor utama dan interaksi memberikan pengaruh yang signifikan secara statistik terhadap kualitas clustering (p-value < 0,05). Hal ini terjadi karena ketika jumlah record yang diuji sangat besar maka nilai \(F_{hitung}\) semakin besar dan \(F_{tabel}\) semakin kecil sehingga dapat lebih mudah untuk signifikan.

Namun demikian, berdasarkan nilai Partial Eta Squared terlihat bahwa tingkat noise dan jumlah klaster merupakan faktor yang paling dominan. Tingkat noise memiliki ukuran efek sebesar 0,92, sedangkan jumlah klaster memiliki ukuran efek sebesar 0,91. Interaksi antara tingkat noise dan jumlah klaster juga memiliki ukuran efek yang besar, yaitu 0,58.

Uji Asumsi ANOVA ARI

plot(anova_ari)

Pada plot Residual vs Fitted memperlihatkan tujuh kelompok vertikal, yang mencerminkan tujuh kombinasi nilai prediksi (fitted values) unik dari faktor-faktor yang diuji serta interaksinya. Secara umum, asumsi homogenitas ragam (homoskedastisitas) antar-perlakuan tidak terpenuhi. Hal ini ditunjukkan oleh ketidakseragaman lebar sebaran residual di setiap kombinasi perlakuan; beberapa kombinasi di bagian kiri dan tengah memiliki variabilitas yang sangat tinggi dan diperparah oleh adanya pencilan ekstrem (seperti data nomor 7869 dan 7284), sementara kombinasi perlakuan di sisi kanan memiliki variabilitas yang jauh lebih homogen dan stabil mendekati garis nol. Mengingat ini adalah analisis faktorial dengan ukuran sampel besar, pelanggaran heteroskedastisitas ini perlu diantisipasi menggunakan transformasi data atau pendekatan Robust ANOVA agar kesimpulan mengenai efek utama maupun interaksi antar-faktor tetap valid.

Pada plot Q-Q Residuals terlihat bahwa titik tidak mengikuti garis putus-putus. Hal ini menandakan bahwa residual ANOVA tidak berdistribusi normal.

2. Silhoutte

anova_sil <- aov(
  Mean_Silhouette ~
    factor(n) *
    factor(noise) *
    factor(k),
  data = results
)

cat("Hasil ANOVA Silhoutte: \n")
## Hasil ANOVA Silhoutte:
summary(anova_sil)
##                                      Df Sum Sq Mean Sq   F value   Pr(>F)    
## factor(n)                             2    1.2    0.62   1552.55  < 2e-16 ***
## factor(noise)                         2  536.0  267.98 668824.71  < 2e-16 ***
## factor(k)                             2   70.0   34.98  87298.89  < 2e-16 ***
## factor(n):factor(noise)               4    0.2    0.05    129.68  < 2e-16 ***
## factor(n):factor(k)                   4    1.0    0.24    610.25  < 2e-16 ***
## factor(noise):factor(k)               4   35.4    8.85  22081.25  < 2e-16 ***
## factor(n):factor(noise):factor(k)     8    0.0    0.00     11.26 4.77e-16 ***
## Residuals                         26973   10.8    0.00                       
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
cat("\n ", rep("=",80), "\n Partial eta squared: \n", sep = "")
## 
##  ================================================================================
##  Partial eta squared:
eta_squared(anova_sil, partial = TRUE)
## # Effect Size for ANOVA (Type I)
## 
## Parameter                         | Eta2 (partial) |       95% CI
## -----------------------------------------------------------------
## factor(n)                         |           0.10 | [0.10, 1.00]
## factor(noise)                     |           0.98 | [0.98, 1.00]
## factor(k)                         |           0.87 | [0.86, 1.00]
## factor(n):factor(noise)           |           0.02 | [0.02, 1.00]
## factor(n):factor(k)               |           0.08 | [0.08, 1.00]
## factor(noise):factor(k)           |           0.77 | [0.76, 1.00]
## factor(n):factor(noise):factor(k) |       3.33e-03 | [0.00, 1.00]
## 
## - One-sided CIs: upper bound fixed at [1.00].

Hasil ANOVA menunjukkan bahwa seluruh faktor utama dan interaksi memberikan pengaruh yang signifikan secara statistik terhadap kualitas clustering (p-value < 0,05). Hal ini terjadi karena ketika jumlah record yang diuji sangat besar maka nilai \(F_{hitung}\) semakin besar dan \(F_{tabel}\) semakin kecil sehingga dapat lebih mudah untuk signifikan.

Namun demikian, berdasarkan nilai Partial Eta Squared terlihat bahwa tingkat noise dan jumlah klaster merupakan faktor yang paling dominan. Tingkat noise memiliki ukuran efek sebesar 0,98, sedangkan jumlah klaster memiliki ukuran efek sebesar 0,87. Interaksi antara tingkat noise dan jumlah klaster juga memiliki ukuran efek yang besar, yaitu 0,77.

Uji Asumsi ANOVA Silhoutte

plot(anova_sil)

Pada plot Residuals vs Fitted terlihat bahwa tidak terlihat kehomogenan pada tingkat fitted values (nilai yang diprediksi). Beberapa fitted value ada yang memiliki range besar bahkan sampai ada outlier. Beberapa fiited value juga ada yang memiliki residual yang dekat denngan 0. Hal ini menandakan bahwa terdapat pelanggaran hoterokedastisitas.

Plot Q-Q Residual terlihat sama seperti pada ARI di mana plot cenderung tidak mengikuti garis putus-putus sehingga dapat dianggap bahwa residual tidak berdistribusi normal. Asumsi normalitas juga tidak terpenuhi.

Plot

# Mengubah tipe data beberapa variabel sehingga dapat divisualisasikan
results <- results %>%
  mutate(
    n = factor(n),
    noise = factor(noise),
    k = factor(k)
  )

Box-plot dan lince chart pengaruh ukuran sampel terhadap ARI dan Silhoutte

Boxplot

  1. ARI
ggplot(results,
       aes(x = n,
           y = ARI)) +
  geom_boxplot() +
  labs(
    x = "Ukuran Sampel",
    y = "ARI",
    title = "Distribusi ARI Berdasarkan Ukuran Sampel"
  ) +
  theme_classic() +
  theme(plot.title = element_text(hjust = 0.5, face = 'bold'))

ggsave("C:/Users/LENOVO/Documents/Output R/1.png", width = 8, height = 6, dpi = 300)

Berdasarkan boxplot di atas, distribusi nilai ARI pada ketiga ukuran sampel berbeda. Semakin tinggi ukuran sampel, distribusi ARI semakin sempit. Hal ini ditandai dengan meningkatnya nilai minimum, \(Q_1\), median seiring meningkatnya ukuran sampel.

  1. Silhoutte
ggplot(results,
       aes(x = n,
           y = Mean_Silhouette)) +
  geom_boxplot() +
  labs(
    x = "Ukuran Sampel",
    y = expression(bar(Silhouette)),
    title = "Distribusi Mean Silhouette Berdasarkan Ukuran Sampel"
  ) +
  theme_classic() +
  theme(plot.title = element_text(hjust = 0.5, face = 'bold'))

ggsave("C:/Users/LENOVO/Documents/Output R/2.png", width = 8, height = 6, dpi = 300)

Berdasarkan boxplot di atas, distribusi nilai \(\overline{Silhoutte}\) pada ketiga ukuran sampel berbeda. Seiring bertambahnya ukuran sampel, nilai minimum \(\overline{Silhoutte}\) semakin naik. Namun menariknya adalah seiring bertambahnya ukuran sampel, nilai \(Q_1\) dan median menurun. Hal ini menandakan bahwa walaupun nilai minimum semakin meningkat, \(\overline{Silhoutte}\) kecil yang dihasilkan juga semakin banyak. Tidak ada outlier pada box-plot ARI ataupun \(\overline{Silhoutte}\) sehingga dapat dianggap bahwa tidak ada nilai yang berbeda secara ekstrem pada nilai yang dihasilkan.

Line Chart

  1. ARI
results %>%
  group_by(n) %>%
  summarise(
    Mean_ARI = mean(ARI)
  ) %>%
  ggplot(
    aes(
      x = n,
      y = Mean_ARI,
      group = 1
    )
  ) +
  geom_line() +
  geom_point(size = 3) +
  labs(
    x = "Ukuran Sampel",
    y = expression(bar(ARI)),
    title = "Rata-rata ARI Berdasarkan Ukuran Sampel"
  ) +
  theme_classic() +
  theme(plot.title = element_text(hjust = 0.5, face = 'bold'))

ggsave("C:/Users/LENOVO/Documents/Output R/3.png", width = 8, height = 6, dpi = 300)

Berdasarkan gambar di atas terjadi peningkatan nilai rata-rata ARI seiring bertambahnya ukuran sampel. Nilai rata-rata ARI meningkat dari sekitar 0,674 pada ukuran sampel 45 menjadi sekitar 0,681 pada ukuran sampel 180 dan 450.

  1. Silhouette
results %>%
  group_by(n) %>%
  summarise(
    Mean_mean_Silhoutte = mean(Mean_Silhouette)
  ) %>%
  ggplot(
    aes(
      x = n,
      y = Mean_mean_Silhoutte,
      group = 1
    )
  ) +
  geom_line() +
  geom_point(size = 3) +
  labs(
    x = "Ukuran Sampel",
    y = expression(bar(bar(Silhouette))),
    title = expression(bold(paste(bar(bar(Silhouette))," Berdasarkan Ukuran Sampel")))
  ) +
  theme_classic() +
  theme(plot.title = element_text(hjust = 0.5))

ggsave("C:/Users/LENOVO/Documents/Output R/4.png", width = 8, height = 6, dpi = 300)

Berbeda dari nilai \(\overline{ARI}\), Nilai \(\overline{\overline{Silhoutte}}\) justru mengalami penurunan dari sekitar 0,571 pada ukuran sampel 45 menjadi sekitar 0,555 pada ukuran sampel 450. Namun penurunan tersebut relatif kecil.

# Tabel Ringkasan
results %>%
  group_by(n) %>%
  summarise(
    Mean_mean_a = mean(Mean_a),
    Mean_mean_b = mean(Mean_b)
  )
## # A tibble: 3 × 3
##   n     Mean_mean_a Mean_mean_b
##   <fct>       <dbl>       <dbl>
## 1 45           3.15        7.55
## 2 180          3.18        7.50
## 3 450          3.20        7.48

Dari tabel di atas terlihat bahwa nilai Nilai \(\bar{\bar{a}}\) semakin menurun seiring bertambahnya ukuran sampel. Hal ini menandakan bahwa seiring bertambahnya ukuran sampel, jarak intra-cluster semakin meningkat atau kondisi dalam klaster yang dihasilkan semakin heterogen. Namun, semakin bertambahnya ukuran sampel justru nilai \(\bar{\bar{b}}\) semakin menurun. Hal ini menandakan bahwa seiring bertambahnya ukuran sampel, jarak nearest-cluster semakin menurun atau anggota antar klaster yang dihasilkan semakin mirip (semakin homogen).

Box-plot dan line chart pengaruh tingkat noise terhadap ARI dan Silhoutte

Box-plot

  1. Ari
ggplot(results,
       aes(x = noise,
           y = ARI)) +
  geom_boxplot() +
  labs(
    x = "Tingkat Noise",
    y = "ARI",
    title = "Distribusi ARI Berdasarkan Tingkat Noise"
  ) +
  theme_classic() +
  theme(plot.title = element_text(hjust = 0.5, face = 'bold'))

ggsave("C:/Users/LENOVO/Documents/Output R/5.png", width = 8, height = 6, dpi = 300)

Hasil boxplot menunjukkan adanya penurunan kualitas clustering yang sangat jelas ketika tingkat noise meningkat. Pada boxplot ARI, semakin bertambahnya tingkat noise data maka nilai ARI yang didapatkan semakin bervariasi. Hal ini terlihat bahwa pada tingkat noise 0,5, nilai ARI yang dihasilkan berada pada \(Q_1\) sampai \(Q_3\). Kemudian nilai ARI semakin menyebar bahkan sampai ada outlier dan menurun.

  1. Silhoutte
ggplot(results,
       aes(x = noise,
           y = Mean_Silhouette)) +
  geom_boxplot() +
  labs(
    x = "Tingkat Noise",
    y = expression(bar(Silhouette)),
    title = "Distribusi Mean Silhouette Berdasarkan Tingkat Noise"
  ) +
  theme_classic() +
  theme(plot.title = element_text(hjust = 0.5, face = 'bold'))

ggsave("C:/Users/LENOVO/Documents/Output R/6.png", width = 8, height = 6, dpi = 300)

Boxplot \(\overline{Silhoutte}\) juga menunjukkan bahwa semakin meningkatnya tingkat noise, nilai \(\overline{Silhoutte}\) yang dihasilkan juga menurun dan semakin menyebar. Pada box-plot \(\overline{Silhoutte}\), perbedaan range akibat tingkat noise lebih terlihat.

Line Chart

  1. Ari
results %>%
  group_by(noise) %>%
  summarise(
    Mean_ARI = mean(ARI)
  ) %>%
  ggplot(
    aes(
      x = noise,
      y = Mean_ARI,
      group = 1
    )
  ) +
  geom_line() +
  geom_point(size = 3) +
  labs(
    x = "Tingkat Noise",
    y = expression(bar(ARI)),
    title = "Rata-rata ARI Berdasarkan Tingkat Noise"
  ) +
  theme_classic() +
  theme(plot.title = element_text(hjust = 0.5, face = 'bold'))

ggsave("C:/Users/LENOVO/Documents/Output R/7.png", width = 8, height = 6, dpi = 300)

Berbeda dari pengaruh ukuran sampel, pengaruh tingkat noise terhadap \(\overline{ARI}\) menurun. Pada noise 0,5 diperoleh rata-rata ARI sekitar 0,81. Nilai tersebut sedikit menurun menjadi sekitar 0,77 pada noise 1,5 dan turun drastis menjadi sekitar 0,45 pada noise 3.

  1. Silhoutte
results %>%
  group_by(noise) %>%
  summarise(
    Mean_mean_Silhoutte = mean(Mean_Silhouette)
  ) %>%
  ggplot(
    aes(
      x = noise,
      y = Mean_mean_Silhoutte,
      group = 1
    )
  ) +
  geom_line() +
  geom_point(size = 3) +
  labs(
    x = "Tingkat Noise",
    y = expression(bar(bar(Silhouette))),
    title = expression(bold(paste(bar(bar(Silhouette))," Berdasarkan Tingkat Noise")))
  ) +
  theme_classic() +
  theme(plot.title = element_text(hjust = 0.5))

ggsave("C:/Users/LENOVO/Documents/Output R/8.png", width = 8, height = 6, dpi = 300)

Pola serupa juga terlihat pada \(\overline{\overline{Silhoutte}}\). Nilai \(\overline{\overline{Silhoutte}}\) menurun dari sekitar 0,75 pada noise 0,5 menjadi sekitar 0,55 pada noise 1,5 dan sekitar 0,40 pada noise 3. Penurunan nilai \(\overline{\overline{Silhoutte}}\) pada noise 3 tidak se-drastis pada nilai \(\overline{ARI}\).

# Tabel Ringkasan
results %>%
  group_by(noise) %>%
  summarise(
    Mean_mean_a = mean(Mean_a),
    Mean_mean_b = mean(Mean_b)
  )
## # A tibble: 3 × 3
##   noise Mean_mean_a Mean_mean_b
##   <fct>       <dbl>       <dbl>
## 1 0.5          1.56        6.85
## 2 1.5          3.08        7.18
## 3 3            4.90        8.50

Berdasarkan tabel di atas terlihat bahwa semakin besar tingkat noise data, nilai \(\bar{\bar{a}}\) dan \(\bar{\bar{b}}\) semakin meningkat. Hal ini menandakan bahwa semakin besar tingkat noise, jarak intra-cluster ataupun nearest-cluster semakin besar (semakin heterogen). Perubahan nilai \(\bar{\bar{a}}\) dan \(\bar{\bar{b}}\) juga lebih terlihat daripada pengaruh ukuran sampel.

Secara konseptual, peningkatan noise menyebabkan penyebaran data di sekitar centroid semakin besar. Akibatnya terjadi peningkatan overlap antar klaster sehingga objek dari klaster yang berbeda menjadi semakin sulit dibedakan. Kondisi ini menyebabkan kemampuan K-Means dalam mengidentifikasi struktur sebenarnya menurun sehingga ARI dan Silhouette mengalami penurunan.

Box-plot dan lince chart pengaruh jumlah klaster pada algoritma K-Means terhadap ARI dan Silhoutte

Box-plot

  1. ARI
ggplot(results,
       aes(x = k,
           y = ARI)) +
  geom_boxplot() +
  labs(
    x = "Jumlah Klaster",
    y = "ARI",
    title = "Distribusi ARI Berdasarkan Jumlah Klaster Algoritma K-Means"
  ) +
  theme_classic() +
  theme(plot.title = element_text(hjust = 0.5, face = 'bold'))

ggsave("C:/Users/LENOVO/Documents/Output R/9.png", width = 8, height = 6, dpi = 300)
  1. silhoutte
ggplot(results,
       aes(x = k,
           y = Mean_Silhouette)) +
  geom_boxplot() +
  labs(
    x = "Jumlah Klaster",
    y = expression(bar(Silhouette)),
    title = "Distribusi Mean Silhouette Berdasarkan Jumlah Klaster Algoritma K-means"
  ) +
  theme_classic() +
  theme(plot.title = element_text(hjust = 0.5, face = 'bold'))

ggsave("C:/Users/LENOVO/Documents/Output R/10.png", width = 8, height = 6, dpi = 300)

Dari dua boxplot sebelumnya tidak terlihat adanya pengaruh akibat semakin tingginya jumlah klaster yang digunakan. Karena pada simulasi ini dibangkitkan data simulasi dengan jumlah klaster 3 maka klaster 3 menjadi acuan. Jumlah klaster di bawah klaster 3 (klaster 2) memiliki nilai IQR ARI dan \(\overline{Silhoutte}\) yang lebih sempit daripada jumlah klaster di atasnya. Hal ini menandakan bahwa nilai ARI dan \(\overline{Silhoutte}\) pada jumlah klaster di bawah klaster acuan lebih padat (tidak se-variasi) pada jumlah klaster di atas klaster acuan.

Line Chart

  1. ARI
results %>%
  group_by(k) %>%
  summarise(
    Mean_ARI = mean(ARI)
  ) %>%
  ggplot(
    aes(
      x = k,
      y = Mean_ARI,
      group = 1
    )
  ) +
  geom_line() +
  geom_point(size = 3) +
  labs(
    x = "Jumlah Klaster",
    y = expression(bar(ARI)),
    title = "Rata-rata ARI Berdasarkan Jumlah Klaster Algoritma K-Means"
  ) +
  theme_classic() +
  theme(plot.title = element_text(hjust = 0.5, face = 'bold'))

ggsave("C:/Users/LENOVO/Documents/Output R/11.png", width = 8, height = 6, dpi = 300)

Hasil simulasi menunjukkan bahwa nilai \(\overline{ARI}\) tertinggi diperoleh ketika jumlah klaster yang digunakan sama dengan jumlah klaster sebenarnya, yaitu k = 3. Rata-rata ARI pada k = 2 hanya sekitar 0,49, meningkat menjadi sekitar 0,84 pada k = 3, kemudian menurun menjadi sekitar 0,71 pada k = 4.

  1. silhoutte
results %>%
  group_by(k) %>%
  summarise(
    Mean_mean_Silhoutte = mean(Mean_Silhouette)
  ) %>%
  ggplot(
    aes(
      x = k,
      y = Mean_mean_Silhoutte,
      group = 1
    )
  ) +
  geom_line() +
  geom_point(size = 3) +
  labs(
    x = "Jumlah Klaster",
    y = expression(bar(bar(Silhouette))),
    title = expression(bold(paste(bar(bar(Silhouette))," Berdasarkan Jumlah Klaster Algoritma K-Means")))
  ) +
  theme_classic() +
  theme(plot.title = element_text(hjust = 0.5))

ggsave("C:/Users/LENOVO/Documents/Output R/12.png", width = 8, height = 6, dpi = 300)

Pola yang sama terlihat pada nilai Silhouette. Nilai \(\overline{\overline{Silhouette}}\) tertinggi diperoleh pada k = 3 dengan nilai sekitar 0,63, sedangkan pada k = 2 dan k = 4 hanya sekitar 0,52 hingga 0,54. Nilai evaluasi yang dihasilkan pada jumlah klaster di bawah klaster sebenarnya lebih kecil daripada jumlah klaster di bawah klaster di atasnya.

# Tabel Ringkasan
results %>%
  group_by(k) %>%
  summarise(
    Mean_mean_a = mean(Mean_a),
    Mean_mean_b = mean(Mean_b)
  )
## # A tibble: 3 × 3
##   k     Mean_mean_a Mean_mean_b
##   <fct>       <dbl>       <dbl>
## 1 2            4.35        9.20
## 2 3            2.73        7.50
## 3 4            2.45        5.83

Nilai \(\bar{\bar{a}}\) ataupun \(\bar{\bar{b}}\) pada jumlah klaster 2 lebih kecil daripada jumlah klaster 4. Hal ini menandakan bahwa pada jumlah klaster di bawah jumlah klaster sebenarnya, anggota klaster di dalamnya lebih homogen dan antar klaster juga lebih homogen daripada jumlah klaster di atas jumlah klaster sebenarnya.

Temuan ini sesuai dengan prinsip dasar K-Means bahwa kualitas clustering terbaik akan diperoleh ketika jumlah klaster yang digunakan sesuai dengan struktur sebenarnya pada data. Ketika k terlalu kecil, beberapa klaster akan digabung sehingga meningkatkan heterogenitas dalam klaster. Sebaliknya, ketika k terlalu besar, satu klaster dapat terpecah menjadi beberapa klaster yang lebih kecil sehingga struktur data menjadi kurang representatif.

Box-plot dan lince chart pengaruh interaksi antara ukuran sampel dan tingkat noise terhadap ARI dan Silhoutte

Box-plot

  1. ARI
ggplot(results,
       aes(x = n,
           y = ARI,
           fill = noise)) +
  geom_boxplot() +
  labs(
    x = "Ukuran Sampel",
    y = "ARI",
    title = "Distribusi ARI Berdasarkan Ukuran Sampel dan Tingkat Noise"
  ) +
  theme_classic() +
  theme(plot.title = element_text(hjust = 0.5, face = 'bold'))

ggsave("C:/Users/LENOVO/Documents/Output R/13.png", width = 8, height = 6, dpi = 300)

Berdasarkan box-plot di atas terlihat bahwa pada tingkat noise kecil (0,5), range pada nilai ARI tidak menurun seiring bertambahnya ukuran sampel.

  1. Silhoutte
ggplot(results,
       aes(x = n,
           y = Mean_Silhouette,
           fill = noise)) +
  geom_boxplot() +
  labs(
    x = "Ukuran Sampel",
    y = expression(bar(Silhouette)),
    title = "Distribusi Mean Silhouette Berdasarkan Ukuran Sampel dan Tingkat Noise"
  ) +
  theme_classic() +
  theme(plot.title = element_text(hjust = 0.5, face = 'bold'))

ggsave("C:/Users/LENOVO/Documents/Output R/14.png", width = 8, height = 6, dpi = 300)

Hal ini juga terlihat pada nilai \(\overline{Silhoutte}\) pada noise 0,5 bahwa variasi nilai \(\overline{Silhoutte}\) lebih stabil (tidak seperti pada noise lainnya) seiring bertambahnya ukuran sampel. Hal ini menandakan bahwa pada tingkat noise kecil, variasi evaluasi lebih stabil seiring bertambahnya ukuran sampel.

Line Chart

  1. ARI
results %>%
  group_by(n, noise) %>%
  summarise(
    Mean_ARI = mean(ARI)
  ) %>%
  ggplot(
    aes(
      x = n,
      y = Mean_ARI,
      group = noise,
      colour = noise
    )
  ) +
  geom_line() +
  geom_point(size = 3) +
  labs(
    x = "Ukuran Sampel",
    y = expression(bar(ARI)),
    title = "Rata-rata ARI Berdasarkan Interaksi Ukuran Sampel dan Tingkat Noise"
  ) +
  theme_classic() +
  theme(plot.title = element_text(hjust = 0.5, face = 'bold'))

ggsave("C:/Users/LENOVO/Documents/Output R/15.png", width = 8, height = 6, dpi = 300)
  1. Silhoutte
results %>%
  group_by(n, noise) %>%
  summarise(
    Mean_mean_Silhoutte = mean(Mean_Silhouette)
  ) %>%
  ggplot(
    aes(
      x = n,
      y = Mean_mean_Silhoutte,
      group = noise,
      colour = noise
    )
  ) +
  geom_line() +
  geom_point(size = 3) +
  labs(
    x = "Ukuran Sampel",
    y = expression(bar(bar(Silhouette))),
    title = expression(bold(paste(bar(bar(Silhouette))," Interaksi Ukuran Sampel dan Tingkat Noise")))
  ) +
  theme_classic() +
  theme(plot.title = element_text(hjust = 0.5))

ggsave("C:/Users/LENOVO/Documents/Output R/16.png", width = 8, height = 6, dpi = 300)

Berdasarkan interaction plot, garis antar ukuran sampel pada masing-masing tingkat noise cenderung hampir sejajar. Hal ini menunjukkan bahwa pengaruh ukuran sampel terhadap ARI dan Silhouette relatif konsisten pada setiap tingkat noise.

Pada \(\overline{ARI}\), tingkat noise 3 sangat berbeda daripada noise 0 ataupun 0,5. Namun, pada \(\overline{\overline{Silhoutte}}\), tingkat noise 3 tidak jauh berbeda daripada noise 0 ataupun 0,5. Temuan ini menunjukkan bahwa perubahan kualitas clustering (khususnya ARI) lebih banyak dipengaruhi oleh noise dibandingkan ukuran sampel.

# Tabel Ringkasan
results %>%
  group_by(n, noise) %>%
  summarise(
    Mean_mean_a = mean(Mean_a),
    Mean_mean_b = mean(Mean_b),
    .groups = 'drop'
  )
## # A tibble: 9 × 4
##   n     noise Mean_mean_a Mean_mean_b
##   <fct> <fct>       <dbl>       <dbl>
## 1 45    0.5          1.56        6.87
## 2 45    1.5          3.06        7.21
## 3 45    3            4.84        8.58
## 4 180   0.5          1.55        6.85
## 5 180   1.5          3.08        7.17
## 6 180   3            4.92        8.47
## 7 450   0.5          1.55        6.85
## 8 450   1.5          3.09        7.15
## 9 450   3            4.94        8.44

Box-plot dan lince chart pengaruh interaksi antara tingkat noise dan jumlah klaster pada algoritma K-Means terhadap ARI dan Silhoutte

Box-plot

  1. ARI
ggplot(results,
       aes(x = noise,
           y = ARI,
           fill = k)) +
  geom_boxplot() +
  labs(
    x = "Tingkat Noise",
    y = "ARI",
    title = "Distribusi ARI Berdasarkan Tingkat Noise dan Jumlah Klaster K-Means"
  ) +
  theme_classic() +
  theme(plot.title = element_text(hjust = 0.5, face = 'bold'))

ggsave("C:/Users/LENOVO/Documents/Output R/17.png", width = 8, height = 6, dpi = 300)
  1. Silhoutte
ggplot(results,
       aes(x = noise,
           y = Mean_Silhouette,
           fill = k)) +
  geom_boxplot() +
  labs(
    x = "Tingkat Noise",
    y = expression(bar(Silhouette)),
    title = "Distribusi Mean Silhoutte Berdasarkan Tingkat Noise dan Jumlah Klaster"
  ) +
  theme_classic() +
  theme(plot.title = element_text(hjust = 0.5, face = 'bold'))

ggsave("C:/Users/LENOVO/Documents/Output R/18.png", width = 8, height = 6, dpi = 300)

Pada dua Box-plot sebelumnya terlihat bahwa tidak ada interaksi yang menyebabkan distribusi nilai evaluasi berbeda pada kombinasi antara tingkat noise dan jumlah klaster tertentu.

Line Chart

  1. ARI
results %>%
  group_by(noise, k) %>%
  summarise(
    Mean_ARI = mean(ARI)
  ) %>%
  ggplot(
    aes(
      x = noise,
      y = Mean_ARI,
      group = k,
      colour = k
    )
  ) +
  geom_line() +
  geom_point(size = 3) +
  labs(
    x = "Tingkat Noise",
    y = expression(bar(ARI)),
    title = "Rata-rata ARI Berdasarkan Interaksi Tingkat Noise dan Jumlah Klaster"
  ) +
  theme_classic() +
  theme(plot.title = element_text(hjust = 0.5, face = 'bold'))

ggsave("C:/Users/LENOVO/Documents/Output R/19.png", width = 8, height = 6, dpi = 300)

Interaksi antara tingkat noise dan jumlah klaster menunjukkan pola yang paling menarik. Pada kondisi noise rendah (0,5), penggunaan k = 3 menghasilkan \(\overline{ARI}\) hampir sempurna dengan nilai mendekati 1. Namun ketika noise meningkat menjadi 3, nilai $ pada k = 3 turun hingga sekitar 0,56. Penurunan juga terjadi pada k = 2 dan k = 4, tetapi dengan tingkat yang berbeda. Hal ini menghasilkan garis interaksi yang tidak sejajar.

  1. Silhoutte
results %>%
  group_by(noise, k) %>%
  summarise(
    Mean_mean_Silhoutte = mean(Mean_Silhouette)
  ) %>%
  ggplot(
    aes(
      x = noise,
      y = Mean_mean_Silhoutte,
      group = k,
      colour = k
    )
  ) +
  geom_line() +
  geom_point(size = 3) +
  labs(
    x = "Tingkat Noise",
    y = expression(bar(bar(Silhouette))),
    title = expression(bold(paste(bar(bar(Silhouette))," Interaksi Tingkat Noise dan Jumlah Klaster K-Means")))
  ) +
  theme_classic() +
  theme(plot.title = element_text(hjust = 0.5))

ggsave("C:/Users/LENOVO/Documents/Output R/20.png", width = 8, height = 6, dpi = 300)

Fenomena yang sama terlihat pada nilai \(\overline{\overline{Silhouette}}\). Ketika noise rendah, perbedaan kualitas antara k = 2, k = 3, dan k = 4 sangat jelas. Namun ketika noise tinggi, seluruh nilai \(\overline{\overline{Silhouette}}\) menurun dan perbedaannya menjadi lebih kecil. Pada jumlah klaster 2 dan dan tingkat noise 3, nilai \(\overline{\overline{Silhouette}}\) menjadi terbaik setelah jumlah klaster 3. Hal ini menandakan bahwa pengaruh jumlah klaster terhadap kualitas clustering sangat bergantung pada tingkat noise yang terdapat pada data.

# Tabel Ringkasan
results %>%
  group_by(noise, k) %>%
  summarise(
    Mean_mean_a = mean(Mean_a),
    Mean_mean_b = mean(Mean_b),
    .groups = 'drop'
  )
## # A tibble: 9 × 4
##   noise k     Mean_mean_a Mean_mean_b
##   <fct> <fct>       <dbl>       <dbl>
## 1 0.5   2           2.97         8.59
## 2 0.5   3           0.885        7.01
## 3 0.5   4           0.810        4.96
## 4 1.5   2           4.20         8.85
## 5 1.5   3           2.64         7.14
## 6 1.5   4           2.40         5.55
## 7 3     2           5.87        10.2 
## 8 3     3           4.68         8.35
## 9 3     4           4.14         6.99

Box-plot dan lince chart pengaruh interaksi antara ukuran sampel dan jumlah klaster pada algoritma K-Means terhadap ARI dan Silhoutte

Box-Plot

  1. ARI
ggplot(results,
       aes(x = n,
           y = ARI,
           fill = k)) +
  geom_boxplot() +
  labs(
    x = "Ukuran Sampel",
    y = "ARI",
    title = "Distribusi ARI Berdasarkan Ukuran Sampel dan Jumlah Klaster K-Means"
  ) +
  theme_classic() +
  theme(plot.title = element_text(hjust = 0.5, face = 'bold'))

ggsave("C:/Users/LENOVO/Documents/Output R/21.png", width = 8, height = 6, dpi = 300)
  1. Silhoutte
ggplot(results,
       aes(x = n,
           y = Mean_Silhouette,
           fill = k)) +
  geom_boxplot() +
  labs(
    x = "Ukuran Sampel",
    y = expression(bar(Silhouette)),
    title = "Distribusi Mean Silhouette Berdasarkan Ukuran Sampel dan Jumlah Klaster"
  ) +
  theme_classic() +
  theme(plot.title = element_text(hjust = 0.5, face = 'bold'))

ggsave("C:/Users/LENOVO/Documents/Output R/22.png", width = 8, height = 6, dpi = 300)

Sama seperti pada boxplot interaksi antara tingkat noise dan jumlah klaster, tidak ada interaksi yang menyebabkan distribusi nilai evaluasi berbeda pada kombinasi antara ukuran sampel dan jumlah klaster tertentu.

Line Chart

  1. ARI
results %>%
  group_by(n, k) %>%
  summarise(
    Mean_ARI = mean(ARI)
  ) %>%
  ggplot(
    aes(
      x = n,
      y = Mean_ARI,
      group = k,
      colour = k
    )
  ) +
  geom_line() +
  geom_point(size = 3) +
  labs(
    x = "Ukuran Sampel",
    y = expression(bar(ARI)),
    title = "Rata-rata ARI Berdasarkan Interaksi Ukuran Sampel dan Jumlah Klaster"
  ) +
  theme_classic() +
  theme(plot.title = element_text(hjust = 0.5, face = 'bold'))

ggsave("C:/Users/LENOVO/Documents/Output R/23.png", width = 8, height = 6, dpi = 300)

Interaction plot menunjukkan bahwa pengaruh jumlah klaster terhadap kualitas clustering relatif konsisten pada seluruh ukuran sampel. Pada semua ukuran sampel, nilai ARI tertinggi selalu diperoleh pada k = 3. Demikian pula pada nilai Silhouette, k = 3 secara konsisten menghasilkan kualitas clustering terbaik.

  1. Silhoutte
results %>%
  group_by(n, k) %>%
  summarise(
    Mean_mean_Silhoutte = mean(Mean_Silhouette)
  ) %>%
  ggplot(
    aes(
      x = n,
      y = Mean_mean_Silhoutte,
      group = k,
      colour = k
    )
  ) +
  geom_line() +
  geom_point(size = 3) +
  labs(
    x = "Ukuran Sampel",
    y = expression(bar(bar(Silhouette))),
    title = expression(bold(paste(bar(bar(Silhouette))," Interaksi Ukuran Sampel dan Jumlah Klaster K-Means")))
  ) +
  theme_classic() +
  theme(plot.title = element_text(hjust = 0.5))

ggsave("C:/Users/LENOVO/Documents/Output R/24.png", width = 8, height = 6, dpi = 300)
# Tabel Ringkasan
results %>%
  group_by(n, k) %>%
  summarise(
    Mean_mean_a = mean(Mean_a),
    Mean_mean_b = mean(Mean_b),
    .groups = 'drop'
  )
## # A tibble: 9 × 4
##   n     k     Mean_mean_a Mean_mean_b
##   <fct> <fct>       <dbl>       <dbl>
## 1 45    2            4.34        9.26
## 2 45    3            2.72        7.51
## 3 45    4            2.39        5.89
## 4 180   2            4.34        9.18
## 5 180   3            2.74        7.49
## 6 180   4            2.47        5.82
## 7 450   2            4.35        9.16
## 8 450   3            2.74        7.49
## 9 450   4            2.49        5.79

Pada nilai \(\overline{ARI}\) dan \(\overline{\overline{Silhoutte}}\) terlihat garis yang dihasilkan sejajar atau tidak berpotongan sehingga dapat dianggap bahwa tidak ada pengaruh interaksi antara ukuran sampel dan jumlah klaster yang digunakan. Namun, nilai \(\overline{\overline{Silhoutte}}\) sangat berbeda pada jumlah klaster yang digunakan. Hal ini menandakan bahwa pengaruh ukuran sampel terhadap kualitas clustering sangat bergantung pada jumlah klaster yang digunakan.

Box-plot dan lince chart pengaruh interaksi antara ukuran sampel, noise, dan jumlah klaster pada algoritma K-Means terhadap ARI dan Silhoutte

Box-Plot

  1. ARI
ggplot(results,
       aes(x = n, 
           y = ARI, 
           fill = k)) +      
  geom_boxplot(outlier.size = 1, alpha = 0.8) +
  # Memisahkan panel berdasarkan tingkat Noise
  facet_wrap(~ noise, labeller = label_both) + 
  labs(
    x = "Ukuran Sampel (n)",
    y = "ARI",
    fill = "Jumlah Klaster (k)",
    title = "Distribusi ARI berdasarkan Ukuran Sampel, Tingkat Noise, dan Jumlah Klaster"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(hjust = 0.5, face = 'bold', size = 12),
    strip.text = element_text(face = 'bold', size = 10), 
    legend.position = "bottom" 
  )

ggsave("C:/Users/LENOVO/Documents/Output R/25.png", width = 8, height = 6, dpi = 300)
  1. Silhoutte
ggplot(results,
       aes(x = n, 
           y = Mean_Silhouette, 
           fill = k)) +      
  geom_boxplot(outlier.size = 1, alpha = 0.8) +
  # Memisahkan panel berdasarkan tingkat Noise
  facet_wrap(~ noise, labeller = label_both) + 
  labs(
    x = "Ukuran Sampel (n)",
    y = expression(bar(bar(Silhouette))),
    fill = "Jumlah Klaster (k)",
    title = expression(bold(paste("Distribusi ", bar(bar(Silhouette)), " berdasarkan Ukuran Sampel, Tingkat Noise, dan Jumlah Klaster")))
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(hjust = 0.5, face = 'bold', size = 12),
    strip.text = element_text(face = 'bold', size = 10), 
    legend.position = "bottom" 
  )

ggsave("C:/Users/LENOVO/Documents/Output R/26.png", width = 8, height = 6, dpi = 300)

Line Chart

  1. ARI
results %>%
  group_by(n, noise, k) %>%
  summarise(
    Mean_ARI = mean(ARI),
    .groups = "drop"
  ) %>%

  ggplot(
    aes(
      x = n,
      y = Mean_ARI,
      group = k,
      color = k
    )
  ) +
  geom_line(linewidth = 1) +
  geom_point(size = 3) +
  # Memisahkan grafik berdasarkan tingkat Noise
  facet_wrap(~ noise, labeller = label_both) + 
  labs(
    x = "Ukuran Sampel (n)",
    y = expression(bar(ARI)),
    color = "Jumlah Klaster (k)",
    title = expression(bold(paste("Interaksi n, Noise, dan Jumlah Klaster terhadap ", bar(ARI))))
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(hjust = 0.5, face = 'bold', size = 12),
    strip.text = element_text(face = 'bold', size = 10) # Menebalkan judul panel noise
  )

ggsave("C:/Users/LENOVO/Documents/Output R/27.png", width = 8, height = 6, dpi = 300)
  1. Silhoutte
results %>%
  group_by(n, noise, k) %>%
  summarise(
    Mean_Sil = mean(Mean_Silhouette),
    .groups = "drop"
  ) %>%

  ggplot(
    aes(
      x = n,
      y = Mean_Sil,
      group = k,
      color = k
    )
  ) +
  geom_line(linewidth = 1) +
  geom_point(size = 3) +
  # Memisahkan grafik berdasarkan tingkat Noise
  facet_wrap(~ noise, labeller = label_both) + 
  labs(
    x = "Ukuran Sampel (n)",
    y = expression(bar(bar(Silhouette))),
    color = "Jumlah Klaster (k)",
    title = expression(bold(paste("Interaksi n, Noise, dan Jumlah Klaster terhadap ", bar(bar(Silhouette)))))
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(hjust = 0.5, face = 'bold', size = 12),
    strip.text = element_text(face = 'bold', size = 10) # Menebalkan judul panel noise
  )

ggsave("C:/Users/LENOVO/Documents/Output R/28.png", width = 8, height = 6, dpi = 300)
# Tabel Ringkasan
results %>%
  group_by(n, noise, k) %>%
  summarise(
    Mean_mean_a = mean(Mean_a),
    Mean_mean_b = mean(Mean_b),
    .groups = 'drop'
  )
## # A tibble: 27 × 5
##    n     noise k     Mean_mean_a Mean_mean_b
##    <fct> <fct> <fct>       <dbl>       <dbl>
##  1 45    0.5   2           3.00         8.61
##  2 45    0.5   3           0.885        7.01
##  3 45    0.5   4           0.798        4.97
##  4 45    1.5   2           4.18         8.91
##  5 45    1.5   3           2.64         7.13
##  6 45    1.5   4           2.35         5.60
##  7 45    3     2           5.84        10.2 
##  8 45    3     3           4.64         8.40
##  9 45    3     4           4.03         7.08
## 10 180   0.5   2           2.96         8.59
## # ℹ 17 more rows