# clear-up the environment
rm(list = ls())
# chunk options
knitr::opts_chunk$set(
message = FALSE,
warning = FALSE,
fig.align = "center",
comment = "#>"
)
# scientific notation
options(scipen = 9999)
Materi ini diproduksi oleh tim dari Algoritma untuk DDE - Bank OCBC NISP . Materi berikut hanya ditujukan untuk kalangan terbatas, meliputi individu/personal yang menerima materi ini secara langsung dari lembaga pelatihan. Materi ini dilarang untuk direproduksi, didistribusikan, diterjemahkan, atau diadaptasikan dalam bentuk apapun di luar izin dari individu dan organisasi yang berkepentingan.
Algoritma adalah pusat pendidikan Data Science di Jakarta. Kami mengadakan workshop dan program pelatihan untuk membantu para profesional dan pelajar untuk mendapatkan keahlian dalam berbagai bidang dalam ruang lingkup Data Science: data visualization, machine learning, data modeling, statistical inference, dan lain-lainnya.
Sebelum masuk ke dalam materi dan menjalankan kode-kode di dalam materi ini, silakan anda melihat bagian Library and Setup untuk melihat dan memastikan semua persyaratan dasar untuk mengikuti materi ini sudah terpenuhi termasuk package-package yang diperlukan. Pada bagian Tujuan Pembelajaran anda dapat melihat secara umum apa saja yang akan dipelajari dalam modul materi ini. Kami harap materi ini akan bermanfaat bagi karir ataupun menambah keahlian peserta.
Tujuan utama dari workshop ini adalah untuk memberikan pengenalan yang komprehensif mengenai tools dan perangkat lunak yakni sebuah open-source R Programming yang digunakan untuk melakukan sekementasi kustomer dengan menggunakan dari Unsupervised Machine Learning - Clustering. Adapun materi ini akan mencakup:
Dengan berbagai macam fitur maupun promo yang ditawarkan kepada pengguna kartu kredit, banyak sekali individu yang mulai membuat kartu kredit untuk mempermudah proses transaksi yang dilakukan dan mendapatkan promo menarik.
Untuk dapat bersaing antara Bank dalam mengait calon pengguna kartu kredit, kita harus dapat menawarkan jenis kartu kredit yang sesuai dengan kebutuhan dari calon pelanggan kita. Selain mengait para pengguna baru, kita juga harus menjaga bahkan meningkatkan retensi pelanggan dengan cara memberikan promo yang lebih tepat sasaran.
Dalam melakukan kedua hal tersebut tidaklah mudah karena setiap pengguna kartu kredit memiliki karakteristik yang berbeda-beda. Walaupun berbeda-beda, setiap customer dapat dikelompokan dengan karakteristik yang mendekati satu dengan lainnya sehingga nantinya dapat beberapa kelompok yang memiliki karakteristik yang mendekati. Dengan mempelajari setiap karakteristik dari setiap kelompok, kita dapat menarik kesimpulan untuk menentukan strategi bisnis untuk meningkatkan pengguna baru dan meningkatkan kepuasan dari pengguna lama.
# Data Wrangling
library(tidyverse)
library(Hmisc)
# Machine Learning - Clustering
library(cluster)
library(factoextra)
# Visualization
library(Rtsne)
Data yang kita gunakan adalah data behavior dari para pengguna kartu
kredit disebuah bank. Data tersebut kami letakan di foder
data
dengan nama file
creditcard_customer_behavior.csv
, fungsi yang dapat
dimanfaatkan untuk membaca data adalah `read.csv()``
# Membaca data
customer <- read.csv("data/creditcard_customer_behavior.csv")
# Menampilkan 6 data paling atas
customer %>%
head()
Deskripsi singkat:
CLIENTNUM
: Unique ID ClientCustomer_Age
: Umur customerGender
: gender customerEducation_Level
: Tingkat pendidikanMarital_Status
: Status PernikahanIncome_Category
: Range pendapatanMonths_Inactive_12_mon
: Selama 12 bulan terakhir sempat
tidak menggunakan kartu kredit berapa lamaCredit_Limit
: Limmit dari creditcardTotal_Trans_Amt
: Jumlah amount transaksi yang dilakukan
selama 12 bulan terakhirTotal_Trans_Ct
: Total transaksi yang dilakukan selama
12 bulan terakhirAdditional Info:
Kita dapat membaca berbagai macam tipe file data di R, berikut adalah beberapa contoh file yang dapat kita baca di R.
Selain membaca data yang sudah tersimpan dalam komputer kita, R Studio juga dapat kita sambungkan ke database untuk mengambil data-data yang tersimpan pada database tersebut.
Wrangling 1: Apakah kolom CLIENTNUM
?
CLIENTNUM
dapat kita buang karena
nantinya dapat mempengaruhi perhitungan dan pembuatan kelompok.Untuk melakukan hal tersebut kita bisa menggunakan fungsi
select()
customer %>%
select(-CLIENTNUM)
CLIENTNUM
dapat kita buat sebagai
rownames saja.Untuk melakukan hal tersebut kita bisa menggunakan fungsi
column_to_rownames()
customer %>%
column_to_rownames("CLIENTNUM")
# Menyimpan hasilnya ke dalam sebuah objek baru
customer_clean <- customer %>%
column_to_rownames("CLIENTNUM")
Wrangling 2: Apakah terdapat kolom yang belum sesuai tipe datanya?
Untuk mengetahui apakah ada tipe data yang belum sesuai kita dapat
menggunakan fungsi glimpse()
.
customer %>%
glimpse()
#> Rows: 6,339
#> Columns: 10
#> $ CLIENTNUM <int> 768805383, 818770008, 713982108, 769911858, 713…
#> $ Customer_Age <int> 45, 49, 51, 40, 44, 32, 48, 56, 35, 57, 48, 61,…
#> $ Gender <chr> "M", "F", "M", "F", "M", "M", "M", "M", "M", "F…
#> $ Education_Level <chr> "High School", "Graduate", "Graduate", "High Sc…
#> $ Marital_Status <chr> "Married", "Single", "Married", "Unknown", "Mar…
#> $ Income_Category <chr> "$60K - $80K", "Less than $40K", "$80K - $120K"…
#> $ Months_Inactive_12_mon <int> 1, 1, 1, 4, 1, 2, 3, 6, 1, 2, 2, 2, 2, 3, 2, 1,…
#> $ Credit_Limit <dbl> 12691.0, 8256.0, 3418.0, 3313.0, 4010.0, 29081.…
#> $ Total_Trans_Amt <int> 1144, 1291, 1887, 1171, 1088, 1538, 1441, 1539,…
#> $ Total_Trans_Ct <int> 42, 33, 20, 20, 24, 36, 32, 17, 33, 29, 27, 30,…
Intuisi dari masing-masing tipe data:
int
: integer, merupakan tipe data yang
diperuntuhkan untuk data-data numerik tanpa koma.dbl
: double, merupakan tipe data yang serupa
dengan integer akan tetapi data-data numerik ini bisa memiliki unsur
koma/desimal.chr
: character, merupakan tipe data yang
diperuntuhkan untuk data-data alfabetikalfct
: factor, merupakan tipe data yang
diperuntuhkan untuk data-data alfabetikal yang sifatnya
berulang-ulang.lgl
: logical, merupan tipe data yang berisikan
nilai TRUE atau FALSE saja.Berdasarkan intuisi dari masing-masing tipe data, terdapat beberapa kolom yang belum sesuai:
Gender
-> FactorEducation_Level
-> FactorMarital_Status
-> FactorIncome_Category
-> FactorUntuk mengubah beberapa kolom di atas menjadi tipe yang lebih sesuai,
kita dapat memanfaatkan fungsi mutate()
. Contoh penggunaan
fungsi mutate():
mutate(nama_kolom = fungsi_untuk_mengubah_tipe_data(nama_kolom))
.
as.factor()
-> untuk mengubah tipe data menjadi
factoras.integer()
-> untuk mengubah tipe data menjadi
integeras.character
-> untuk mengubah tipe data menjadi
characterSetelah mengetahui bagaimana cara mengubah tipe data, mari kita coba implementasikan.
customer_clean <- customer_clean %>%
mutate(Gender = as.factor(Gender),
Education_Level = as.factor(Education_Level),
Marital_Status = as.factor(Marital_Status),
Income_Category = as.factor(Income_Category))
customer_clean %>%
glimpse()
#> Rows: 6,339
#> Columns: 9
#> $ Customer_Age <int> 45, 49, 51, 40, 44, 32, 48, 56, 35, 57, 48, 61,…
#> $ Gender <fct> M, F, M, F, M, M, M, M, M, F, M, M, M, F, M, F,…
#> $ Education_Level <fct> High School, Graduate, Graduate, High School, G…
#> $ Marital_Status <fct> Married, Single, Married, Unknown, Married, Unk…
#> $ Income_Category <fct> $60K - $80K, Less than $40K, $80K - $120K, Less…
#> $ Months_Inactive_12_mon <int> 1, 1, 1, 4, 1, 2, 3, 6, 1, 2, 2, 2, 2, 3, 2, 1,…
#> $ Credit_Limit <dbl> 12691.0, 8256.0, 3418.0, 3313.0, 4010.0, 29081.…
#> $ Total_Trans_Amt <int> 1144, 1291, 1887, 1171, 1088, 1538, 1441, 1539,…
#> $ Total_Trans_Ct <int> 42, 33, 20, 20, 24, 36, 32, 17, 33, 29, 27, 30,…
Wrangling 3: Apakah terdapat missing value?
Untuk melihat apakah terdapat missing value pada data yang kita
gunakan, kita dapat menggunakan fungsi anyNA()
.
customer_clean %>%
anyNA()
#> [1] FALSE
Jika hasil dari fungsi adalah FALSE, maka tidak ada nilai missing pada data kita.
Pada tahapan eksplorasi data, kita akan mencoba untuk lebih mengenali data yang kita miliki.
EDA 1: Eksplorasi data dengan memanfaatkan statistika deskriptif
Statistika deskriptif dapat juga disebut sebuah eksplorasi data
dengan melihat hasil dari 6 number summary (minimal, maksimum,
mean, median, 1st quartile & 3rd quartile). Fungsi yang dapat kita
gunakan adalah summary()
.
customer_clean %>%
summary()
#> Customer_Age Gender Education_Level Marital_Status
#> Min. :26.00 F:3008 College : 905 Divorced: 455
#> 1st Qu.:41.00 M:3331 Doctorate : 381 Married :2986
#> Median :46.00 Graduate :2796 Single :2436
#> Mean :46.28 High School :1788 Unknown : 462
#> 3rd Qu.:52.00 Post-Graduate: 469
#> Max. :73.00
#> Income_Category Months_Inactive_12_mon Credit_Limit Total_Trans_Amt
#> $120K + : 488 Min. :0.000 Min. : 1438 Min. : 510
#> $40K - $60K :1272 1st Qu.:2.000 1st Qu.: 2523 1st Qu.: 2109
#> $60K - $80K : 997 Median :2.000 Median : 4327 Median : 3863
#> $80K - $120K :1099 Mean :2.343 Mean : 8490 Mean : 4396
#> Less than $40K:2483 3rd Qu.:3.000 3rd Qu.:10588 3rd Qu.: 4751
#> Max. :6.000 Max. :34516 Max. :17995
#> Total_Trans_Ct
#> Min. : 10.00
#> 1st Qu.: 44.00
#> Median : 67.00
#> Mean : 64.56
#> 3rd Qu.: 81.00
#> Max. :132.00
Insight:
Jika dirasa dengan menggunakan perhitungan statistika kita masih belum mendapatkan kesimpulan yang memuaskan, kita juga dapat melakukan analisa dengan menggunakan bantuan visualisasi. Selain itu, kita juga akan melakukan analisa yang lebih detail lagi untuk beberapa insight yang sudah kita dapatkan.
EDA 2: Eksplorasi data dengan memanfaatkan visualisasi
Sebagai tambahan untuk data dengan tipe numerik kita bisa melakukan
visualiasi dengan plot histogram untuk melihat jumlah observasinya.
Untuk melelihatnya dengan visualisasi histogram, kita tidak perlu
membuatnya satu per satu, melainkan kita bisa menggunakan fungsi
hist.data.frame()
dari library(Hmisc)
.
customer_clean %>%
hist.data.frame()
Insight
EDA 3 Melakukan analisa lebih mendetail untuk memvalidasi beberapa temuan yang sudah kita dapatkan
ggplot(data = customer_clean, mapping = aes(x = Education_Level, y = ..count..)) +
geom_bar(mapping = aes(fill = Income_Category),
position = "dodge")
Untuk melakukan analisa lebih mendetail terhadap temuan tersebut, kita akan mencoba melihat secara lebih spesifik terhadap customer yang memiliki credit limit direntang 33-35rb USD.
customer_clean %>%
filter(Credit_Limit > 33000) %>%
summary()
#> Customer_Age Gender Education_Level Marital_Status
#> Min. :27.00 F: 0 College : 59 Divorced: 28
#> 1st Qu.:43.00 M:354 Doctorate : 18 Married :134
#> Median :48.00 Graduate :157 Single :165
#> Mean :46.92 High School : 93 Unknown : 27
#> 3rd Qu.:52.00 Post-Graduate: 27
#> Max. :62.00
#> Income_Category Months_Inactive_12_mon Credit_Limit Total_Trans_Amt
#> $120K + :140 Min. :1.000 Min. :33122 Min. : 691
#> $40K - $60K : 0 1st Qu.:2.000 1st Qu.:34516 1st Qu.: 2311
#> $60K - $80K : 45 Median :2.000 Median :34516 Median : 4263
#> $80K - $120K :169 Mean :2.299 Mean :34467 Mean : 6156
#> Less than $40K: 0 3rd Qu.:3.000 3rd Qu.:34516 3rd Qu.: 8184
#> Max. :6.000 Max. :34516 Max. :16692
#> Total_Trans_Ct
#> Min. : 12.00
#> 1st Qu.: 52.00
#> Median : 72.00
#> Mean : 72.24
#> 3rd Qu.: 92.00
#> Max. :132.00
customer_clean %>%
filter(Credit_Limit > 33000) %>%
hist.data.frame()
Clustering adalah salah satu teknik Machine Learning, yang memiliki kemampuan untuk mengelompokkan kumpulan data yang tidak berlabel. Setiap data yang tidak berlabel nantinya akan diklasifikasikan ke dalam kelompok tertentu dimana, titik data yang berada dalam kelompok yang sama akan memiliki sifat atau fitur yang serupa, sedangkan titik data dalam kelompok yang berbeda diharapkan memiliki sifat atau fitur yang sangat berbeda.
Dalam ilmu data, kita dapat menggunakan clustering untuk mendapatkan beberapa wawasan berharga dari data kita dengan melihat hasil pengelompokan yang terjadi. Informasi yang berharga tersebut bisa kita bawa untuk membantu kita dalam menentukan segmentasi market, social netwrok analysis, dan masih banyak lagi. Dalam kasus ini kita akan memanfatkannya untuk melakuakan segmentasi customer.
Setelah berkenalan dengan data yang kita gunakan, mari kita coba implementasikan metode PAM untuk membuat segmentasi kustomer. Secara garis besar akan ada 3 langkah yang nantinya akan dilakukan, yaitu:
Dari hasil eksplorasi data, kita mengetahui bahwa total observasi data kita adalah lebih dari 6.000 baris dan setiap observasi data pastinya memiliki nilai yang berbeda. Agar nantinya hasil dari setiap kelompok terdiri dari data-data yang identik, kita harus mengetahui jarak antara satu observasi dengan observasi lainnya berdekatan atau tidak
Di R, terdapat sebuah metode yang dapat kita manfaatkan untuk
menghitung seberapa dekat satu observasi terhadap observasi lainnya.
Metode tersebut dinamakan Gower Distance, metode Gower Distance
tersimpan pada library(cluster)
dan fungsi yang bisa
digunakan adalah daisy()
Pada fungsi tersebut nantinya akan
ada 2 parameter yang bisa diisi, yaitu:
x
: Data frame yang ingin digunakanmetric
: Metode apa yang ingin digunakan, karena kita
akan menggunakan metode Gower Distance, kita bisa isi dengan
“gower”.customer_gd <- daisy(x = customer_clean,
metric = "gower")
kita bisa mencetak pasangan yang paling mirip dan berbeda dalam data kita dengan menggunakan fungsi di bawah ini.
# Please run the code down below
example <- as.matrix(customer_gd)
customer_clean[which(example == min(example[example != min(example)]),
arr.ind = TRUE)[1, ], ]
# Please run the code down below
customer_clean[which(example == max(example[example != max(example)]),
arr.ind = TRUE)[1, ], ]
Seperti yang sudah disampaikan pada bagian pendahuluan, tujuan dari melakukan clustering adalah menempatkan setiap observasi data yang ada ke beberapa kelompok yang sesuai dengan karakteristiknya atau bedasarkan kedekatan jarak antar setiap observasi. Pada langkah pertama kita sudah memiliki informasi jarak antar setiap observasi, kita akan memanfaatkan informasi tersebut untuk menentukan berapakah kelompok yang paling optimal. Hasil dari jumlah kelompok nantinya akan digunakan untuk menentukan berapa banyak segmentasi kustomer yang bisa dibuat berdasarkan data historis pembelian kustomer.
Dalam menentukan jumlah kelompok yang paling optimum, kita data memanfaatkan metode Elbow Method. Hasil dari elbow method ini akan menghasilkan rekomendasi kelompok yang diangap paling optimum untuk digunakan.
Metode Elbow dapat kita gunakan dengan fungsi
fviz_nbclust()
dari library(factoextra)
. Pada
fungsi tersebut nantinya akan ada 3 parameter yang bisa diisi,
yaitu:
x
= data yang akan kita gunakanFUNcluster
= metode cluster yang akan kita gunakanmethod
= metode penentuan jumlah cluster yang akan
digunakan# Please type your code
set.seed(123)
elbow_method <- fviz_nbclust(x = as.matrix(customer_gd),
FUNcluster = pam,
method = "wss",
k.max = 5)
Dari hasil visualisasi di atas, kita data berasumsi bahwa K = 2 karea kita dapat melihat pada titik manakah penurunan WSS tidak terlalu signifikan, pada titik itulah nantinya kita akan manfaatkan sebagai jumlah kelompok yang paling ideal.
Dislaimer: Penentuan jumlah kelompok tidak wajib menggunakan metode pengujian di atas, penentuan kelompok juga dapat ditentukan berdasarkan pertanyaan bisnis atau kesepakatan bersama.
Sekarang kita bisa memulai tahapan terakhir yaitu mengelompokan semua
data customer ke kelompok yang sudah ditentukan dengan menggunakan
fungsi pam()
. Pada fungsi tersebut nantinya akan ada 2
parameter yang bisa diisi, yaitu:
x
= Data frame yang ingin digunakank
= Jumlah kelompok# Please type your code
pam_fit <- pam(x = customer_gd,
k = 2)
Jika dengan menggunakan metode statistik deskriptif kita bisa memahami karakteristik dari masing-masing kelompok, metode visualisasi dapat membantu kita untuk menilai bagaimana hasil pengelompokan. Metode visualisasi yang akan digunakan adalah metode t-SNE, metode ini merupakan salah satu cara untuk memvisualisasikan data yang tidak hanya memiliki nilai numerik saja melainkan nilai kategorikal juga.
# Please type your code
set.seed(123)
tsne_obj <- Rtsne(X = customer_gd,
is_distance = TRUE)
tsne_data <- tsne_obj$Y %>%
data.frame() %>%
setNames(c("X", "Y")) %>%
mutate(cluster = factor(pam_fit$clustering))
ggplot(aes(x = X, y = Y), data = tsne_data) +
geom_point(aes(color = cluster)) +
labs(title = "Visualisasi Clustering 2D") +
theme_bw() +
theme(plot.title = element_text(hjust = 0.5),
axis.title = element_blank())
Tujuan melakukan statistik deskriptif adalah untuk memahami karakteristik masing-masing kelompok, dan dalam kasus ini untuk mengetahui karakteristik untuk setiap segmentasi kustomer.
# Please type your code
pam_results <- customer_clean %>%
mutate(cluster = pam_fit$clustering) %>%
group_by(cluster) %>%
do(the_summary = summary(.))
Cluster 1:
pam_results$the_summary[[1]]
#> Customer_Age Gender Education_Level Marital_Status
#> Min. :26.00 F: 0 College : 461 Divorced: 224
#> 1st Qu.:41.00 M:3167 Doctorate : 182 Married :1511
#> Median :46.00 Graduate :1355 Single :1191
#> Mean :46.16 High School : 929 Unknown : 241
#> 3rd Qu.:52.00 Post-Graduate: 240
#> Max. :73.00
#> Income_Category Months_Inactive_12_mon Credit_Limit Total_Trans_Amt
#> $120K + : 488 Min. :0.000 Min. : 1438 Min. : 530
#> $40K - $60K : 546 1st Qu.:2.000 1st Qu.: 4116 1st Qu.: 1870
#> $60K - $80K : 997 Median :2.000 Median : 9272 Median : 3547
#> $80K - $120K :1099 Mean :2.332 Mean :13072 Mean : 4519
#> Less than $40K: 37 3rd Qu.:3.000 3rd Qu.:19444 3rd Qu.: 4766
#> Max. :6.000 Max. :34516 Max. :17995
#> Total_Trans_Ct cluster
#> Min. : 10.00 Min. :1
#> 1st Qu.: 42.00 1st Qu.:1
#> Median : 64.00 Median :1
#> Mean : 63.26 Mean :1
#> 3rd Qu.: 80.00 3rd Qu.:1
#> Max. :132.00 Max. :1
Characteristic:
Cluster 2:
pam_results$the_summary[[2]]
#> Customer_Age Gender Education_Level Marital_Status
#> Min. :26.00 F:3008 College : 444 Divorced: 231
#> 1st Qu.:41.00 M: 164 Doctorate : 199 Married :1475
#> Median :46.00 Graduate :1441 Single :1245
#> Mean :46.39 High School : 859 Unknown : 221
#> 3rd Qu.:52.00 Post-Graduate: 229
#> Max. :70.00
#> Income_Category Months_Inactive_12_mon Credit_Limit Total_Trans_Amt
#> $120K + : 0 Min. :0.000 Min. : 1438 Min. : 510
#> $40K - $60K : 726 1st Qu.:2.000 1st Qu.: 2048 1st Qu.: 2349
#> $60K - $80K : 0 Median :2.000 Median : 2873 Median : 4105
#> $80K - $120K : 0 Mean :2.354 Mean : 3914 Mean : 4273
#> Less than $40K:2446 3rd Qu.:3.000 3rd Qu.: 4489 3rd Qu.: 4747
#> Max. :6.000 Max. :23981 Max. :17437
#> Total_Trans_Ct cluster
#> Min. : 13.00 Min. :2
#> 1st Qu.: 47.00 1st Qu.:2
#> Median : 69.00 Median :2
#> Mean : 65.86 Mean :2
#> 3rd Qu.: 81.00 3rd Qu.:2
#> Max. :131.00 Max. :2
Characteristic:
Business Plan: