# 1. Panggil data
library(caret)  # Tambahkan ini
## Warning: package 'caret' was built under R version 4.4.3
## Loading required package: ggplot2
## Loading required package: lattice
library(e1071)  # Untuk SVM
## Warning: package 'e1071' was built under R version 4.4.3
library(rpart)  # Untuk Decision Tree
## Warning: package 'rpart' was built under R version 4.4.3
library(class)  # Untuk KNN
## Warning: package 'class' was built under R version 4.4.3
library(ggplot2)
library(gridExtra)
## Warning: package 'gridExtra' was built under R version 4.4.3
data("john.alpha", package = "agridat")
df <- john.alpha

# 2. Buat variabel target biner
df$yield_class <- ifelse(df$yield < median(df$yield), "rendah", "tinggi")
df$yield_class <- as.factor(df$yield_class)

# 3. Cek distribusi kelas
table(df$yield_class)
## 
## rendah tinggi 
##     36     36
# Split data
set.seed(42)
index <- createDataPartition(df$yield_class, p = 0.7, list = FALSE)
train <- df[index, ]
test <- df[-index, ]
# Model SVM
svm_model <- svm(yield_class ~ row + col, data = train, kernel = "radial")
## Warning in svm.default(x, y, scale = scale, ..., na.action = na.action):
## Variable(s) 'col' constant. Cannot scale data.
svm_pred <- predict(svm_model, newdata = test)
svm_acc <- mean(svm_pred == test$yield_class)

# Model KNN (k = 5)
knn_pred <- knn(train = train[, c("row", "col")],
                test = test[, c("row", "col")],
                cl = train$yield_class, k = 5)
knn_acc <- mean(knn_pred == test$yield_class)

# Model Decision Tree
dt_model <- rpart(yield_class ~ row + col, data = train, method = "class")
dt_pred <- predict(dt_model, test, type = "class")
dt_acc <- mean(dt_pred == test$yield_class)

# Tampilkan akurasi
cat("Akurasi SVM :", round(svm_acc * 100, 2), "%\n")
## Akurasi SVM : 60 %
cat("Akurasi KNN (k = 5) :", round(knn_acc * 100, 2), "%\n")
## Akurasi KNN (k = 5) : 85 %
cat("Akurasi Decision Tree:", round(dt_acc * 100, 2), "%\n")
## Akurasi Decision Tree: 70 %
# Buat dataframe hasil prediksi
results <- data.frame(
  Actual = test$yield_class,
  SVM = svm_pred,
  KNN = knn_pred,
  DecisionTree = dt_pred
)

# Pastikan level faktor konsisten
results$Actual <- factor(results$Actual, levels = c("rendah", "tinggi"))
results$SVM <- factor(results$SVM, levels = c("rendah", "tinggi"))
results$KNN <- factor(results$KNN, levels = c("rendah", "tinggi"))
results$DecisionTree <- factor(results$DecisionTree, levels = c("rendah", "tinggi"))
# Visualisasi untuk masing-masing model
svm_plot <- ggplot(results, aes(x = Actual, fill = SVM)) +
  geom_bar(position = "dodge") +
  geom_text(stat = "count", aes(label = after_stat(count)),
            position = position_dodge(0.8), vjust = -0.5) +
  labs(title = "Prediksi SVM", x = "Aktual", y = "Frekuensi") +
  scale_fill_manual(values = c("red", "blue"))

knn_plot <- ggplot(results, aes(x = Actual, fill = KNN)) +
  geom_bar(position = "dodge") +
  geom_text(stat = "count", aes(label = after_stat(count)),
            position = position_dodge(0.8), vjust = -0.5) +
  labs(title = "Prediksi KNN (k = 5)", x = "Aktual", y = "Frekuensi") +
  scale_fill_manual(values = c("red", "blue"))

dt_plot <- ggplot(results, aes(x = Actual, fill = DecisionTree)) +
  geom_bar(position = "dodge") +
  geom_text(stat = "count", aes(label = after_stat(count)),
            position = position_dodge(0.8), vjust = -0.5) +
  labs(title = "Prediksi Decision Tree", x = "Aktual", y = "Frekuensi") +
  scale_fill_manual(values = c("red", "blue"))

grid.arrange(svm_plot, knn_plot, dt_plot, ncol = 3)

# Fungsi evaluasi model biner
evaluasi_model <- function(prediksi, aktual, positive_class = "tinggi") {
  cm <- table(Aktual = aktual, Prediksi = prediksi)

  TP <- cm[positive_class, positive_class]
  TN <- cm["rendah", "rendah"]
  FP <- cm["rendah", "tinggi"]
  FN <- cm["tinggi", "rendah"]

  akurasi <- (TP + TN) / sum(cm)
  presisi <- TP / (TP + FP)
  recall <- TP / (TP + FN)
  f1 <- 2 * (presisi * recall) / (presisi + recall)

  cat("==== Evaluasi Model ====\n")
  cat("TP (tinggi - benar) :", TP, "\n")
  cat("TN (rendah - benar):", TN, "\n")
  cat("FP (rendah jadi tinggi):", FP, "\n")
  cat("FN (tinggi jadi rendah):", FN, "\n\n")
  cat("Akurasi :", round(akurasi * 100, 2), "%\n")
  cat("Presisi :", round(presisi, 2), "\n")
  cat("Recall  :", round(recall, 2), "\n")
  cat("F1 Score:", round(f1, 2), "\n\n")
}
cat("=== Evaluasi SVM ===\n")
## === Evaluasi SVM ===
evaluasi_model(results$SVM, results$Actual)
## ==== Evaluasi Model ====
## TP (tinggi - benar) : 8 
## TN (rendah - benar): 4 
## FP (rendah jadi tinggi): 6 
## FN (tinggi jadi rendah): 2 
## 
## Akurasi : 60 %
## Presisi : 0.57 
## Recall  : 0.8 
## F1 Score: 0.67
cat("=== Evaluasi KNN (k = 5) ===\n")
## === Evaluasi KNN (k = 5) ===
evaluasi_model(results$KNN, results$Actual)
## ==== Evaluasi Model ====
## TP (tinggi - benar) : 9 
## TN (rendah - benar): 8 
## FP (rendah jadi tinggi): 2 
## FN (tinggi jadi rendah): 1 
## 
## Akurasi : 85 %
## Presisi : 0.82 
## Recall  : 0.9 
## F1 Score: 0.86
cat("=== Evaluasi Decision Tree ===\n")
## === Evaluasi Decision Tree ===
evaluasi_model(results$DecisionTree, results$Actual)
## ==== Evaluasi Model ====
## TP (tinggi - benar) : 9 
## TN (rendah - benar): 5 
## FP (rendah jadi tinggi): 5 
## FN (tinggi jadi rendah): 1 
## 
## Akurasi : 70 %
## Presisi : 0.64 
## Recall  : 0.9 
## F1 Score: 0.75