Rumusan Masalah

Pada Learn by Building terkait Unsupervised Learning kali ini, akan dilakukan analisis kluster atau kelompok menggunakan K-Means Clustering dari data wholesale.csv. Data tersebut bersumber dari UCI Machine Learning Repository.

Berikut ini informasi tentang data:
FRESH: annual spending (m.u.) on fresh products (Continuous)
MILK: annual spending (m.u.) on milk products (Continuous)
GROCERY: annual spending (m.u.)on grocery products (Continuous)
FROZEN: annual spending (m.u.)on frozen products (Continuous)
DETERGENTS_PAPER: annual spending (m.u.) on detergents and paper products (Continuous)
DELICATESSEN: annual spending (m.u.)on and delicatessen products (Continuous)
CHANNEL: customers Channel - Horeca (Hotel/Restaurant/Cafe) or Retail channel (Nominal)
REGION: customers Region Lisnon, Oporto or Other (Nominal)

Praproses Data

Membaca dan melihat struktur data:

wholesale <- read.csv("wholesale.csv")
str(wholesale)
## 'data.frame':    440 obs. of  8 variables:
##  $ Channel         : int  2 2 2 1 2 2 2 2 1 2 ...
##  $ Region          : int  3 3 3 3 3 3 3 3 3 3 ...
##  $ Fresh           : int  12669 7057 6353 13265 22615 9413 12126 7579 5963 6006 ...
##  $ Milk            : int  9656 9810 8808 1196 5410 8259 3199 4956 3648 11093 ...
##  $ Grocery         : int  7561 9568 7684 4221 7198 5126 6975 9426 6192 18881 ...
##  $ Frozen          : int  214 1762 2405 6404 3915 666 480 1669 425 1159 ...
##  $ Detergents_Paper: int  2674 3293 3516 507 1777 1795 3140 3321 1716 7425 ...
##  $ Delicassen      : int  1338 1776 7844 1788 5185 1451 545 2566 750 2098 ...

Data Channel merupakan klasifikasi asli dari sumber data (Horeca dan Retail). Ini akan dijadikan pembanding dengan hasil K-Means Clustering. Berikut ini jumlah masing - masing klasifikasi asli dari sumber data.

wholesale$Channel <- as.factor(wholesale$Channel)
table(wholesale$Channel)
## 
##   1   2 
## 298 142

Dalam melakukan K-Means Clustering, data Channel dan Region tidak diperlukan, sehingga akan dihapus.

wholesale_k <- wholesale[,-c(1:2)]
head(wholesale_k)
##   Fresh Milk Grocery Frozen Detergents_Paper Delicassen
## 1 12669 9656    7561    214             2674       1338
## 2  7057 9810    9568   1762             3293       1776
## 3  6353 8808    7684   2405             3516       7844
## 4 13265 1196    4221   6404              507       1788
## 5 22615 5410    7198   3915             1777       5185
## 6  9413 8259    5126    666             1795       1451

Selanjutnya, dilakukan scale() untuk standarisasi data, agar semua data mempunyai skala yang sama, karena pada prinsipnya K-Means Clustering akan melakukan clustering berdasarkan kedekatan jarak masing - masing data.

wholesale_z <- scale(wholesale_k)
summary(wholesale_z)
##      Fresh              Milk            Grocery            Frozen        
##  Min.   :-0.9486   Min.   :-0.7779   Min.   :-0.8364   Min.   :-0.62763  
##  1st Qu.:-0.7015   1st Qu.:-0.5776   1st Qu.:-0.6101   1st Qu.:-0.47988  
##  Median :-0.2764   Median :-0.2939   Median :-0.3363   Median :-0.31844  
##  Mean   : 0.0000   Mean   : 0.0000   Mean   : 0.0000   Mean   : 0.00000  
##  3rd Qu.: 0.3901   3rd Qu.: 0.1889   3rd Qu.: 0.2846   3rd Qu.: 0.09935  
##  Max.   : 7.9187   Max.   : 9.1732   Max.   : 8.9264   Max.   :11.90545  
##  Detergents_Paper    Delicassen     
##  Min.   :-0.6037   Min.   :-0.5396  
##  1st Qu.:-0.5505   1st Qu.:-0.3960  
##  Median :-0.4331   Median :-0.1984  
##  Mean   : 0.0000   Mean   : 0.0000  
##  3rd Qu.: 0.2182   3rd Qu.: 0.1047  
##  Max.   : 7.9586   Max.   :16.4597

K-Means Clustering

Untuk menentukan nilai k (jumlah klaster yang optimal), akan digunakan metode Elbow. Dalam hal ini dibuat fungsi wss() untuk memvisualisasikan tot.withinss sebagai berikut.

