Seberapa Penting Asumsi dalam Analisis Diskriminan?

Analisis diskriminan (LDA) sering digunakan untuk mengelompokkan data ke dalam dua atau lebih kelas. Tapi, apakah kita selalu yakin bahwa data kita memenuhi syarat untuk digunakan dalam LDA? Dalam tulisan ini, saya ingin membandingkan bagaimana performa LDA ketika dua asumsi pentingnya normalitas dan homogenitas kovarian dipenuhi atau dilanggar.

Kedua asumsi ini sangat penting karena fungsi diskriminan yang dibentuk LDA berasal dari rumus probabilitas distribusi normal multivariat dengan kovarian yang seragam. Jika tidak terpenuhi, maka fungsi pemisah bisa jadi tidak representatif terhadap data sebenarnya.

Sejumlah referensi akademik yang dapat menguatkan hal ini:

Jadi, meskipun LDA tergolong metode sederhana dan interpretatif, penggunaannya tetap membutuhkan kehati-hatian dalam memeriksa asumsi.

Karena dalam praktik kita jarang tahu apakah data betul-betul memenuhi asumsi normalitas dan homogenitas kovarian, saya mencoba menyimulasikan beberapa skenario berbeda. Tujuannya adalah untuk menguji bagaimana performa LDA berubah ketika salah satu atau kedua asumsi tersebut dilanggar.

Kasus Asumsi Normalitas Varians-Kovarian sama? Catatan
1 Ya Ya kondisi ideal
2 Tidak Ya Data tidak normal
3 Ya Tidak Varians antar kelas berbeda
4 Tidak Tidak Semua asumsi dilanggar

Teknis Simulasi

Alur simulasi ini dijabarkan pada diagraam alir di bawah

Setelah menentukan alur simulasi, maka selanjutnya menjalankan simulasi pada kode R.

library(MASS)
library(mvtnorm)
library(ggplot2)
library(caret)
library(dplyr)
generate_data <- function(case) {
  n <- 100
  
  if (case == 1) {
    sigma <- matrix(c(1, 0.5, 0.5, 1), 2)
    group1 <- rmvnorm(n, mean=c(2, 2), sigma=sigma)
    group2 <- rmvnorm(n, mean=c(0, 0), sigma=sigma)
    
  } else if (case == 2) {
    group1 <- cbind(runif(n, 1, 5), runif(n, 1, 5))
    group2 <- cbind(runif(n, -1, 3), runif(n, -1, 3))
    
  } else if (case == 3) {
    sigma1 <- matrix(c(1, 0.3, 0.3, 1), 2)
    sigma2 <- matrix(c(2, 0.5, 0.5, 2), 2)
    group1 <- rmvnorm(n, mean=c(2, 2), sigma=sigma1)
    group2 <- rmvnorm(n, mean=c(0, 0), sigma=sigma2)
    
  } else if (case == 4) {
    group1 <- cbind(runif(n, 1, 5), runif(n, 1, 5))
    group2 <- cbind(rexp(n, 1/2), rexp(n, 1/2))
  }
  
  data <- rbind(group1, group2)
  group <- factor(c(rep("A", n), rep("B", n)))
  df <- data.frame(X1 = data[,1], X2 = data[,2], Group = group)
  return(df)
}

contoh tampilan dari data yang telah dibangkitkan

head(generate_data(1))
         X1       X2 Group
1 3.4257446 2.693945     A
2 0.9698819 1.030588     A
3 2.4748207 1.554914     A
4 2.2736308 2.306999     A
5 1.6433755 1.189025     A
6 2.5279350 2.641366     A
summary(generate_data(1))
       X1                 X2          Group  
 Min.   :-2.33671   Min.   :-2.8157   A:100  
 1st Qu.:-0.07469   1st Qu.:-0.2272   B:100  
 Median : 0.73787   Median : 0.9343          
 Mean   : 0.87550   Mean   : 0.9251          
 3rd Qu.: 1.86338   3rd Qu.: 2.0111          
 Max.   : 4.47949   Max.   : 4.7543          

Sebaran data bangkitan dengan berbagai kasus dapat dilihat di bawah ini

ggplot(generate_data(1), aes(x = X1, y = X2, color = Group)) +
  geom_point(alpha = 0.7) +
  labs(title = "Visualisasi Sebaran Data (Kasus 1)") +
  theme_minimal()

ggplot(generate_data(2), aes(x = X1, y = X2, color = Group)) +
  geom_point(alpha = 0.7) +
  labs(title = "Visualisasi Sebaran Data (Kasus 2)") +
  theme_minimal()

ggplot(generate_data(3), aes(x = X1, y = X2, color = Group)) +
  geom_point(alpha = 0.7) +
  labs(title = "Visualisasi Sebaran Data (Kasus 3)") +
  theme_minimal()

ggplot(generate_data(4), aes(x = X1, y = X2, color = Group)) +
  geom_point(alpha = 0.7) +
  labs(title = "Visualisasi Sebaran Data (Kasus 4)") +
  theme_minimal()

membuat fungsi evaluasi LDA

evaluate_lda <- function(df) {
  set.seed(2025)
  trainIndex <- createDataPartition(df$Group, p = 0.7, list = FALSE)
  train <- df[trainIndex, ]
  test <- df[-trainIndex, ]
  
  lda_model <- lda(Group ~ X1 + X2, data = train)
  pred <- predict(lda_model, test)$class
  acc <- mean(pred == test$Group)
  return(acc)
}

Menjalankan simulasi ke semua kasus

results <- data.frame(Kasus = character(), Normalitas = character(), Varians_Homogen = character(), Akurasi = numeric())

for (i in 1:4) {
  data_sim <- generate_data(i)
  acc <- evaluate_lda(data_sim)
  
  normal <- ifelse(i %in% c(1,3), "Ya", "Tidak")
  homogen <- ifelse(i %in% c(1,2), "Ya", "Tidak")
  
  results <- rbind(results, data.frame(
    Kasus = paste("Kasus", i),
    Normalitas = normal,
    Varians_Homogen = homogen,
    Akurasi = round(acc * 100, 2)
  ))
}

print(results)
    Kasus Normalitas Varians_Homogen Akurasi
1 Kasus 1         Ya              Ya   88.33
2 Kasus 2      Tidak              Ya   83.33
3 Kasus 3         Ya           Tidak   78.33
4 Kasus 4      Tidak           Tidak   65.00

Dari hasil simulasi, terlihat bahwa akurasi tertinggi muncul ketika dua asumsi terpenuhi. Saat asumsi dilanggar, apalagi keduanya, akurasi turun drastis. Ini bukti pentingnya memeriksa asumsi sebelum menggunakan LDA.

LDA memang teknik yang powerful, tapi tidak cocok untuk semua data. Jika datamu tidak normal atau varians antar grup berbeda jauh, LDA bisa memberi hasil yang menyesatkan.

Alternatifnya? Coba QDA, SVM, atau Random Forest. Tapi yang paling penting: pahami dulu karakteristik datamu sebelum memilih metode.

Referensi