Dalam pengelolaan layanan keuangan, penting bagi perusahaan untuk memahami karakteristik dan perilaku nasabahnya. Salah satu metode yang efektif untuk segmentasi nasabah adalah clustering, yang memungkinkan pengelompokan nasabah berdasarkan kemiripan atribut tertentu. Pada analisis ini, metode K-Means digunakan untuk mengelompokkan nasabah kartu kredit berdasarkan data keuangan seperti saldo, pembayaran, penggunaan cash advance, dan lamanya menjadi nasabah. Hasilnya dapat membantu dalam pengambilan keputusan strategis, seperti penawaran produk yang lebih tepat sasaran atau pengelolaan risiko kredit.
Mengimpor dataset berisi informasi profil nasabah kartu kredit. Dataset ini akan digunakan untuk menganalisis pola perilaku berdasarkan data keuangan mereka.
data <- read.csv("C:/Users/dafin/Downloads/archive (5)/CC GENERAL.csv")
head(data, 10)
## CUST_ID BALANCE BALANCE_FREQUENCY PURCHASES ONEOFF_PURCHASES
## 1 C10001 40.90075 0.818182 95.40 0.00
## 2 C10002 3202.46742 0.909091 0.00 0.00
## 3 C10003 2495.14886 1.000000 773.17 773.17
## 4 C10004 1666.67054 0.636364 1499.00 1499.00
## 5 C10005 817.71434 1.000000 16.00 16.00
## 6 C10006 1809.82875 1.000000 1333.28 0.00
## 7 C10007 627.26081 1.000000 7091.01 6402.63
## 8 C10008 1823.65274 1.000000 436.20 0.00
## 9 C10009 1014.92647 1.000000 861.49 661.49
## 10 C10010 152.22598 0.545455 1281.60 1281.60
## INSTALLMENTS_PURCHASES CASH_ADVANCE PURCHASES_FREQUENCY
## 1 95.40 0.000 0.166667
## 2 0.00 6442.945 0.000000
## 3 0.00 0.000 1.000000
## 4 0.00 205.788 0.083333
## 5 0.00 0.000 0.083333
## 6 1333.28 0.000 0.666667
## 7 688.38 0.000 1.000000
## 8 436.20 0.000 1.000000
## 9 200.00 0.000 0.333333
## 10 0.00 0.000 0.166667
## ONEOFF_PURCHASES_FREQUENCY PURCHASES_INSTALLMENTS_FREQUENCY
## 1 0.000000 0.083333
## 2 0.000000 0.000000
## 3 1.000000 0.000000
## 4 0.083333 0.000000
## 5 0.083333 0.000000
## 6 0.000000 0.583333
## 7 1.000000 1.000000
## 8 0.000000 1.000000
## 9 0.083333 0.250000
## 10 0.166667 0.000000
## CASH_ADVANCE_FREQUENCY CASH_ADVANCE_TRX PURCHASES_TRX CREDIT_LIMIT PAYMENTS
## 1 0.000000 0 2 1000 201.8021
## 2 0.250000 4 0 7000 4103.0326
## 3 0.000000 0 12 7500 622.0667
## 4 0.083333 1 1 7500 0.0000
## 5 0.000000 0 1 1200 678.3348
## 6 0.000000 0 8 1800 1400.0578
## 7 0.000000 0 64 13500 6354.3143
## 8 0.000000 0 12 2300 679.0651
## 9 0.000000 0 5 7000 688.2786
## 10 0.000000 0 3 11000 1164.7706
## MINIMUM_PAYMENTS PRC_FULL_PAYMENT TENURE
## 1 139.5098 0.000000 12
## 2 1072.3402 0.222222 12
## 3 627.2848 0.000000 12
## 4 NA 0.000000 12
## 5 244.7912 0.000000 12
## 6 2407.2460 0.000000 12
## 7 198.0659 1.000000 12
## 8 532.0340 0.000000 12
## 9 311.9634 0.000000 12
## 10 100.3023 0.000000 12
Memilih kolom-kolom numerik penting yang berkaitan dengan kebiasaan pembayaran, penggunaan kartu kredit, dan lamanya menjadi nasabah. Kolom-kolom ini akan digunakan untuk clustering.
df <- data[, c('BALANCE',
'CREDIT_LIMIT',
'PAYMENTS',
'MINIMUM_PAYMENTS',
'PRC_FULL_PAYMENT',
'CASH_ADVANCE',
'CASH_ADVANCE_FREQUENCY',
'TENURE')]
head(df, 10)
## BALANCE CREDIT_LIMIT PAYMENTS MINIMUM_PAYMENTS PRC_FULL_PAYMENT
## 1 40.90075 1000 201.8021 139.5098 0.000000
## 2 3202.46742 7000 4103.0326 1072.3402 0.222222
## 3 2495.14886 7500 622.0667 627.2848 0.000000
## 4 1666.67054 7500 0.0000 NA 0.000000
## 5 817.71434 1200 678.3348 244.7912 0.000000
## 6 1809.82875 1800 1400.0578 2407.2460 0.000000
## 7 627.26081 13500 6354.3143 198.0659 1.000000
## 8 1823.65274 2300 679.0651 532.0340 0.000000
## 9 1014.92647 7000 688.2786 311.9634 0.000000
## 10 152.22598 11000 1164.7706 100.3023 0.000000
## CASH_ADVANCE CASH_ADVANCE_FREQUENCY TENURE
## 1 0.000 0.000000 12
## 2 6442.945 0.250000 12
## 3 0.000 0.000000 12
## 4 205.788 0.083333 12
## 5 0.000 0.000000 12
## 6 0.000 0.000000 12
## 7 0.000 0.000000 12
## 8 0.000 0.000000 12
## 9 0.000 0.000000 12
## 10 0.000 0.000000 12
Cek jumlah nilai yang hilang di setiap kolom.
colSums(is.na(df))
## BALANCE CREDIT_LIMIT PAYMENTS
## 0 1 0
## MINIMUM_PAYMENTS PRC_FULL_PAYMENT CASH_ADVANCE
## 313 0 0
## CASH_ADVANCE_FREQUENCY TENURE
## 0 0
Menghapus baris yang memiliki nilai kosong pada MINIMUM_PAYMENTS dan CREDIT_LIMIT untuk memastikan kualitas data sebelum pemodelan.
df <- df[!is.na(df$MINIMUM_PAYMENTS) & !is.na(df$CREDIT_LIMIT), ]
colSums(is.na(df))
## BALANCE CREDIT_LIMIT PAYMENTS
## 0 0 0
## MINIMUM_PAYMENTS PRC_FULL_PAYMENT CASH_ADVANCE
## 0 0 0
## CASH_ADVANCE_FREQUENCY TENURE
## 0 0
Visualisasi sebaran data dan deteksi outlier sebelum transformasi data. Setiap kotak menunjukkan distribusi nilai dari masing-masing fitur.
boxplot(df, main = "Boxplot", las = 2, col = rainbow(ncol(df)))
Normalisasi menggunakan Min-Max Scaling dilakukan agar semua fitur berada dalam rentang 0 hingga 1 sehingga semua fitur memiliki kontribusi yang seimbang dalam proses clustering. Kemudian, menampilkan boxplot untuk melihat kembali distribusi setelah scaling untuk memastikan data sudah berada dalam skala yang seragam.
df_minmax <- as.data.frame(lapply(df, function(x) (x - min(x)) / (max(x) - min(x))))
boxplot(df_minmax, main = "Boxplot setelah Min-Max Scaling",
las = 2,
col = rainbow(ncol(df_minmax)))
Menggunakan metode Within-Cluster Sum of Squares (WSS) untuk menentukan jumlah cluster optimal. Titik “siku” (elbow) menunjukkan jumlah cluster ideal, dalam hal ini 3 cluster.
library(factoextra)
## Warning: package 'factoextra' was built under R version 4.4.3
## Loading required package: ggplot2
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
fviz_nbclust(df_minmax, kmeans, method = "wss") +
geom_vline(xintercept = 3, linetype = 2) +
labs(subtitle = "Metode Elbow untuk Menentukan Jumlah Klaster Optimal")
Menerapkan K-Means dengan 3 cluster dan 25 kali inisialisasi acak untuk hasil yang stabil. Output berisi pusat cluster dan jumlah data dalam masing-masing cluster.
clustering = kmeans(df_minmax, centers=3, nstart =25)
clustering$size
## [1] 1304 6677 655
clustering$centers
## BALANCE CREDIT_LIMIT PAYMENTS MINIMUM_PAYMENTS PRC_FULL_PAYMENT
## 1 0.01003726 0.16929885 0.04414600 0.002745948 0.78968665
## 2 0.10045071 0.15062142 0.03522058 0.013510213 0.03995603
## 3 0.06465979 0.09625984 0.01692912 0.005953665 0.12092875
## CASH_ADVANCE CASH_ADVANCE_FREQUENCY TENURE
## 1 0.003169395 0.0124997 0.9573108
## 2 0.023395908 0.1005103 0.9831262
## 3 0.033275343 0.1600408 0.2338422
clustering$withinss
## [1] 114.86390 427.27116 96.68048
clustering$betweenss / clustering$totss
## [1] 0.6042447
names(clustering)
## [1] "cluster" "centers" "totss" "withinss" "tot.withinss"
## [6] "betweenss" "size" "iter" "ifault"
Visualisasi penyebaran data berdasarkan hasil clustering. Warna berbeda menunjukkan cluster yang berbeda.
fviz_cluster(clustering, data= df_minmax)+ggtitle("Clustering")
Menambahkan hasil cluster ke dalam dataset untuk dianalisis lebih lanjut.
hasil = data.frame(df_minmax, clustering$cluster)
head(hasil, 10)
## BALANCE CREDIT_LIMIT PAYMENTS MINIMUM_PAYMENTS PRC_FULL_PAYMENT
## 1 0.002147795 0.03171953 0.003977659 0.001825646 0.000000
## 2 0.168169097 0.23205342 0.080892490 0.014034479 0.222222
## 3 0.131026136 0.24874791 0.012263400 0.008209618 0.000000
## 4 0.042940103 0.03839733 0.013372754 0.003203563 0.000000
## 5 0.095038365 0.05843072 0.027601906 0.031505653 0.000000
## 6 0.032938940 0.44908180 0.125277705 0.002592025 1.000000
## 7 0.095764295 0.07512521 0.013387152 0.006962981 0.000000
## 8 0.053296176 0.23205342 0.013568801 0.004082709 0.000000
## 9 0.007993744 0.36560935 0.022963094 0.001312500 0.000000
## 10 0.067905032 0.03839733 0.021356878 0.028435898 0.000000
## CASH_ADVANCE CASH_ADVANCE_FREQUENCY TENURE clustering.cluster
## 1 0.0000000 0.0000000 1 2
## 2 0.1366849 0.1666667 1 2
## 3 0.0000000 0.0000000 1 2
## 4 0.0000000 0.0000000 1 2
## 5 0.0000000 0.0000000 1 2
## 6 0.0000000 0.0000000 1 1
## 7 0.0000000 0.0000000 1 2
## 8 0.0000000 0.0000000 1 2
## 9 0.0000000 0.0000000 1 2
## 10 0.0000000 0.0000000 1 2
Menampilkan jumlah data (nasabah) dalam masing-masing cluster. Untuk membantu memahami distribusi segmentasi.
library(ggplot2)
ggplot(data.frame(cluster = as.factor(clustering$cluster)), aes(x = cluster)) +
geom_bar(fill = "steelblue") +
labs(title = "Jumlah Data per Cluster",
x = "Cluster",
y = "Jumlah Observasi") +
theme_minimal()
Silhouette Score digunakan untuk mengevaluasi sejauh mana objek cocok dengan clusternya sendiri dibandingkan dengan cluster lain. Plot silhouette menunjukkan hasil klasterisasi menjadi tiga kelompok dengan rata-rata nilai silhouette sebesar 0,58, yang menandakan pemisahan antar klaster cukup baik. Klaster 2 mendominasi dengan anggota terbanyak dan kualitas pemisahan yang relatif tinggi, sementara klaster 1 dan 3 memiliki lebih sedikit anggota dan sebagian nilainya lebih rendah, mengindikasikan adanya tumpang tindih pada beberapa data.
library(cluster)
## Warning: package 'cluster' was built under R version 4.4.3
sil <- silhouette(clustering$cluster, dist(df_minmax))
fviz_silhouette(sil)
## cluster size ave.sil.width
## 1 1 1304 0.52
## 2 2 6677 0.61
## 3 3 655 0.41
Melihat rata-rata setiap fitur dalam masing-masing cluster untuk mendeskripsikan karakteristik unik dari setiap segmen nasabah.
aggregate(df_minmax, by=list(cluster=clustering$cluster), mean)
## cluster BALANCE CREDIT_LIMIT PAYMENTS MINIMUM_PAYMENTS PRC_FULL_PAYMENT
## 1 1 0.01003726 0.16929885 0.04414600 0.002745948 0.78968665
## 2 2 0.10045071 0.15062142 0.03522058 0.013510213 0.03995603
## 3 3 0.06465979 0.09625984 0.01692912 0.005953665 0.12092875
## CASH_ADVANCE CASH_ADVANCE_FREQUENCY TENURE
## 1 0.003169395 0.0124997 0.9573108
## 2 0.023395908 0.1005103 0.9831262
## 3 0.033275343 0.1600408 0.2338422
K-Means berhasil mengelompokkan nasabah menjadi tiga tipe utama: nasabah disiplin (klaster 1), nasabah aktif namun sedang (klaster 2), dan nasabah baru yang berisiko lebih tinggi (klaster 3). Berikut masing-masing karakteristiknya:
Hasil informasi ini dapat digunakan untuk penentuan strategi pemasaran, manajemen risiko, dan kebijakan kredit yang lebih tepat sasaran.