Install & Load Package

Pada tahap ini dilakukan instalasi dan pemanggilan beberapa package di RStudio yang digunakan untuk proses clustering, visualisasi, dan evaluasi. Package seperti tidyverse, dbscan, dan cluster membantu dalam pengolahan data serta penerapan berbagai metode clustering. #install.packages(tidyverse) #install.packages(flexclust) # k-median #install.packages(dbscan) # dbscan #install.packages(meanShiftR) # meanshift #install.packages(e1071) # fuzzy c-means #install.packages(cluster) # shilhoutte score #install.packages(fpc) # another metrics #install.packages(mclust) # ARI metrics to compare cluster with true label

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.2.0     ✔ 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
library(flexclust)
library(dbscan)
## 
## Attaching package: 'dbscan'
## 
## The following object is masked from 'package:stats':
## 
##     as.dendrogram
library(meanShiftR)
library(e1071)
## 
## Attaching package: 'e1071'
## 
## The following object is masked from 'package:flexclust':
## 
##     bclust
## 
## The following object is masked from 'package:ggplot2':
## 
##     element
library(cluster)
library(fpc)
## 
## Attaching package: 'fpc'
## 
## The following object is masked from 'package:dbscan':
## 
##     dbscan
library(mclust)
## Package 'mclust' version 6.1.2
## Type 'citation("mclust")' for citing this R package in publications.
## 
## Attaching package: 'mclust'
## 
## The following object is masked from 'package:dplyr':
## 
##     count
## 
## The following object is masked from 'package:purrr':
## 
##     map

Load Data

Dataset Online Shoppers Intention dibaca ke dalam R menggunakan fungsi read.csv(). Selanjutnya dilakukan pengecekan awal menggunakan head() dan str() untuk melihat struktur data dan tipe setiap variabel.

df <- read.csv("online_shoppers_intention.csv")

head(df)
##   Administrative Administrative_Duration Informational Informational_Duration
## 1              0                       0             0                      0
## 2              0                       0             0                      0
## 3              0                       0             0                      0
## 4              0                       0             0                      0
## 5              0                       0             0                      0
## 6              0                       0             0                      0
##   ProductRelated ProductRelated_Duration BounceRates ExitRates PageValues
## 1              1                0.000000  0.20000000 0.2000000          0
## 2              2               64.000000  0.00000000 0.1000000          0
## 3              1                0.000000  0.20000000 0.2000000          0
## 4              2                2.666667  0.05000000 0.1400000          0
## 5             10              627.500000  0.02000000 0.0500000          0
## 6             19              154.216667  0.01578947 0.0245614          0
##   SpecialDay Month OperatingSystems Browser Region TrafficType
## 1          0   Feb                1       1      1           1
## 2          0   Feb                2       2      1           2
## 3          0   Feb                4       1      9           3
## 4          0   Feb                3       2      2           4
## 5          0   Feb                3       3      1           4
## 6          0   Feb                2       2      1           3
##         VisitorType Weekend Revenue
## 1 Returning_Visitor   FALSE   FALSE
## 2 Returning_Visitor   FALSE   FALSE
## 3 Returning_Visitor   FALSE   FALSE
## 4 Returning_Visitor   FALSE   FALSE
## 5 Returning_Visitor    TRUE   FALSE
## 6 Returning_Visitor   FALSE   FALSE
str(df)
## 'data.frame':    12330 obs. of  18 variables:
##  $ Administrative         : int  0 0 0 0 0 0 0 1 0 0 ...
##  $ Administrative_Duration: num  0 0 0 0 0 0 0 0 0 0 ...
##  $ Informational          : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ Informational_Duration : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ ProductRelated         : int  1 2 1 2 10 19 1 0 2 3 ...
##  $ ProductRelated_Duration: num  0 64 0 2.67 627.5 ...
##  $ BounceRates            : num  0.2 0 0.2 0.05 0.02 ...
##  $ ExitRates              : num  0.2 0.1 0.2 0.14 0.05 ...
##  $ PageValues             : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ SpecialDay             : num  0 0 0 0 0 0 0.4 0 0.8 0.4 ...
##  $ Month                  : chr  "Feb" "Feb" "Feb" "Feb" ...
##  $ OperatingSystems       : int  1 2 4 3 3 2 2 1 2 2 ...
##  $ Browser                : int  1 2 1 2 3 2 4 2 2 4 ...
##  $ Region                 : int  1 1 9 2 1 1 3 1 2 1 ...
##  $ TrafficType            : int  1 2 3 4 4 3 3 5 3 2 ...
##  $ VisitorType            : chr  "Returning_Visitor" "Returning_Visitor" "Returning_Visitor" "Returning_Visitor" ...
##  $ Weekend                : logi  FALSE FALSE FALSE FALSE TRUE FALSE ...
##  $ Revenue                : logi  FALSE FALSE FALSE FALSE FALSE FALSE ...

Preprocessing

encoding

Beberapa variabel kategorikal seperti Month, VisitorType, dan Weekend diubah menjadi bentuk numerik agar dapat digunakan dalam proses clustering.

