INTRODUCTION

    Data berikut merupakan data keanggotaan pelanggan mall. Dimana dalam data tersebut kita memiliki data mengenai ID pelanggan, usia pelanggan, jenis kelamin pelanggan, pendapatan tahunan, serta Skor yang diberikan oleh mall berdasarkan perilaku dan pengeluaran pelanggan. Dimana kita ingin menganalisis pencapaian segmentasi pelanggan dan siapa saja target pelanggan yang sebenarnya dituju. Dalam hal ini bagian marketing atau pemasaran bisa mmendapatkan pelanggan sesuai dengan yang kita harapkan.

link : https://www.kaggle.com/datasets/krishnaraj30/mall-visiting-customer-data

IMPORT LIBRARY

library(dplyr)
library(lubridate)
library(GGally)
library(ggiraphExtra)
library(factoextra)
library(FactoMineR)
library(animation)
library(gridExtra)
library(ggplot2)
library(skmeans)
library(tidyr)

READ DATA

Hal pertama yang harus kita lakukan yaitu import data kita terlebih dahulu read.csv.

customers <- read.csv("mall_visiting_customers.csv")

DATA INSPECTIONS

Kita gunakan head() untuk melihat urutan data teratas dan gunakan tail() untuk melihat urutan data paling bawah.

head(customers)
tail(customers)

Cek struktur tipe data yang kita miliki menggunakan glimpse()

glimpse(customers)
#> Rows: 200
#> Columns: 5
#> $ CustomerID             <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, …
#> $ Gender                 <chr> "Male", "Male", "Female", "Female", "Female", "…
#> $ Age                    <int> 19, 21, 20, 23, 31, 22, 35, 23, 64, 30, 67, 35,…
#> $ Annual.Income..k..     <int> 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 19, 19,…
#> $ Spending.Score..1.100. <int> 39, 81, 6, 77, 40, 76, 6, 94, 3, 72, 14, 99, 15…

Dari fungsi glimps() yang telah kita jalankan diatas, kita mendapatkan informasi bahwa terdapat 200 rows dan 5 columns. Memuat informasi columns sebagai berikut :

`CustomerID`            : ID unik pelanggan
`Gender`                : Jenis kelamin pelanggan
`Age`                   : Usia pelanggan
`Annual.Income..k..`    : Pendapatan tahunan
`Spending.Score..1.100.`: Skor yang diberikan oleh mall berdasarkan perilaku dan pengeluaran pelanggan.

CLEANSING DATA

Kita ganti nama kolom yang tersedia sesuai dengan nama columns yang kita inginkan. Agar lebih mudah saat dibacanya dengan menngunakan fungsi rename(), lalu yang terakhir ubah tipe data yang kita miliki dengan tipe data yang sesuai menggunakan fungsi mmutate().

customers_mall <- customers %>%
  rename(Annual.Income = Annual.Income..k..,
         Spending.Score = Spending.Score..1.100.) %>% 
  mutate(Gender = as.factor (Gender))
customers_mall

Setelah proses rename() dan mutate() selesai, kita lanjutkan dengan menggunakan fungsi anyNA() yaitu untuk mengecheck apakah terdapat missing value atau tidak.

anyNA(customers_mall)
#> [1] FALSE

Dari hasil tersebut menunjukkan output FALSE yang artinya tidak terdapat missing value.

EXPLORATORY DATA ANALYSIS (EDA)

Analisis persebaran data meggunakan str() dan summary()

str(customers_mall)
#> 'data.frame':    200 obs. of  5 variables:
#>  $ CustomerID    : int  1 2 3 4 5 6 7 8 9 10 ...
#>  $ Gender        : Factor w/ 2 levels "Female","Male": 2 2 1 1 1 1 1 1 2 1 ...
#>  $ Age           : int  19 21 20 23 31 22 35 23 64 30 ...
#>  $ Annual.Income : int  15 15 16 16 17 17 18 18 19 19 ...
#>  $ Spending.Score: int  39 81 6 77 40 76 6 94 3 72 ...
summary(customers_mall)
#>    CustomerID        Gender         Age        Annual.Income    Spending.Score 
#>  Min.   :  1.00   Female:112   Min.   :18.00   Min.   : 15.00   Min.   : 1.00  
#>  1st Qu.: 50.75   Male  : 88   1st Qu.:28.75   1st Qu.: 41.50   1st Qu.:34.75  
#>  Median :100.50                Median :36.00   Median : 61.50   Median :50.00  
#>  Mean   :100.50                Mean   :38.85   Mean   : 60.56   Mean   :50.20  
#>  3rd Qu.:150.25                3rd Qu.:49.00   3rd Qu.: 78.00   3rd Qu.:73.00  
#>  Max.   :200.00                Max.   :70.00   Max.   :137.00   Max.   :99.00

