LOAD LIBRARY DAN DATA

install.packages(c("tidyverse","cluster","factoextra","dbscan","fpc","e1071","meanShiftR"))
## Installing packages into '/cloud/lib/x86_64-pc-linux-gnu-library/4.5'
## (as 'lib' is unspecified)

Menginstal package yang dibutuhkan dalam analisis.

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.2.1     ✔ readr     2.2.0
## ✔ forcats   1.0.1     ✔ stringr   1.6.0
## ✔ ggplot2   4.0.2     ✔ tibble    3.3.1
## ✔ lubridate 1.9.5     ✔ tidyr     1.3.2
## ✔ purrr     1.2.1     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors

Memanggil package tidyverse yang digunakan untuk manipulasi dan transformasi data.

library(cluster)

Digunakan untuk metode clustering seperti PAM dan evaluasi silhouette.

library(factoextra)
## Welcome to factoextra!
## Want to learn more? See two factoextra-related books at https://www.datanovia.com/en/product/practical-guide-to-principal-component-methods-in-r/

Digunakan untuk visualisasi hasil clustering.

library(dbscan)
## 
## Attaching package: 'dbscan'
## The following object is masked from 'package:stats':
## 
##     as.dendrogram

Digunakan untuk metode clustering DBSCAN.

library(fpc)
## 
## Attaching package: 'fpc'
## The following object is masked from 'package:dbscan':
## 
##     dbscan

Menyediakan fungsi tambahan untuk clustering (meskipun tidak digunakan secara utama).

library(e1071)
## 
## Attaching package: 'e1071'
## The following object is masked from 'package:ggplot2':
## 
##     element

Digunakan untuk metode Fuzzy C-Means clustering.

library(meanShiftR)

Memanggil package yang digunakan untuk metode Mean Shift.

data <- read.csv("hcvdat0.csv")

Kode ini digunakan untuk membaca dataset dalam format CSV ke dalam R dan menyimpannya ke dalam variabel data, sehingga dapat digunakan untuk analisis selanjutnya.

str(data)
## 'data.frame':    615 obs. of  14 variables:
##  $ X       : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ Category: chr  "0=Blood Donor" "0=Blood Donor" "0=Blood Donor" "0=Blood Donor" ...
##  $ Age     : int  32 32 32 32 32 32 32 32 32 32 ...
##  $ Sex     : chr  "m" "m" "m" "m" ...
##  $ ALB     : num  38.5 38.5 46.9 43.2 39.2 41.6 46.3 42.2 50.9 42.4 ...
##  $ ALP     : num  52.5 70.3 74.7 52 74.1 43.3 41.3 41.9 65.5 86.3 ...
##  $ ALT     : num  7.7 18 36.2 30.6 32.6 18.5 17.5 35.8 23.2 20.3 ...
##  $ AST     : num  22.1 24.7 52.6 22.6 24.8 19.7 17.8 31.1 21.2 20 ...
##  $ BIL     : num  7.5 3.9 6.1 18.9 9.6 12.3 8.5 16.1 6.9 35.2 ...
##  $ CHE     : num  6.93 11.17 8.84 7.33 9.15 ...
##  $ CHOL    : num  3.23 4.8 5.2 4.74 4.32 6.05 4.79 4.6 4.1 4.45 ...
##  $ CREA    : num  106 74 86 80 76 111 70 109 83 81 ...
##  $ GGT     : num  12.1 15.6 33.2 33.8 29.9 91 16.9 21.5 13.7 15.9 ...
##  $ PROT    : num  69 76.5 79.3 75.7 68.7 74 74.5 67.1 71.3 69.9 ...

Menampilkan struktur dataset (tipe data dan jumlah variabel).

summary(data)
##        X           Category              Age            Sex           
##  Min.   :  1.0   Length:615         Min.   :19.00   Length:615        
##  1st Qu.:154.5   Class :character   1st Qu.:39.00   Class :character  
##  Median :308.0   Mode  :character   Median :47.00   Mode  :character  
##  Mean   :308.0                      Mean   :47.41                     
##  3rd Qu.:461.5                      3rd Qu.:54.00                     
##  Max.   :615.0                      Max.   :77.00                     
##                                                                       
##       ALB             ALP              ALT              AST        
##  Min.   :14.90   Min.   : 11.30   Min.   :  0.90   Min.   : 10.60  
##  1st Qu.:38.80   1st Qu.: 52.50   1st Qu.: 16.40   1st Qu.: 21.60  
##  Median :41.95   Median : 66.20   Median : 23.00   Median : 25.90  
##  Mean   :41.62   Mean   : 68.28   Mean   : 28.45   Mean   : 34.79  
##  3rd Qu.:45.20   3rd Qu.: 80.10   3rd Qu.: 33.08   3rd Qu.: 32.90  
##  Max.   :82.20   Max.   :416.60   Max.   :325.30   Max.   :324.00  
##  NA's   :1       NA's   :18       NA's   :1                        
##       BIL             CHE              CHOL            CREA        
##  Min.   :  0.8   Min.   : 1.420   Min.   :1.430   Min.   :   8.00  
##  1st Qu.:  5.3   1st Qu.: 6.935   1st Qu.:4.610   1st Qu.:  67.00  
##  Median :  7.3   Median : 8.260   Median :5.300   Median :  77.00  
##  Mean   : 11.4   Mean   : 8.197   Mean   :5.368   Mean   :  81.29  
##  3rd Qu.: 11.2   3rd Qu.: 9.590   3rd Qu.:6.060   3rd Qu.:  88.00  
##  Max.   :254.0   Max.   :16.410   Max.   :9.670   Max.   :1079.10  
##                                   NA's   :10                       
##       GGT              PROT      
##  Min.   :  4.50   Min.   :44.80  
##  1st Qu.: 15.70   1st Qu.:69.30  
##  Median : 23.30   Median :72.20  
##  Mean   : 39.53   Mean   :72.04  
##  3rd Qu.: 40.20   3rd Qu.:75.40  
##  Max.   :650.90   Max.   :90.00  
##                   NA's   :1

Menampilkan ringkasan statistik dari setiap variabel.

PREPROCESSING

data_clean <- data %>%
  select_if(is.numeric) %>%
  na.omit()

Pada tahap ini dilakukan pembersihan data. Fungsi select_if(is.numeric) digunakan untuk memilih hanya variabel numerik karena metode clustering hanya dapat bekerja dengan data numerik. Selanjutnya, na.omit() digunakan untuk menghapus baris yang memiliki nilai kosong agar tidak mengganggu proses analisis.

data_scaled <- scale(data_clean)

Data kemudian distandarisasi menggunakan fungsi scale(). Proses ini penting agar setiap variabel memiliki skala yang sama, sehingga tidak ada variabel yang mendominasi hasil clustering.

Statistik Deskriptif

summary(data_clean)
##        X              Age             ALB             ALP        
##  Min.   :  1.0   Min.   :23.00   Min.   :14.90   Min.   : 11.30  
##  1st Qu.:149.0   1st Qu.:39.00   1st Qu.:38.80   1st Qu.: 52.50  
##  Median :296.0   Median :47.00   Median :41.90   Median : 66.20  
##  Mean   :298.6   Mean   :47.42   Mean   :41.62   Mean   : 68.12  
##  3rd Qu.:448.0   3rd Qu.:54.00   3rd Qu.:45.10   3rd Qu.: 79.90  
##  Max.   :613.0   Max.   :77.00   Max.   :82.20   Max.   :416.60  
##       ALT              AST              BIL              CHE        
##  Min.   :  0.90   Min.   : 10.60   Min.   :  0.80   Min.   : 1.420  
##  1st Qu.: 16.40   1st Qu.: 21.50   1st Qu.:  5.20   1st Qu.: 6.930  
##  Median : 22.70   Median : 25.70   Median :  7.10   Median : 8.260  
##  Mean   : 26.58   Mean   : 33.77   Mean   : 11.02   Mean   : 8.204  
##  3rd Qu.: 31.90   3rd Qu.: 31.70   3rd Qu.: 11.00   3rd Qu.: 9.570  
##  Max.   :325.30   Max.   :324.00   Max.   :209.00   Max.   :16.410  
##       CHOL            CREA              GGT             PROT      
##  Min.   :1.430   Min.   :   8.00   Min.   :  4.5   Min.   :44.80  
##  1st Qu.:4.620   1st Qu.:  68.00   1st Qu.: 15.6   1st Qu.:69.30  
##  Median :5.310   Median :  77.00   Median : 22.8   Median :72.10  
##  Mean   :5.391   Mean   :  81.67   Mean   : 38.2   Mean   :71.89  
##  3rd Qu.:6.080   3rd Qu.:  89.00   3rd Qu.: 37.6   3rd Qu.:75.20  
##  Max.   :9.670   Max.   :1079.10   Max.   :650.9   Max.   :86.50

Kode ini digunakan untuk melihat kembali ringkasan statistik setelah proses pembersihan data, guna memastikan bahwa data sudah siap untuk dianalisis.

colMeans(data_clean)
##          X        Age        ALB        ALP        ALT        AST        BIL 
## 298.648557  47.417657  41.624278  68.123090  26.575382  33.772835  11.018166 
##        CHE       CHOL       CREA        GGT       PROT 
##   8.203633   5.391341  81.669100  38.198472  71.890153

Fungsi ini digunakan untuk menghitung nilai rata-rata dari setiap variabel numerik, sehingga dapat memberikan gambaran umum karakteristik data.

##Visualisasi Distribusi (Histogram)

library(tidyr)

Package tidyr digunakan untuk melakukan transformasi data, khususnya dalam mengubah format data agar sesuai untuk visualisasi.

data_long <- data_clean %>%
  pivot_longer(cols = -c(X), names_to = "Variabel", values_to = "Nilai")

Kode ini mengubah data dari format wide ke long. Transformasi ini diperlukan agar setiap variabel dapat divisualisasikan dalam satu grafik menggunakan ggplot.

ggplot(data_long, aes(x = Nilai)) +
  geom_histogram(bins = 30, fill = "steelblue", color = "black") +
  facet_wrap(~Variabel, scales = "free") +
  theme_minimal() +
  ggtitle("Distribusi Parameter Fungsi Hati")

Kode ini digunakan untuk membuat histogram dari setiap variabel. geom_histogram() menampilkan distribusi data, facet_wrap() memisahkan grafik berdasarkan variabel, theme_minimal() mempercantik tampilan, dan ggtitle() menambahkan judul grafik.

Boxplot Berdasarkan Kategori

data_box <- data %>%
  pivot_longer(cols = c(ALB, ALP, ALT, AST, BIL, CHE, CHOL, CREA, GGT, PROT),
               names_to = "Variabel", values_to = "Nilai")
data_box <- na.omit(data_box)

Kode ini mengubah beberapa variabel parameter fungsi hati ke dalam format long agar dapat dibandingkan antar kategori.

ggplot(data_box, aes(x = Category, y = Nilai, fill = Category)) +
  geom_boxplot() +
  facet_wrap(~Variabel, scales = "free") +
  ggtitle("Boxplot Parameter Fungsi Hati berdasarkan Kategori Pasien")

Boxplot digunakan untuk melihat distribusi data serta perbedaan antar kategori pasien. Visualisasi ini membantu mengidentifikasi adanya perbedaan pola atau outlier pada setiap variabel. ## K-MEANS

set.seed(123)

Digunakan untuk menetapkan nilai seed agar hasil clustering yang diperoleh dapat direproduksi dan konsisten setiap kali dijalankan.

kmeans_model <- kmeans(data_scaled, centers = 3, nstart = 25)

Kode ini menjalankan algoritma K-Means dengan jumlah cluster sebanyak 3. Parameter nstart = 25 digunakan untuk mencoba beberapa titik awal centroid agar diperoleh hasil clustering yang lebih optimal.

data_clean$kmeans_cluster <- kmeans_model$cluster

Hasil pengelompokan dari K-Means disimpan ke dalam dataset sebagai variabel baru, sehingga setiap data memiliki label cluster.

sil_kmeans <- silhouette(kmeans_model$cluster, dist(data_scaled))
sil_kmeans_val <- mean(sil_kmeans[,3])

Silhouette digunakan untuk mengevaluasi kualitas clustering. Nilai rata-rata silhouette menunjukkan seberapa baik pemisahan antar cluster, di mana semakin tinggi nilainya maka semakin baik hasil clustering.

K-MEDIAN (menggunakan PAM)

kmed_model <- pam(data_scaled, k = 3)

Metode PAM (Partitioning Around Medoids) digunakan sebagai alternatif K-Means dengan konsep median. Jumlah cluster ditentukan sebanyak 3.

data_clean$kmed_cluster <- kmed_model$clustering

Hasil cluster dari metode PAM disimpan ke dalam dataset.

sil_kmed <- silhouette(kmed_model$clustering, dist(data_scaled))
sil_kmed_val <- mean(sil_kmed[,3])

Nilai silhouette dihitung untuk mengevaluasi kualitas hasil clustering dari metode K-Median.

DBSCAN

db_model <- dbscan::dbscan(data_scaled, eps = 1.5, minPts = 5)

Melakukan clustering DBSCAN dengan (eps) radius pencarian tetangga dan (minPts)minimum jumlah titik dalam cluster

data_clean$dbscan_cluster <- db_model$cluster

Hasil clustering disimpan ke dalam dataset. Cluster dengan label 0 menunjukkan data yang dianggap sebagai noise atau outlier.

if(length(unique(db_model$cluster)) > 1){
  sil_db <- silhouette(db_model$cluster, dist(data_scaled))
  sil_db_val <- mean(sil_db[,3])
} else {
  sil_db_val <- NA
}

Silhouette hanya dihitung jika jumlah cluster lebih dari satu. Jika tidak, nilainya diisi dengan NA.

MEAN SHIFT

ms_model <- meanShift(data_scaled)

Mean Shift digunakan untuk mengelompokkan data tanpa menentukan jumlah cluster di awal, berdasarkan distribusi kepadatan data.

data_clean$ms_cluster <- ms_model$assignment

Menyimpan hasil cluster.

if(length(unique(ms_model$assignment)) > 1){
  sil_ms <- silhouette(ms_model$assignment, dist(data_scaled))
  sil_ms_val <- mean(sil_ms[,3])
} else {
  sil_ms_val <- NA
}

Evaluasi silhouette dilakukan jika cluster lebih dari satu.

FUZZY C-MEANS

fcm_model <- cmeans(data_scaled, centers = 3, m = 2)

Metode Fuzzy C-Means digunakan untuk clustering dengan konsep keanggotaan ganda, di mana satu data dapat memiliki derajat keanggotaan pada beberapa cluster.

data_clean$fcm_cluster <- fcm_model$cluster

Label cluster utama disimpan dalam dataset.

sil_fcm <- silhouette(fcm_model$cluster, dist(data_scaled))
sil_fcm_val <- mean(sil_fcm[,3])

Nilai silhouette dihitung untuk mengevaluasi kualitas clustering.

PERBANDINGAN METODE

results <- data.frame(
  Method = c("KMeans","KMedian","DBSCAN","MeanShift","FuzzyCMeans"),
  Silhouette = c(
    sil_kmeans_val,
    sil_kmed_val,
    sil_db_val,
    sil_ms_val,
    sil_fcm_val
  )
)

print(results)
##        Method  Silhouette
## 1      KMeans  0.14146759
## 2     KMedian  0.09650719
## 3      DBSCAN  0.20552096
## 4   MeanShift -0.20969039
## 5 FuzzyCMeans  0.13418023

Semua nilai silhouette dari masing-masing metode dikumpulkan dalam satu tabel untuk dibandingkan. Metode dengan nilai tertinggi dianggap memiliki performa terbaik.

Menentukan Metode terbaik

best_method <- results$Method[which.max(results$Silhouette)]

Kode ini digunakan untuk memilih metode dengan nilai silhouette tertinggi sebagai metode terbaik.

print(paste("Metode terbaik:", best_method))
## [1] "Metode terbaik: DBSCAN"

Menampilkan metode terbaik berdasarkan hasil perbandingan.

EDA Berdasarkan Metode Terbaik

if(best_method == "KMeans"){
  data_clean$cluster <- data_clean$kmeans_cluster
} else if(best_method == "KMedian"){
  data_clean$cluster <- data_clean$kmed_cluster
} else if(best_method == "DBSCAN"){
  data_clean$cluster <- data_clean$dbscan_cluster
} else if(best_method == "MeanShift"){
  data_clean$cluster <- data_clean$ms_cluster
} else if(best_method == "FuzzyCMeans"){
  data_clean$cluster <- data_clean$fcm_cluster
}

Mmemilih hasil cluster dari metode terbaik dan menyimpannya ke dalam satu variabel cluster agar dapat digunakan pada analisis lanjutan.

data_eda <- data_clean

Membuat salinan data untuk keperluan eksplorasi tanpa mengubah data asli.

if(best_method == "DBSCAN"){
  data_eda <- data_clean %>% filter(cluster != 0)
  cat("Jumlah data noise:", sum(data_clean$cluster == 0), "\n")
}
## Jumlah data noise: 187

Jika metode terbaik adalah DBSCAN, maka data noise (cluster 0) dihapus karena tidak termasuk dalam kelompok utama.

aggregate(. ~ cluster, data = data_eda, mean)
##   cluster        X      Age      ALB      ALP      ALT      AST      BIL
## 1       1 271.9154 46.69154 42.02065 66.16095 23.84577 25.00896 7.895025
##        CHE     CHOL     CREA      GGT    PROT kmeans_cluster kmed_cluster
## 1 8.290498 5.472164 78.34975 24.29378 72.0398       1.554726     2.032338
##   dbscan_cluster      V16 fcm_cluster
## 1              1 125.9627    1.502488

Menghitung rata-rata setiap variabel pada masing-masing cluster untuk mengetahui karakteristik tiap kelompok.

visualisasi

fviz_cluster(list(data = data_scaled, cluster = data_clean$cluster))

Visualisasi digunakan untuk melihat hasil clustering secara grafis, sehingga pola pemisahan antar cluster dan keberadaan outlier dapat lebih mudah dipahami.