library(dplyr)
library(FactoMineR)
library(factoextra)
Business Question:
Perusahaan memiliki data pembelian ragam tipe produk dari masing-masing customer, lalu ingin dilakukan segmentasi customer dari sebuah perusahaan wholesale berdasarkan karakteristik tiap customer dalam membeli produk.
wholesale <- read.csv("wholesale.csv")
head(wholesale)
Deskripsi kolom:
Menghapus kolom yang tidak diperlukan
wholesale <- wholesale %>%
select(-c(Channel, Region))
Cek missing value
colSums(is.na(wholesale))
#> Fresh Milk Grocery Frozen
#> 0 0 0 0
#> Detergents_Paper Delicassen
#> 0 0
Cek summary
summary(wholesale)
#> Fresh Milk Grocery Frozen
#> Min. : 3 Min. : 55 Min. : 3 Min. : 25.0
#> 1st Qu.: 3128 1st Qu.: 1533 1st Qu.: 2153 1st Qu.: 742.2
#> Median : 8504 Median : 3627 Median : 4756 Median : 1526.0
#> Mean : 12000 Mean : 5796 Mean : 7951 Mean : 3071.9
#> 3rd Qu.: 16934 3rd Qu.: 7190 3rd Qu.:10656 3rd Qu.: 3554.2
#> Max. :112151 Max. :73498 Max. :92780 Max. :60869.0
#> Detergents_Paper Delicassen
#> Min. : 3.0 Min. : 3.0
#> 1st Qu.: 256.8 1st Qu.: 408.2
#> Median : 816.5 Median : 965.5
#> Mean : 2881.5 Mean : 1524.9
#> 3rd Qu.: 3922.0 3rd Qu.: 1820.2
#> Max. :40827.0 Max. :47943.0
Insight: Perlu dilakukan scalling karena skala antar variable berbeda / range-nya terlalu kontras.
Sebelum melakukan clustering, mari lihat apakah terdapat outlier pada data. Outlier akan sangat mempengaruhi hasil clustering sehingga akan lebih baik bila kita menghilangkan terlebih dahulu outlier dari data. Outlier dapat divisualisasikan dengan biplot dari hasil PCA. Buat PCA dengan fungsi PCA() dan plot observasi dengan plot.PCA()!
Note: scaling hanya dilakukan 1 kali
wholesale_pca <- PCA(X = wholesale,
scale.unit = T)
Insight: Dari plot diketahui bahwa kelompok produk Milk, Grocery, dan Detergents_Paper memiliki kontribusi tinggi terhadap Dim 1 atau PC 1. Sedangkan kelompok produk Fresh, Frozen, dan Delicassen memiliki kontribusi tinggi terhadap Dim 2 atau PC 2. Kedua kelompok produk tersebut tidak saling berkorelasi.
Buat plot, visualisasikan 10 outlier terluar.
plot.PCA(x = wholesale_pca,
choix = "ind",
select = "contrib10")
Simpan indeks outlier dalam objek
outlier <- wholesale[-c(184,326,182,24,48,87,61,66,334,86),]
Sekarang kita dapat membuang observasi outlier dari data awal dan menyimpannya ke objek ws_normal untuk digunakan pada clustering.
Buang data outlier
ws_normal <- outlier
Cek variansi yang dirangkum tiap PC
wholesale_pca$eig
#> eigenvalue percentage of variance cumulative percentage of variance
#> comp 1 2.64497357 44.082893 44.08289
#> comp 2 1.70258397 28.376400 72.45929
#> comp 3 0.74006477 12.334413 84.79371
#> comp 4 0.56373023 9.395504 94.18921
#> comp 5 0.28567634 4.761272 98.95048
#> comp 6 0.06297111 1.049519 100.00000
Sebelum melakukan clustering, pastikan data kita hanya terdiri dari kolom numerik yang akan digunakan untuk clustering dan sudah bebas dari outlier yang dapat mengganggu.
summary(ws_normal)
#> Fresh Milk Grocery Frozen
#> Min. : 3 Min. : 55 Min. : 3 Min. : 25
#> 1st Qu.: 3098 1st Qu.: 1497 1st Qu.: 2132 1st Qu.: 744
#> Median : 8224 Median : 3596 Median : 4630 Median : 1526
#> Mean :11561 Mean : 5164 Mean : 7263 Mean : 2843
#> 3rd Qu.:16641 3rd Qu.: 7011 3rd Qu.:10066 3rd Qu.: 3491
#> Max. :76237 Max. :38369 Max. :59598 Max. :35009
#> Detergents_Paper Delicassen
#> Min. : 3 Min. : 3.0
#> 1st Qu.: 256 1st Qu.: 405.2
#> Median : 788 Median : 946.5
#> Mean : 2571 Mean : 1346.8
#> 3rd Qu.: 3806 3rd Qu.: 1779.0
#> Max. :26701 Max. :14472.0
Scaling
Sebelum melakukan clustering, perlu dilakukan scalling untuk menyeragamkan skala antar variable. Scalling pada saat PCA dilakukan hanya untuk observasi data dan tidak di-assign sebagai data processing, sedangkan scalling yang dilakukan disini akan di-assign pada data sebagai tahap processing untuk Clustering.
ws_scale <- scale(ws_normal)
k Optimum# fungsi tuning k berdasarkan wss
RNGkind(sample.kind = "Rounding")
kmeansTunning <- function(data, maxK) {
withinall <- NULL
total_k <- NULL
for (i in 2:maxK) {
set.seed(101)
temp <- kmeans(data,i)$tot.withinss
withinall <- append(withinall, temp)
total_k <- append(total_k,i)
}
plot(x = total_k, y = withinall, type = "o", xlab = "Number of Cluster", ylab = "Total within")
}
# kmeansTunning(your_data, maxK = 10)
kmeansTunning(ws_scale, maxK = 10)
Insight: Dalam pemilihan
k dapat dilakukan berdasarkan elbow method, yaitu kita ambil nilai k ketika penurunan total within sum of squares tidak lagi signifikan. Atau jika dilihat dalam plot, nilai k dipilih saat grafik mulai melandai. Dari plot diatas, berdasarkan elbow method kita pilih nilai k = 6.
Buat clustering dan simpan hasil clustering pada objek ws_kmeans
RNGkind(sample.kind = "Rounding")
set.seed(101)
ws_kmeans <- kmeans(ws_scale, centers = 6)
Kembalikan hasil cluster ke data awal
ws_normal$cluster <- ws_kmeans$cluster
Profiling
ws_normal %>%
group_by(cluster) %>% # kelompokan berdasarkan cluster
summarise_all(mean)
Insight:
Visualisasi Cluster
fviz_cluster(ws_kmeans, data = ws_normal)
Data Tabular
ws_normal %>%
group_by(cluster) %>%
summarise(sum_of_customer = length(cluster))
Kesimpulan: