Halo!, ini merupakan Learn By Building yang dilakukan di Algoritma Data Science. Kali ini saya akan mencoba melakukan Customer Segmentation dengan pendekatan K-mean Clustering
Customer Segmentation adalah pembagian pasar menjadi kelompok-kelompok customer yang berbeda yang memiliki karakteristik serupa. Customer Segmentation bisa menjadi alat yang sangat berguna untuk mengidentifikasi kebutuhan pelanggan yang tidak terpenuhi. Dengan menggunakan data di atas, perusahaan dapat melampaui kompetisi dengan mengembangkan produk dan layanan yang unik dan menarik.
Data ini saya peroleh melalui kaggle : https://www.kaggle.com/datasets/dev0914sharma/customer-clustering/data yang berisikan data dasar tentang pelanggan Anda seperti ID Pelanggan, usia, jenis kelamin, pendapatan tahunan, dan skor pengeluaran. Tujuan kita ingin memahami pelanggan seperti siapa saja pelanggan yang menjadi target sehingga informasi ini dapat diberikan kepada tim pemasaran dan merencanakan strategi sesuai.
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ forcats 1.0.0 ✔ readr 2.1.4
## ✔ ggplot2 3.4.3 ✔ stringr 1.5.0
## ✔ lubridate 1.9.2 ✔ tibble 3.2.1
## ✔ purrr 1.0.2 ✔ tidyr 1.3.0
## ── 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
## Warning: package 'factoextra' was built under R version 4.3.2
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
## Warning: package 'FactoMineR' was built under R version 4.3.2
##
## Attaching package: 'plotly'
##
## The following object is masked from 'package:ggplot2':
##
## last_plot
##
## The following object is masked from 'package:stats':
##
## filter
##
## The following object is masked from 'package:graphics':
##
## layout
## [1] 2 1 0 3
Okay, data ini terdiri dari 8 kolom yang terdiri dari : Deskripsi
ID berisikan nomor ID masing - masing pelangganSex merujuk pada jenis kelamin pelanggan dalam bentuk
biner. ( Jika Pria maka 1)Marital.status merujuk pada status pernikahan (Jika 1
maka menikah)Age merujuk pada usia pelanggan dari rentang nilai
maksimum 76 dan minimum 18Education merujuk pada tingkat pendidikan yang dimiliki
oleh pelanggan [ 0 = tidak sekolah dan 3 = Post Graduates atau
Pendidikan Doktor ]Income pendapatan pelanggan[35832 hingga 309364. (
Tidak diketahui dalam mata uang apa dan apakah pendapatan pertahuna tau
perbulan, mari kita asumsikan dengan pendapatan pertahun dalam bentuk
USD)Occupation: status pekerjaan ( 0 = Unemployed , 1 =
Employed, 2 = Highly Employed)Settlement.size : tempat tingga ( 0 = small city, 1 =
med city, 2 = big city)Dengan kita mengetahui isi dari perkolomnya, kita perlu mengubah tipe data untuk memastikan tipe data pada masing - masing kolom sudah sesuai atau tidak
## Rows: 2,000
## Columns: 8
## $ ID <int> 100000001, 100000002, 100000003, 100000004, 100000005,…
## $ Sex <int> 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, …
## $ Marital.status <int> 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, …
## $ Age <int> 67, 22, 49, 45, 53, 35, 53, 35, 61, 28, 25, 24, 22, 60…
## $ Education <int> 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 0, …
## $ Income <int> 124670, 150773, 89210, 171565, 149031, 144848, 156495,…
## $ Occupation <int> 1, 1, 0, 1, 1, 0, 1, 2, 0, 2, 1, 1, 1, 0, 1, 0, 1, 1, …
## $ Settlement.size <int> 2, 2, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 2, 0, 1, 0, 0, 2, …
Untuk memudahkan kita dalam melakukan clustering, kita bisa mengganti nilai variabel
customer <- customer %>%
mutate(Sex = recode(Sex, `0` = "Male", `1` = "Female")) %>%
mutate(Marital.status = recode(Marital.status, '0' = "Single", '1' = "Married" )) %>%
mutate(Education = recode(Education, '0' = "Others", '1' = "High School", '2' = "University", '3' = "Post Graduate" )) %>%
mutate(Occupation = recode(Occupation, '0' = "Unemployed", '1' = "Employed", '2' = "Highly Employed" )) %>%
mutate(Settlement.size = recode(Settlement.size, '0' = "Small City", '1' = "Med City" , '2' = "Big City")) ## Rows: 2,000
## Columns: 8
## $ ID <int> 100000001, 100000002, 100000003, 100000004, 100000005,…
## $ Sex <chr> "Male", "Female", "Male", "Male", "Male", "Male", "Mal…
## $ Marital.status <chr> "Single", "Married", "Single", "Single", "Single", "Si…
## $ Age <int> 67, 22, 49, 45, 53, 35, 53, 35, 61, 28, 25, 24, 22, 60…
## $ Education <chr> "University", "High School", "High School", "High Scho…
## $ Income <int> 124670, 150773, 89210, 171565, 149031, 144848, 156495,…
## $ Occupation <chr> "Employed", "Employed", "Unemployed", "Employed", "Emp…
## $ Settlement.size <chr> "Big City", "Big City", "Small City", "Med City", "Med…
Terlihat kita sudah mengubah isi variabel kita pada beberapa bagian kolom agar memudahkan membaca data yang ada
customer <- customer %>%
mutate_at(vars("Sex", "Marital.status", "Education", "Occupation", "Settlement.size"), as.factor)kita berhasil mengelompokan sesuai dengan tipe data yang seharunya digunakan
Selanjutnya kita akan melihat EDA, untuk melihat persebaran pada data customer yang kita miliki
Coba kita memerika terlebih dahulu pada kolom numerik yaitu
Age dan Income dari customer yang kita
miliki
#Melihat `Age`
ggplot(customer, aes(x = Age)) +
geom_histogram(binwidth = 5, fill = "skyblue", color = "black") +
labs(title = "Distribusi Usia (Age)",
x = "Usia (Age)", y = "Frekuensi")
Insight :
data customer kita memiliki pelanggan paling banyak
berusia 20 - 30 tahun
ggplot(customer, aes(x = Income)) +
geom_histogram(binwidth = 50000, fill = "lightgreen", color = "black") +
labs(title = "Distribusi Pendapatan (Income)",
x = "Pendapatan (Income)", y = "Frekuensi")
Lalu, pada kolom
Income pendapatan pelanggan paling banyak
berkisar 100k
Selanjutnya, mari kita lihat hubungan Age dan
Income melalui plot
plot <- plot_ly(customer, x = ~Age, y = ~Income, mode = "markers", type = "scatter", marker = list(color = ~Income, colorscale = 'Viridis')) %>%
layout(title = "Hubungan Antara Usia (Age) dan Pendapatan (Income)",
xaxis = list(title = "Usia (Age)"),
yaxis = list(title = "Pendapatan (Income)"))
plot Terlihat pada plot, data usia 20 - 30 tahun banyak berkumpul pada data pendapatan sekisar 100k - 150K
Selanjutnya, kita akan melihat lebih spesifik pada kolom data kategorik
kita ingin melihat bagaimana persebaran pada kolom Sex,
Marital.status, Education,
Occupation, Settlement.size.
plot_sex <- plot_ly(customer, x = ~Sex, type = "histogram", marker = list(color = "skyblue")) %>%
layout(title = "Persebaran Jenis Kelamin (Sex)",
xaxis = list(title = "Jenis Kelamin"),
yaxis = list(title = "Frekuensi"))
plot_sexplot_marital <- plot_ly(customer, x = ~Marital.status, type = "histogram", marker = list(color = "lightgreen")) %>%
layout(title = "Persebaran Status Pernikahan (Marital Status)",
xaxis = list(title = "Status Pernikahan"),
yaxis = list(title = "Frekuensi"))
plot_maritalplot_education <- plot_ly(customer, x = ~Education, type = "histogram", marker = list(color = "salmon")) %>%
layout(title = "Persebaran Pendidikan (Education)",
xaxis = list(title = "Pendidikan"),
yaxis = list(title = "Frekuensi"))
plot_educationplot_occupation <- plot_ly(customer, x = ~Occupation, type = "histogram", marker = list(color = "yellow")) %>%
layout(title = "Persebaran Pekerjaan (Occupation)",
xaxis = list(title = "Pekerjaan"),
yaxis = list(title = "Frekuensi"))
plot_occupationplot_settlement <- plot_ly(customer, x = ~Settlement.size, type = "histogram", marker = list(color = "orange")) %>%
layout(title = "Persebaran Ukuran Tempat Tinggal (Settlement Size)",
xaxis = list(title = "Ukuran Tempat Tinggal"),
yaxis = list(title = "Frekuensi"))
plot_settlementAgar memudahkan dalam membaca insight mari kita menggabungkan semua barplot pada setiap kolom
subplot(plot_sex, plot_marital, plot_education, plot_occupation, plot_settlement, nrows = 5) %>%
layout(showlegend = FALSE)Insight :
Female dan Male
terlihat hampir seimbang walaupun pelanggan Female lebih
banyakSingle dan
Married seimbangHigh SchoolEmployedSmall CitySelanjutnya kita ingin mengetahui bagaimana perbandingan antara
Sex, Income, serta Age
scatter_plot <- plot_ly(customer, x = ~Age, y = ~Income, color = ~factor(Sex),
type = "scatter", mode = "markers", marker = list(opacity = 0.7)) %>%
layout(title = "Hubungan Antara Usia (Age) dan Pendapatan (Income) dengan Perbedaan Jenis Kelamin (Sex)",
xaxis = list(title = "Usia (Age)"), yaxis = list(title = "Pendapatan (Income)"),
colorway = c("blue", "red"), legend = list(title = "Jenis Kelamin"))
scatter_plot## Warning in RColorBrewer::brewer.pal(N, "Set2"): minimal value for n is 3, returning requested palette with 3 different levels
## Warning in RColorBrewer::brewer.pal(N, "Set2"): minimal value for n is 3, returning requested palette with 3 different levels
terlihat pada plot, hubungan antara usia pelanggan dan gender mereka mempengaruhi pendapatan yang dimiliki hal ini menjadikan sebuah pertimbangan dalam menentukan cluster apa yang akan nantinya dibuat
Sebelum kita melakukan clustering, kita perlu menentukan jumlah cluster yang optimal. Dalam metode pengelompokan, kami berupaya meminimalkan total jumlah kuadrat dalam kluster (artinya jarak minimum antara observasi dalam kluster yang sama).
Untuk mencari jumlah cluster yang optimal, kita dapat menggunakan 3 metode: metode elbow, metode siluet, dan statistik gap. kita akan menentukan jumlah klaster berdasarkan suara terbanyak.
Saat kita mencoba k-means clustering perlu variabel berisikan tipe data numerik, kita akan mencoba apakah bisa kita melakukan clustering dengan data ini atau tidak, kita perlu mengubah beberapa kolom menjadi tipe data numerik
customer_clean <- customer %>%
mutate(Sex = as.numeric(Sex),
Marital.status = as.numeric(Marital.status),
Education = as.numeric(Education),
Occupation = as.numeric(Occupation),
Settlement.size = as.numeric(Settlement.size)) %>%
select(-"ID")
customer_cleanMenentukan K-means dengan Elbow Method :
kita tentukan k = 9
# Standarisasi variabel numerik
customer_clean[, c("Age", "Income")] <- scale(customer_clean[, c("Age", "Income")])
# Penerapan K-means
set.seed(123) # untuk hasil yang konsisten
customer_cluster <- kmeans(customer_clean, centers = 9) ## [1] 157.7580 274.8204 164.4439 705.3052 212.9942 703.3782 212.7580 135.3401
## [9] 268.1025
## [1] 0.723044
## [1] 240 122 102 214 174 507 210 144 287
Untuk bisa menginterpretasi karakteristik setiap cluster, kita bisa melihat dari centroid/titik pusat cluster.
Grouping data berdasarkan cluster label
Melakukan grouping berdasarkan cluster yang terbentuk, untuk mengetahui karakteristik dari masing-masing cluster.
# melakukan profiling cluster
customer_centroid <- customer_clean %>%
group_by(cluster) %>% # mengelompokkan data berdasarkan cluster
summarise_all(mean) # menentukan rata-rata untuk setiap kolom
customer_centroid# visualisasi 2 dimensi
fviz_cluster(object = customer_cluster ,
data = customer_clean
%>% select(-cluster),
labelsize = 7) #mengatur font gambar
Kita mencoba melakukan clustring dengan pendeketan k-means, tetapi pada
hasil visualiasi yang diberikan tidak dapat membantu kita mengenali
clustering mana pada data kita berada
Pada hasil proses data ini, perlu mengenali dan menentukan pendeketan clustering mana yang akan kita gunakan. Pada LBB yang saya lakukan, saya melakukan kesalahan dengan tidak menentukan pendeketan apa yang cocok pada data yang saya miliki
ternyata data Customer Segmentation tidak cocok menggunakan k-means clustering, yang dimana data tersebut lebih cocok untuk data yang memiliki skala atau pertipe numerik.
Solusi yang bisa dilakukan untuk melakukan clustering pada data Customer Segmentation adalah dengan Hierarchical Clustering.
Hierarchical Clustering adalah salah satu teknik dalam analisis cluster yang digunakan untuk mengelompokkan data ke dalam hierarki yang berstruktur secara bertingkat. Metode ini bekerja dengan cara membangun serangkaian cluster secara bertahap, di mana pada awalnya setiap data dianggap sebagai satu cluster individu. Kemudian, langkah demi langkah, algoritma menggabungkan dua cluster yang paling mirip menjadi satu cluster yang lebih besar, membentuk hierarki atau “dendrogram”.
Di lain kesempatan, saya akan mencoba membuat clustring dengan menggunakan Hierarchical Clustering dengan dataset Customer Segmentation seperti LBB ini.