df$Month <- as.numeric(as.factor(df$Month))
df$VisitorType <- as.numeric(as.factor(df$VisitorType))
df$Weekend <- as.numeric(df$Weekend)

Menghapus target (Revenue)

Variabel Revenue dipisahkan sebagai label dan tidak digunakan dalam proses clustering karena metode clustering termasuk unsupervised learning.

label <- df$Revenue
df$Revenue <- NULL

Ambil fitur numerik

Memilih fitur numerik yang relevan untuk digunakan dalam analisis clustering.

df_num <- df[, c(
  "Administrative","Administrative_Duration",
  "Informational","Informational_Duration",
  "ProductRelated","ProductRelated_Duration",
  "BounceRates","ExitRates","PageValues","SpecialDay",
  "Month","VisitorType","Weekend"
)]

Scaling

Data dinormalisasi menggunakan fungsi scale() agar semua fitur memiliki skala yang sama, sehingga perhitungan jarak antar data menjadi lebih akurat.

df_scaled <- scale(df_num)

Sampling

Dilakukan pengambilan sampel sebanyak 3000 data untuk mempercepat proses komputasi tanpa mengurangi representasi data secara signifikan.

set.seed(123)
index <- sample(1:nrow(df_scaled), 3000)

df_sample <- df_scaled[index, ]
label_sample <- label[index]

Menentukan Jumlah Cluster

Elbow Method

Metode ini digunakan untuk menentukan jumlah cluster optimal dengan melihat grafik perubahan nilai WCSS. Titik “siku” pada grafik menunjukkan jumlah cluster yang baik.

wss <- sapply(1:10, function(k){
  kmeans(df_sample, centers = k, nstart = 20)$tot.withinss
})

plot(1:10, wss, type="b", pch=19,
     main="Elbow Method",
     xlab="Jumlah Cluster", ylab="WCSS")

Silhouette

Silhouette score digunakan untuk mengukur kualitas cluster. Nilai yang lebih tinggi menunjukkan bahwa cluster yang terbentuk semakin baik.

avg_sil <- function(k){
  km <- kmeans(df_sample, centers = k, nstart = 25)
  ss <- silhouette(km$cluster, dist(df_sample))
  mean(ss[,3])
}

k_values <- 2:10
sil <- sapply(k_values, avg_sil)

plot(k_values, sil, type="b", pch=19,
     main="Silhouette Score")

## Clustering # K-Means Metode K-Means digunakan untuk mengelompokkan data berdasarkan jarak ke pusat cluster (centroid).

km <- kmeans(df_sample, centers = 3)

K-Median

K-Median mirip dengan K-Means, namun menggunakan median sebagai pusat cluster sehingga lebih tahan terhadap outlier.

kmed <- kcca(df_sample, k = 3, family = kccaFamily("kmedians"))
## Found more than one class "kcca" in cache; using the first, from namespace 'flexclust'
## Also defined by 'kernlab'
## Found more than one class "kcca" in cache; using the first, from namespace 'flexclust'
## Also defined by 'kernlab'

DBSCAN

DBSCAN mengelompokkan data berdasarkan kepadatan (density) dan mampu mendeteksi data yang dianggap sebagai noise atau outlier.

db <- dbscan::dbscan(df_sample, eps = 0.5, minPts = 5)

Mean Shift

Mean Shift mencari pusat cluster secara otomatis tanpa menentukan jumlah cluster di awal.

ms <- meanShift(df_sample)

Fuzzy C-Means

Fuzzy C-Means memungkinkan satu data masuk ke lebih dari satu cluster dengan tingkat keanggotaan tertentu.

fcm <- cmeans(df_sample, centers = 3, m = 2)

Visualisasi

Visualisasi dilakukan untuk melihat hasil pengelompokan dari masing-masing metode clustering. Setiap warna menunjukkan cluster yang berbeda sehingga memudahkan dalam interpretasi hasil.

par(mfrow=c(2,3))

plot(df_sample, col=km$cluster, main="K-Means")
plot(df_sample, col=clusters(kmed), main="K-Median")
plot(df_sample, col=db$cluster+1, main="DBSCAN")
plot(df_sample, col=ms$assignment, main="Mean Shift")
plot(df_sample, col=fcm$cluster, main="Fuzzy C-Means")
plot(df_sample, col=as.numeric(label_sample), main="Original Revenue")

## Evaluasi metrix # Silhoutte Digunakan untuk mengukur seberapa baik suatu data cocok dengan cluster-nya dibandingkan dengan cluster lain.

mean(silhouette(km$cluster, dist(df_sample))[,3])
## [1] 0.3084682

Dunn Index

Dunn Index digunakan untuk mengevaluasi kualitas cluster berdasarkan jarak antar cluster dan kepadatan dalam cluster. Nilai yang lebih tinggi menunjukkan cluster yang lebih baik.

stats <- cluster.stats(dist(df_sample), km$cluster)
stats$dunn
## [1] 0.01656521

Adjusted Rand Index (ARI)

ARI digunakan untuk membandingkan hasil clustering dengan label asli (Revenue) untuk melihat seberapa sesuai hasil pengelompokan.

adjustedRandIndex(km$cluster, label_sample)
## [1] 0.03169522