Sebelum explorasi lebih jauh, mari kita buat visualisasi uji coba terhadap beberapa data yang kita miliki saat ini.

Coba kita lihat distribusi data Annual.Income berdasarkan Gender yang dikelompokkan, menggunakan plot densitas kernel :

ggplot(customers_mall,
       aes(x = Annual.Income,
           fill = Gender)) +
  geom_density(alpha = 0.7) +
  theme_minimal() +
  labs(title = "Annual Income Customers by Gender")

Dari hasil plot diatas dapat kita lihat bahwa Annual Income Customer yang paling tinggi adalah Male.

DATA PREPROCESSING

Pada tahap data preprocessing kita akan memasuki proses K-means clustering. Dimana K-means sendiri merupakan salah satu algoritma yang bersifat unsupervised learning. K-Means memiliki fungsi untuk mengelompokkan data kedalam data cluster. Algoritma ini dapat menerima data tanpa ada label kategori. K-Means Clustering Algoritma juga merupakan metode non-hierarchy.

Metode Clustering Algoritma adalah mengelompokkan beberapa data ke dalam kelompok yang menjelaskan data dalam satu kelompok memiliki karakteristik yang sama dan memiliki karakteristik yang berbeda dengan data yang ada di kelompok lain. Cluster Sampling adalah teknik pengambilan sampel di mana unit-unit populasi dipilih secara acak dari kelompok yang sudah ada yang disebut ‘cluster, nah Clustering atau klasterisasi adalah salah satu masalah yang menggunakan teknik unsupervised learning.

K-Means Clustering adalah suatu metode penganalisaan data atau metode Data Mining yang melakukan proses pemodelan unssupervised learning dan menggunakan metode yang mengelompokan data berbagai partisi.

K Means Clustering memiliki objective yaitu meminimalisasi object function yang telah di atur pada proses clasterisasi. Dengan cara minimalisasi variasi antar 1 cluster dengan maksimalisasi variasi dengan data di cluster lainnya.

Clustering Algoritma (K-Means) memiliki tujuan untuk meminimalisasikan fungsi objective yang telah di set dalam proses clustering. Tujuan tersebut dilakukan dengan cara meminimalikan variasi data yang ada didalam cluster dan memaksimalikan variasi data yang ada di cluster lainnya.

[‘Jurnal : SCHOOL OF INFORMATION SYSTEMS’]

Menentukan Variable

Sebelum melakukan proses scalling data, kita perlu menentukan variable mana yang perlu kita gunakan.

customers_k <- customers_mall[, c(3,4,5)]
customers_k

Scalling

Selanjutnya kita akan melaukan proses scallingScaling dilakukan sebelum melakukan Principal Component Analysis (PCA) agar antar variabel memiliki skala yang tidak jauh berbeda. Proses scaling yang digunakan adalah Z-score (mean = 0, standar deviasi = 1). Karena asumsinya masing-masing kolom memiliki satuan yang tidak sama.

#scalling data
customers_scale <- scale(customers_k)

#cek range data setelah di scalling
summary(customers_scale)
#>       Age          Annual.Income      Spending.Score     
#>  Min.   :-1.4926   Min.   :-1.73465   Min.   :-1.905240  
#>  1st Qu.:-0.7230   1st Qu.:-0.72569   1st Qu.:-0.598292  
#>  Median :-0.2040   Median : 0.03579   Median :-0.007745  
#>  Mean   : 0.0000   Mean   : 0.00000   Mean   : 0.000000  
#>  3rd Qu.: 0.7266   3rd Qu.: 0.66401   3rd Qu.: 0.882916  
#>  Max.   : 2.2299   Max.   : 2.91037   Max.   : 1.889750

MEMBUAT CLUSTERING DENGAN FUNGSI kmeans(data, center = k)

K-means Clustering

set.seed(100)

cust_cluster <- kmeans(x = customers_scale, centers = 7)
cust_cluster
#> K-means clustering with 7 clusters of sizes 45, 10, 33, 24, 21, 37, 30
#> 
#> Cluster means:
#>          Age Annual.Income Spending.Score
#> 1  1.2515802    -0.2396117    -0.04388764
#> 2 -0.4760539     1.8709508     1.23143545
#> 3  0.2211606     1.0805138    -1.28682305
#> 4 -0.9735839    -1.3221791     1.03458649
#> 5  0.4777583    -1.3049552    -1.19344867
#> 6 -0.8966761    -0.1252528    -0.10403254
#> 7 -0.4116255     0.6728925     1.20691001
#> 
#> Clustering vector:
#>   [1] 4 4 5 4 5 4 5 4 5 4 5 4 5 4 5 4 5 4 5 4 5 4 5 4 5 4 5 4 5 4 5 4 5 4 5 4 5
#>  [38] 4 5 4 1 4 5 4 5 4 1 6 6 6 1 6 6 1 1 1 1 1 6 1 1 6 1 1 1 6 1 1 6 6 1 1 1 1
#>  [75] 1 6 1 6 6 1 1 6 1 1 6 1 1 6 6 1 1 6 1 6 6 6 1 6 1 6 6 1 1 6 1 6 1 1 1 1 1
#> [112] 6 6 6 6 6 1 1 1 1 6 6 7 7 6 7 3 7 3 7 3 7 6 7 3 7 3 7 6 7 3 7 6 7 3 7 3 7
#> [149] 3 7 3 7 3 7 3 7 3 7 3 7 1 7 3 7 3 7 3 7 3 7 3 7 3 7 3 7 3 7 3 7 3 2 3 2 3
#> [186] 2 3 2 3 2 3 2 3 2 3 2 3 2 3 2
#> 
#> Within cluster sum of squares by cluster:
#> [1] 23.870153  4.161530 34.516303 11.716640 20.523322 18.921916  8.953188
#>  (between_SS / total_SS =  79.5 %)
#> 
#> Available components:
#> 
#> [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
#> [6] "betweenss"    "size"         "iter"         "ifault"

Dari hasil clustering di atas menunjukkan bahwa ukuran tiap cluster tidak proporsional antara satu dengan yang lain. Dimana dari 7 cluster terdiri terdapat : - Cluster 1 berjumlah 37, - Cluster 2 berjumlah 21, - Cluster 3 berjumlah 44, - Cluster 4 berjumlah 23, - Cluster 5 berjumlah 23, - Cluster 6 berjumlah 9, - Cluster 7 berjumlah 39.

Goodness of Fit

Kebaikan hasil clustering dapat dilihat dari 3 nilai:

  1. Within Sum of Squares ($withinss): jumlah jarak kuadrat dari tiap observasi ke centroid tiap cluster.
  2. Between Sum of Squares ($betweenss): jumlah jarak kuadrat terbobot dari tiap centroid ke rata-rata global. Dibobotkan berdasarkan banyaknya observasi pada cluster.
  3. Total Sum of Squares ($totss): jumlah jarak kuadrat dari tiap observasi ke rata-rata global.

Cek Nilai WSS

cust_cluster$withinss
#> [1] 23.870153  4.161530 34.516303 11.716640 20.523322 18.921916  8.953188
cust_cluster$tot.withinss
#> [1] 122.6631

Cek Nilai dan Ratio BSS dan TSS

# cek nilai bss
cust_cluster$betweenss
#> [1] 474.3369
# cek nilai tss
cust_cluster$totss
#> [1] 597
# cek ratio bss/tss
cust_cluster$betweenss/cust_cluster$totss
#> [1] 0.7945342

Insight yang didapat dari hasil diatas yaitu Clustering yang baik terdapat - WSS semakin rendah: jarak observasi di 1 kelompok yang sama semakin rendah, artinya tiap cluster memiliki karakteristik yang semakin mirip. - \[\frac{BSS}{TSS} ≈ 1\], karena kelompok hasil clustering semakin mewakili persebaran data yang sesungguhnya.

Apabila kita mencoba memperbesar nilai k (jumlah cluster) maka kita dapat meningkatkan nilai rasio BSS/TSS. Dan ternyata memperbesar nilai k (jumlah cluster) mendekati jumlah observasi kita membuat WSS akan banyak yang bernilai nol(0). Artinya terdapat banyak cluster yang isinya hanya 1 observasi. Kita tidak mau hal ini karena tujuan clustering tidak tercapai.

PEMILIHAN \(K\) OPTIMUM

Cara menentukan K optimum. Apabila Semakin tinggi \(k\), maka: - WSS (Within Sum of Squares) semakin mendekati 0 - BSS semakin mendekati TSS (atau BSS(Between Sum of Squares)/TSSTtotal Sum of Squares) mendekati 1)

Kalau begitu apakah kita selalu memilih \(k\) = banyak observasi? Bagaimana menentukan \(k\) optimum? Jawabannya yaitu : - Kebutuhan dari segi bisnis, dibutuhkan menjadi berapa kelompok - Secara objektif: Elbow method, visualisasi dengan fviz_nbclust()

fviz_nbclust(
  x = customers_scale,
  FUNcluster = kmeans,
  method = "wss"
)

Note : Pilih nilai k dimana ketika k ditambah, penurunan total within sum of squares tidak terlalu drastis (atau dapat dikatakan sudah melandai).

Insight : Kita pilih k = 6 karena saat di k = 7, ada kenaikan nilai WSS. Dan dapat simpulkan juga dari grafik diatas bahwa pilihan yang masuk akall untuk nilai K adalah k = 6.

Kontruksi kembali k-means clustering menggunakan K optimum.

RNGkind(sample.kind = "Rounding")
set.seed(100)

# k-means dengan k optimum
cust_cluster_op <- kmeans(customers_scale,centers = 9)

# WSS
cust_cluster_op$tot.withinss
#> [1] 93.90739
cust_cluster$tot.withinss
#> [1] 122.6631
# Cek berapa besar tiap cluster
cust_cluster_op$betweenss/cust_cluster_op$totss
#> [1] 0.8427012
# Cek berapa besar tiap cluster
cust_cluster_op$size
#> [1] 24 15 20 21  9 26 39 14 32

INTERPRETATION : CLUSTER PROFILING & VISUALIZATION

Membuat kolom baru yang berisikan informasi label dari cluster yang terbentuk menggunakan k optimum.

customers_mall$cluster <- as.factor(cust_cluster_op$cluster)
head(customers_mall)

Grouping data based on cluster label

cust_cluster_op$centers
#>          Age Annual.Income Spending.Score
#> 1 -1.1257063   -0.04829038   -0.004517845
#> 2 -0.5619583   -1.08992844   -0.327866461
#> 3  1.8612633   -0.28212750   -0.013553535
#> 4 -1.0051162   -1.33033784    1.163206770
#> 5 -0.8164901    0.63862598   -1.535206737
#> 6  0.5008340    1.19557860   -1.193306824
#> 7 -0.4408110    0.98910098    1.236400114
#> 8  0.8544426   -1.30223568   -1.396290689
#> 9  0.5901457   -0.19027425   -0.092454470

Data dengan range berbeda -> scaling -> kmeans(data_scaling, centers) Maka dari itu perlu grouping data berdasakan cluster dari data awal untuk melakukan interpretasi.

#profiling: radar plot
ggRadar(data = customers_mall, 
        aes(colour = cluster), 
        interactive = TRUE)
# Cluster Visualization
fviz_cluster(object = cust_cluster_op, 
             data = customers_scale)

#Cluster Profiling
customers_mall %>%
  group_by(cluster) %>% 
  summarise_all(.funs = "mean") %>% 
  select(-Gender, - CustomerID)

Insight : Dari hasil visualisasi diatas dapat disimpulkan bahwa dengan rentan usia 23 - 64 tahun, memiliki annual income berkisar diantara 26 - 91, dan dengan spedning score antara 10 - 82. Dimana artinya pendekatan pemasaran yang lebih strategis dan tepat sasaran dapat meningkatkan minat pelanggan untuk belanja lebih tinggi.