wss <- function(data, maxCluster = 9) {
    # Initialize within sum of squares
    SSw <- (nrow(data) - 1) * sum(apply(data, 2, var))
    for (i in 2:maxCluster) {
      set.seed(10)
      SSw[i] <- sum(kmeans(data, centers = i)$withinss)
    }
    plot(1:maxCluster, SSw, type = "o", xlab = "Number of Clusters", ylab = "Within groups sum of squares", pch=19)
}

wss(wholesale_z)

Dari hasil visualisasi di atas, dilihat nilai k yang menghasilkan “siku”, yaitu grafik “patah” yang memiliki perubahan slope yang signifikan. Nilai k tersebut adalah 2 dan 4.

Berikut adalah hasil kluster menggunakan K-Means Clustering dari masing - masing k dan disimpan pada kolom clust2 dan clust4.

clust2 <- kmeans(wholesale_z,2)
clust4 <- kmeans(wholesale_z,4)

wholesale$clust2 <- as.factor(clust2$cluster)
wholesale$clust4 <- as.factor(clust4$cluster)

head(wholesale)
##   Channel Region Fresh Milk Grocery Frozen Detergents_Paper Delicassen
## 1       2      3 12669 9656    7561    214             2674       1338
## 2       2      3  7057 9810    9568   1762             3293       1776
## 3       2      3  6353 8808    7684   2405             3516       7844
## 4       1      3 13265 1196    4221   6404              507       1788
## 5       2      3 22615 5410    7198   3915             1777       5185
## 6       2      3  9413 8259    5126    666             1795       1451
##   clust2 clust4
## 1      2      1
## 2      2      4
## 3      2      4
## 4      2      1
## 5      2      3
## 6      2      1

Berikut ini perbandingan hasil K-Means Clustering dengan k = 2 dan k = 4.

table(wholesale$clust2)
## 
##   1   2 
##  49 391
table(wholesale$clust4)
## 
##   1   2   3   4 
## 279  12  52  97

Hasil klaster menggunakan K-Means Clustering dengan k = 2, jika dibandingkan dengan kluster asli dari sumber data, memiliki Accuracy yang kecil, yaitu 23.86%

table(wholesale$clust2, wholesale$Channel)
##    
##       1   2
##   1   6  43
##   2 292  99
num1 <- nrow(wholesale %>% 
                   filter(wholesale$clust2 == "1" & wholesale$Channel == "1"))
num2 <- nrow(wholesale %>% 
                   filter(wholesale$clust2 == "2" & wholesale$Channel == "2"))
accuracy <- (num1 + num2)/nrow(wholesale)
accuracy
## [1] 0.2386364

Berikut ini adalah visualisasi dua dimensi PC dari semua variable.

#transformasi dimensi ke PC
wholesale_pr <- prcomp(wholesale_z)
#menambahkan koordinat masing - masing PC ke data asal
wholesale <- cbind(wholesale, wholesale_pr$x)
#Visualisasi dua dimensi PC
plot.PCA(PCA(wholesale_z, graph=F), choix = "var")

PC1 dan PC2 dapat merangkum total informasi sebesar 44.08% + 28.38% = 72.46%, sehigga bisa dikatakan cukup bagus, karena hanya kehilangan informasi sekitar 27.54% (yang tidak dirangkum oleh PC selain PC1 dan PC2). Milk, Grocery, dan Dtergents_Paper, informasinya banyak dirangkum oleh PC1, sedangkan Frozen, Fresh, dan Delicassen, informasinya banyak dirangkum oleh PC2.

Berikut adalah visualisasi hasil dari masing - masing K-Means Clustering dengan k = 2 dan k = 4.

ggplot(wholesale, aes(x=PC1, y=PC2)) +
  geom_point(aes(col = clust2))

fviz_cluster(clust2, data = wholesale_z)

ggplot(wholesale, aes(x=PC1, y=PC2)) +
  geom_point(aes(col = clust4))

fviz_cluster(clust4, data = wholesale_z)

Berdasarkan hasil visualisasi dengan plot(PCA()) dan ggplot() / fviz_cluster(), secara umum data berada pada titik (0,0) yang artinya data bersifat rata - rata (tidak ada variable yang dominan mempengaruhi).
Apabila memperhatikan hasil kluster K-Means Clustering dengan k = 2, maka kluster ke-2 merupakan cluster dengan sedikit menghabiskan Milk, Grocery, dan Dtergents_Paper.

Kesimpulan

  1. K-Means Clustering dengan k = 2 memiliki Accuracy yang kecil, yaitu 23.86%, jika dibandingkan dengan kluster asli dari sumber data.
  2. Secara umum data berada pada titik (0,0) yang artinya data bersifat rata - rata (tidak ada variable yang dominan mempengaruhi).
  3. Pada hasil kluster dar K-Means Clustering dengan k = 2, kluster ke-2 merupakan cluster dengan sedikit menghabiskan Milk, Grocery, dan Dtergents_Paper.