Dalam suatu industri yang memiliki produk yang dijual, transaksi jual beli sering terjadi. Transaksi tersebut terjadi baik diantara produsen dengan konsumen secara langsung, maupun produsen dengan distributor. Para distributor maupun konsumen tersebut akan dianggap sebagai customer. Customer merupakan hal yang esensial dalam suatu transaksi dan tentunya untuk kemajuan pada suatu industri tersebut. Adanya customer akan membuat industri dapat menjalankan roda bisnisnya dengan baik dan dapat menciptakan sebuah produk sesuai dengan kebutuhan customer.
Dalam mengolah hubungan antara customer dengan industri sendiri tentunya perlu dibuat sebuah strategi agar customer selalu loyal dan tetap membeli produk yang dijual. Oleh karenanya banyak sekali strategi yang digunakan mulai dari pemberian diskon produk, bonus produk setiap membeli berapa banyak produk, dan lain sebagainya. Agar strategi marketing untuk mempertahankan customer tidak salah sasaran, tentunya pemberian promosi ini perlu dipetakan berdasarkan value pada customer.
Untuk melakukan analisa segmentasi customer berdasarkan ‘nilai’ yang mereka miliki, maka disini akan digunakan data sebuah transaksi perusahaan retail yang berbasis di United Kingdom. Data dapat diunduh melalui laman UCI Machine Learning. Data yang akan digunakan adalah data transaksi yang terjadi dari 01/12/2010 hingga 30/11/2011.
Berikut ini gambaran dari dataset yang digunakan.
online_df <- read.csv("data_input/online_retail_II_2010-2011.csv", stringsAsFactors = F)
head(online_df, 10)Data terdiri dari 541,910 observasi dan 8 variabel. Berikut ini gambaran jumlah baris dan kolomnya.
Note: Jumlah baris dan kolom ini merupakan jumlah baris data yang masih raw dan masih perlu dibersihkan terlebih dahulu menjadi data yang siap dianalisis.
Agar lebih seragam dalam penulisan nama kolom, maka akan diubah terlebih format penulisan masing-masing setiap kolom kedalam huruf kecil dan setiap kata dipisahkan oleh underscore.
colnames(online_df) <- tolower(colnames(online_df))
online_df <- online_df %>%
rename("invoice_no" = invoice,
"stock_code" = stockcode,
"invoice_date" = invoicedate,
"price" = price,
"customer_id" = customer.id)
colnames(online_df)#> [1] "invoice_no" "stock_code" "description" "quantity" "invoice_date"
#> [6] "price" "customer_id" "country"
Berikut penjelasan untuk masing-masing variabel yang ada:
| Variable | Description |
|---|---|
invoice_no |
Merupakan nomor transaksi. Terdiri dari 6 digit angka yang bersifat unik setiap transaksi. Kemudian, jika nomor transaksi diawali huruf C maka artinya transaksi tersebut dicancel. |
stock_code |
Merupakan kode produk yang terdiri dari 5 digit angka yang bersifat unik. |
description |
Nama produk. |
quantity |
Jumlah per produk yang dibeli setiap transaksi. |
invoice_date |
Waktu transaksi. |
price |
Harga setiap produk persetiap transaksi. |
customer_id |
ID customer yang terdiri dari 5 digit angka yang bersifat unik setiap customer. |
country |
Negara asal customer ketika melakukan transaksi. |
Berdasarkan informasi yang terkandung dalam variabel tersebut, maka sebelumnya akan dipastikan semua data yang akan digunakan merupakan data transaksi yang valid. Oleh karena itu, akan coba dibersihkan terlebih dahulu datanya.
Berdasarkan informasi variabel invoice_no, quantity, unit_price, stock_code, dan customer_id dapat diketahui transaksi mana yang valid dan tidak. Berikut transaksi yang akan kita hapus berdasarkan transaksi yang tidak valid:
invoice_noquantity = 0unit_price = 0, karena tidak ada keterangan lebih lanjut mengenai transaksi ini, maka akan dihapusstock_code yang valid terdiri dari 5 digit angkacustomer_id yang valid terdiri dari 5 digit angkaonline_df_clean <- online_df %>%
filter(!str_detect(invoice_no, "C"), !nchar(invoice_no)>6, quantity > 0, price > 0) %>%
mutate(stock_code = toupper(stock_code),
stock_code_nchar = nchar(stock_code)) %>%
filter(!stock_code_nchar %in% c(1:4), !stock_code %in% c("AMAZONFEE", "BANK CHARGES", "GIFT_0001_10",
"GIFT_0001_20", "GIFT_0001_20", "GIFT_0001_30",
"GIFT_0001_40","GIFT_0001_50")) %>%
select(-stock_code_nchar)
data.frame(n_observations = format(nrow(online_df_clean), big.mark = ","), n_columns = ncol(online_df_clean))Berdasarkan suatu artikel yang pernah dipublish oleh Diego Usai mengenai Market Basket Analysis berdasarkan suatu transaksi online, ditemukan 50 transaksi dengan deskripsi produk yang diinput secara manual. Produk tersebut dapat diindikasikan tidak valid.
descr <- c( "check", "check?", "?", "??", "damaged", "found",
"adjustment", "Amazon", "AMAZON", "amazon adjust",
"Amazon Adjustment", "amazon sales", "Found", "FOUND",
"found box", "Found by jackie ","Found in w/hse","dotcom",
"dotcom adjust", "allocate stock for dotcom orders ta", "FBA",
"Dotcomgiftshop Gift Voucher £100.00", "on cargo order",
"wrongly sold (22719) barcode", "wrongly marked 23343",
"dotcomstock", "rcvd be air temp fix for dotcom sit",
"Manual", "John Lewis", "had been put aside",
"for online retail orders", "taig adjust", "amazon",
"incorrectly credited C550456 see 47", "returned",
"wrongly coded 20713", "came coded as 20713",
"add stock to allocate online orders", "Adjust bad debt",
"alan hodge cant mamage this section", "website fixed",
"did a credit and did not tick ret", "michel oops",
"incorrectly credited C550456 see 47", "mailout", "test",
"Sale error", "Lighthouse Trading zero invc incorr", "SAMPLES",
"Marked as 23343", "wrongly coded 23343","Adjustment",
"rcvd be air temp fix for dotcom sit", "Had been put aside." )
online_df_clean %>%
filter(description %in% descr) %>%
arrange(stock_code)Apabila diperhatikan berdasarkan deskripsi produk, produk dengan invoice_id 562113 merupakan sebuah gift voucher. Oleh karena itu akan dihapus.
Berdasarkan informasi variabel, stock_code bersifat unik. Oleh karena itu apabila terdapat stock_code dengan deskripsi yang sama, maka akan dihapus.
df_products <- online_df_clean %>%
arrange(desc(invoice_date)) %>% #to get the last named of stock code and description
select(stock_code, description) %>%
distinct()
df_products %>%
group_by(stock_code) %>%
summarise(description_count=n()) %>%
ungroup() %>%
filter(description_count>1)Terdapat 215 stock_code yang terduplikasi, maka akan dihapus. Pada case ini, akan disamakan terlebih dahulu deskripsi produk dengan transaksi terakhirnya.
df_products <- df_products %>%
group_by(stock_code) %>%
slice(1)
online_df_clean <- online_df_clean %>% left_join(df_products, by = c("stock_code" = "stock_code")) %>%
mutate(description=description.y) %>%
select(-description.x,-description.y)
data_frame(
stock_code_unique = online_df_clean$stock_code %>% unique() %>% length(),
description_unique = online_df_clean$description %>% unique() %>% length(),
stock_description_unique = online_df_clean %>% select(stock_code,description) %>% distinct() %>% nrow()
)Selanjutnya, akan disamakan juga stock_code berdasarkan transaksi terakhir yang dilakukan.
df_description <- online_df_clean %>%
arrange(desc(invoice_date)) %>% #to get the last named of stock code and description
select(stock_code,description) %>%
distinct()
df_description <- df_description %>%
group_by(description) %>%
slice(1)
online_df_clean <- online_df_clean %>% left_join(df_description, by = c("description" = "description")) %>%
mutate(stock_code=stock_code.y) %>%
select(-stock_code.x,-stock_code.y)
data_frame(
stock_code_unique = online_df_clean$stock_code %>% unique() %>% length(),
description_unique = online_df_clean$description %>% unique() %>% length(),
stock_description_unique = online_df_clean %>% select(stock_code,description) %>% distinct() %>% nrow()
)Selain itu, apabila ditinjau lebih lanjut, setiap customer seharusnya memiliki 1 negara. Apabila terdapat 1 customer memiliki lebih dari 1 negara, maka kemungkinan terdapat customer yang sudah pindah negara, maka data akan kita sesuaikan dengan transaksi di negara terakhir customer tersebut.
data_frame(
customer_unik = online_df_clean %>% select(customer_id) %>% distinct() %>% nrow(),
country_unik = online_df_clean %>% select(customer_id,country) %>% distinct() %>% nrow()
)df_country <- online_df_clean %>%
arrange(desc(invoice_date,customer_id)) %>% #country that used at the last transaction.
select(customer_id, country) %>%
group_by(customer_id) %>%
slice(1)
online_df_clean <- online_df_clean %>% select(-country) %>%
left_join(df_country, by = c("customer_id" = "customer_id"))
data_frame(
customer_unik = online_df_clean %>% select(customer_id) %>% distinct() %>% nrow(),
country_unik = online_df_clean %>% select(customer_id,country) %>% distinct() %>% nrow()
)online_df_clean <- online_df_clean %>% distinct()Untuk memastikan data memang benar-benar siap untuk digunakan analisis, maka perlu dipastikan juga adakah missing value pada data. Apabila dicek, terdapat 131,420 missing data pada kolom customer_id.
colSums(is.na(online_df_clean))#> invoice_no quantity invoice_date price customer_id description
#> 0 0 0 0 131352 0
#> stock_code country
#> 0 0
Missing data tersebut akan dihapus agar tidak mengganggu proses analisa data nantinya.
online_df_clean <- online_df_clean %>%
filter(complete.cases(customer_id))Tipe data pada setiap variabel harus tepat agar proses pengambilan insight pada data juga tepat.
glimpse(online_df_clean)#> Rows: 391,113
#> Columns: 8
#> $ invoice_no <chr> "536365", "536365", "536365", "536365", "536365", "536365…
#> $ quantity <int> 6, 6, 8, 6, 6, 2, 6, 6, 6, 6, 3, 3, 3, 32, 6, 6, 8, 6, 6,…
#> $ invoice_date <chr> "12/1/2010 8:26", "12/1/2010 8:26", "12/1/2010 8:26", "12…
#> $ price <dbl> 2.55, 3.39, 2.75, 3.39, 3.39, 7.65, 4.25, 1.85, 1.85, 4.2…
#> $ customer_id <int> 17850, 17850, 17850, 17850, 17850, 17850, 17850, 17850, 1…
#> $ description <chr> "WHITE HANGING HEART T-LIGHT HOLDER", "WHITE METAL LANTER…
#> $ stock_code <chr> "85123A", "71053", "84406B", "84029G", "84029E", "22752",…
#> $ country <chr> "United Kingdom", "United Kingdom", "United Kingdom", "Un…
Pada hasil cek tipe data diatas, akan diubah beberapa kolom berikut sesuai dengan tipe data yang tepat:
invoice_date -> datecountry -> factorSelain itu akan dibuat kolom baru dengan nama total_price yang diperoleh dari perkalian anatara kolom quantity dan price.
online_df_clean <- online_df_clean %>%
mutate(invoice_date = as.Date(invoice_date, "%m/%d/%Y %H:%M"),
country = as.factor(country),
total_price = quantity*price)
head(online_df_clean, 10)Terakhir, apabila diperhatikan pada data yang ada, transaksi dilakukan pada tanggal 01 Januari 2010 hingga 09 Desember 2011. Apabila memiliki kebutuhan untuk mengetahui rata-rata penjualan perbulan, sepertinya akan kurang adil jika data pada bulan Desember hanya 9 hari saja. Oleh karena itu, pada analisis ini, data pada bulan Desember akan dihapus terlebih dahulu. Selain itu, pada analisis ini, akan diambil customer yang melakukan pembelian hanya di United Kingdom saja.
range(online_df_clean$invoice_date)#> [1] "2010-12-01" "2011-12-09"
df_customer <- online_df_clean %>%
filter(invoice_date < "2011-12-01", country == "United Kingdom")Berikut hasil akhir data yang akan digunakan dalam analisis recency, frequency, dan monetary (RFM) berdasarkan transaksi pelanggan.
head(df_customer)RFM Analysis merupakan salah satu metode analisis yang digunakan untuk segmentasi customer berdasarkan informasi kebiasaan dari customer itu sendiri. Adapun metrik yang akan dianalisa adalah sebagai berikut:
Metrik-metrik dalam RFM biasanya akan digunakan untuk mengetahui karakteristik dari suatu customer. Selain itu bisa digunakan juga untuk mengetahui value dari suatu customer. Apakaoh customer A termasuk customer yang loyal? Apakah customer A termasuk customer yang selalu melakukan transaksi yang cukup besar? dan lain sebagainya. Menggunakan metrik tersebut, akan dibuat suatu segmen customer berdasarkan nilainya yaitu high-value, medium-value, dan low-value.
Seperti yang sudah dijelaskan pada bagian sebelumnya, recency akan melihat berapa lama waktu customer dalam melakukan transaksi terakhirnya. Oleh karena itu untuk mendapatkan nilai recency, perlu diketahui terlebih dahulu tanggal terakhir customer melakukan transaksi. Selanjutnya akan diselisihkan hari terakhir customer melakukan transaksi dengan hari melakukan analisis. Sebagai asumsi, hari analisis diperoleh dari hari terakhir transaksi + 1.
# hari analisis
date_analysis <- date(max(df_customer$invoice_date))+days(1)
date_analysis#> [1] "2011-12-01"
# hari terakhir transaksi customer
df_recency <- df_customer %>%
group_by(customer_id) %>%
summarise(first_order = min(invoice_date),
last_order = max(invoice_date)) %>%
ungroup()
head(df_recency)# recency
df_recency <- df_recency %>%
group_by(customer_id) %>%
summarise(recency = as.integer(date_analysis - last_order),
age_cust = as.integer(date_analysis - first_order))
head(df_recency)Apabila dilihat dari hasil tabel diatas, diketahui bahwa customer dengan customer_id 12346 sudah selama 317 hari yang lalu. Artinya customer 12346 sudah cukup lama tidak berbelanja pada toko tersebut. Sedangkan customer 12748 baru 2 hari yang lalu melakukan transaksi terakhir, artinya customer ini masih baru sekali berbelanja di toko tersebut.
Untuk mengetahui seberapa sering customer melakukan transaksi, dapat dianalisa dari nilai frekuensi pembelanjaan dari masing-masing customer.
df_customer_rfm <- df_customer %>%
group_by(customer_id, invoice_no) %>%
summarise(freq = n()) %>%
ungroup() %>%
group_by(customer_id) %>%
summarise(avg_basket = round(median(freq))) %>%
ungroup()
df_frequency <- df_customer %>%
select(customer_id, invoice_no) %>%
distinct() %>% # mengambil informasi transaksi yang unik
group_by(customer_id) %>%
summarise(frequency = n()) %>%
ungroup() %>%
left_join(df_customer_rfm, by = c("customer_id" = "customer_id"))
head(df_frequency)Melihat customer 12346 yang sudah cukup lama berbelanja, jika dilihat dari seberapa sering berbelanja di toko tersebut juga hanya 1 kali, sangat tidak sering. Berbeda dengan customer 12748 sangat cukup sering berbelanja terlihat sudah sebanyak 197 kali berbelanja di toko tersebut.
Selanjutnya yaitu monetary, seberapa banyak pengeluaran customer dalam setiap transaksi. Nilai monetary dapat diperoleh dari perkalian harga barang yang dibeli dengan jumlah barang yang dibeli dalam satu kali transaksi. Sebelumnya pernah dibuat kolom total_price yang menunjukkan hasil perkalian antraa price dan quantity. Langkah selanjutnya adalah menjumlahkan total_price dari masing-masing customer.
df_monetary <- df_customer %>%
group_by(customer_id) %>%
summarise(monetary = sum(total_price),
avg_spend = median(total_price))
head(df_monetary)Kembali lagi pada customer 12346 jika dilihat pernah melakukan satu kali transaksi dan sudah lama sekali tidak melakukan transaksi kembali namun dalam satu kali transaksi tersebut termasuk transaksi yang cukup besar dengan besaran pengeluarannya yaitu £77,183.60. Sedangkan jika melihat customer 12748 besaran pengeluaran yang dilakukan dalam 197 transaksi tersebut yaitu £30,652.63 dengan rata-rata pengeluarannya yaitu £3.75
Selanjutnya setiap informasi yang sudah diperoleh baik, recency, frequency dan monetary akan digabungkan dalam 1 dataframe agar mudah dilakukan analisis untuk segmentasi customer.
customer_rfm <- df_recency %>%
left_join(df_frequency) %>%
left_join(df_monetary) %>%
select(customer_id, age_cust, recency, frequency, monetary, avg_basket, avg_spend)
head(customer_rfm, 10)Berikut penjelasan dari masing-masing variabel diatas:
| Variable | Description |
|---|---|
customer_id |
ID customer |
age_cust |
Usia customer, diperoleh dari selisih hari pertama bertransaksi dengan hari analisis |
recency |
Selisih hari terakhir bertransaksi dengan hari analisis |
frequency |
Jumlah transaksi yang dilakukan oleh customer |
monetary |
Besar pengeluaran yang dilakukan oleh customer |
avg_basket |
Rata-rata jumlah produk yang dibeli oleh customer per transaksi |
avg_spend |
Rata-rata besar pengeluaran yang dilakukan customer per transaksi |
Berdasarkan distribusi usia customee tersebut terlihat bahwa kebanyakan customer memiliki usiang 364 hari atau bisa dianggap 1 tahun. Hal ini cukup masuk akal karena data yang digunakan merupakan data transaksi satu tahun saja, sehingga usia customer terlama pun juga pada 364 hari.
Berdasarkan transaksi per bulannya, diketahui bahwa transaksi paling rendah terjadi pada bulan Januari 2011 sedangkan transaksi tertinggi terjadi pada bulan November 2011.
Segmentasi customer kali ini akan membagi beberapa customer kedalam segmen high-value, medium-value, dan low-value.
Recency merupakan salah satu metrik yang bisa digunakan untuk mengetahui nilai dari suatu customer. Tujuannya adalah agar ketika ingin memberikan suatu promosi terhadap customer tidak salah target dan tidak memperbesar biaya campaign. Berdasarkan nilai recency bisa diketahui customer yang masih aktif bertransaksi dan yang sudah tidak aktif. Pada kasus ini, akan dibuat sebuah nilai kuartil yang membagi customer berdasarkan recency dengan ketentuan sebagai berikut:
Berdasarkan informasi diatas digambarkan proporsi customer berdasarkan transaksi terakhirnya. Misal perusahaan ingin memberikan campaign pada segmen customer diatas seperti:
Dua metrik frequency dan monetary memiliki jenis penilaian yang sama, yaitu customer yang bisa dianggap loyal adalah customer yang sering membeli dan pengeluaran setiap membeli produk cukup besar. Untuk dapat melakukan segmentasi customer yang bisa disebut high-value, medium-value, dan low-value, maka akan digunakan kedua metrik tersebut dengan cara melakukan clustering.
customer_rfm %>%
select(frequency, monetary) %>%
ggplot(aes(x = frequency, y = monetary))+
geom_point()+
geom_smooth(method = "lm", col = "firebrick")+
labs(x = "Frequency", y = "Monetary", title = "Correlation between Frequency and Monetary")+
scale_y_continuous(labels = label_number(prefix = "£ ", big.mark = ","))+
theme_minimal()Berdasarkan informasi pada plot tersebut diketahui bahwa kebanyakan customer yang sering melakukan transaksi, besaran transaksi yang dilakukan memiliki nilai yang cukup kecil. Berdasarkan informasi pada sebaran antara frequency dan monetary masing-masing customer diketahui bahwa terdapat banyak sekali beberapa nilai outlier. Artinya beberapa customer memiliki pengeluaran yang cukup besar sekali dan secara frekuensi berbelanja juga sangat sering sekali. Outlier pada data tersebut perlu dikeluarkan terlebih dahulu agar tidak mengganggu proses clustering.
library(FactoMineR)
library(factoextra)
fm_cust <- customer_rfm %>% select(customer_id, frequency, monetary) %>%
column_to_rownames(var = "customer_id")
fm_pca <- PCA(fm_cust, scale.unit = T, graph = F)
plot.PCA(fm_pca, select = "contrib30")Diperoleh 20 data customer yang termasuk outlier yaitu sebagai berikut:
outlier_cust <- c("12346", "17511", "17450", "18102", "16029", "15311", "12971", "13089", "14606",
"17841", "12748", "16684", "15769", "14298", "17949", "13694", "15061", "13408",
"16422", "13798")
#, "15749", "15098", "12931", "16013", "15039", "14527", "14088",
#"17389", "15189", "14096")Perlu dibuang terlebih dahulu dan bisa dijadikan satu kelompok sendiri dengan kriteria yang bisa juga berbeda.
customer_rfm_cluster <- customer_rfm %>%
filter(!customer_id %in% outlier_cust)
head(customer_rfm_cluster)Selanjutnya dibuat clustering berdasarkan nilai frequency dan monetary. Metode clustering yang digunakan yaitu K-Means, dimana k-means akan mengelompokkan setiap data kedalam beberapa kelompok berdasarkan kedekatan jarak antar observasi. Semakin dekat jarak antar observasi dinilai semakin mirip karakteristiknya. Semakin jauh jarak antar observasi dinilai semakin berbeda karakteristiknya. K-means menggunakan perhitungan jarak euclidean distance yang mana secara formula mirip sekali dengan formula pytaghoras.
Pada kasus ini, karena setiap customer ingin dikelompokkan dalam 3 segmen, high, medium, dan low maka jumlah cluster yang akan dibentuk sebanyak 3.
set.seed(100)
cust_rfm_scale <- customer_rfm_cluster %>%
column_to_rownames(var = "customer_id") %>%
select(-recency_segment) %>%
mutate_if(.predicate = is.numeric, scale)
cust_kmeans <- kmeans(cust_rfm_scale %>% select(frequency, monetary), centers = 3)
fviz_cluster(cust_kmeans, cust_rfm_scale %>% select(frequency, monetary), palette = "Set2")+
labs(x = "Frequency", y = "Monetary")+
theme_minimal()Diperoleh hasil clustering berdasarkan variabel frequency dan monetary dimana cluster 1 digambarkan dengan warna hijau, cluster 2 digambarkan dengan warna biru, dan cluster 3 digambarkan dengan warna merah. Masing-masing cluster memiliki karakteristik sebagai berikut:
# data customer outlier
customer_outlier <- customer_rfm %>%
filter(customer_id %in% outlier_cust) %>%
mutate(fm_segment = 4)
# menggabungkan data customer outlier dengan hasil cluster
customer_rfm <- customer_rfm_cluster %>%
mutate(fm_segment = cust_kmeans$cluster) %>%
rbind.data.frame(customer_outlier) %>%
mutate(fm_segment = as.factor(fm_segment))
profiling_cluster <- customer_rfm %>%
group_by(fm_segment) %>%
summarise(min_monetary = min(monetary),
max_monetary = max(monetary),
avg_monetary = mean(monetary),
med_monetary = median(monetary),
min_freq = min(frequency),
max_freq = max(frequency),
avg_freq = mean(frequency),
med_freq = median(frequency),
min_recency = min(recency),
max_recency = max(recency),
avg_recency = mean(recency),
med_recency = median(recency),
avg_basket = mean(avg_basket),
avg_spend = mean(avg_spend)
) %>%
ungroup()
profiling_clusterBerdasarkan hasil profiling cluster diatas dapat diketahui bahwa cluster 4 memiliki nilai rata-rata recency paling rendah, nilai rata-rata frequency serta monetary paling tinggi karena cluster ini merupakan data-data outlier. Cluster 1 memiliki rata-rata recency paling rendah berdasarkan hasil clustering, dan frequency serta monetary paling tinggi. Sedangkan cluster 3 memiliki recency tidak terlalu rendah, nilai rata-rata frequency serta monetary tidak terlalu tinggi. Sedangkan cluster 2 memiliki rata-rata recency paling tinggi, namun frequency dan monetary paling rendah. Oleh karena itu, dapat disimpulkan bahwa hasil profiling cluster yang diperoleh adalah sebagai berikut:
High ValueLow ValueMedium ValueSpecial ValueBerikut gambaran sebaran masing-masing segmen customer berdasarkan sebaran frequency dan monetarynya.
customer_rfm <- customer_rfm %>%
mutate(fm_segment = factor(fm_segment, levels = c("4", "1", "3", "2"),
labels = c("Special Value", "High Value",
"Medium Value", "Low Value")))
plot_segment <- customer_rfm %>%
ggplot(aes(x = frequency, y = monetary, text = glue("Customer ID : {customer_id}
Customer Value : {fm_segment}
Frequency : {frequency}
Monetary : £ {comma(monetary)}")))+
geom_point(aes(col = fm_segment), size = 3, alpha = 0.7)+
scale_color_manual(values = c("#D68F91", "#B63639", "#ae2024", "#561011"))+
labs(title = "Customer Value Segmentation", x = "Frequency", y = "Monetary")+
theme_minimal()
ggplotly(plot_segment, tooltip = "text")Setelah dilakukan segmentasi berdasarkan informasi dari RFM, maka berikut hasil summary segmentasi customernya.
Dapat diketahui bahwa berdasarkan beberapa customer yang sudah melakukan transaksi, lebih banyak customer yang tergolong low-value dan sudah tidak aktif bertransaksi lagi. Selain itu juga customer yang terdapat pada United Kingdom kebanyakan merupakan low-value customer. Hal ini cukup riskan bagi perusahaan apabila memiliki customer yang lebih banyak masuk dalam segmentasi low-value dan inactive karena akan menurunkan performa penjualan dari perusahaan.
Apabila ditelusuri lebih lanjut besaran pendapatan yang diperoleh dalam hal ini akan menggunakan nilai monetary dari masing-masing segmen customer adalah sebagai berikut.
plot_total_monetary <- customer_rfm %>%
group_by(recency_segment) %>%
summarise(freq = n(),
percentage_cust = round((freq/nrow(customer_rfm))*100,2),
total_monetary = sum(monetary),
percentage_monetary = round((total_monetary/sum(customer_rfm$monetary))*100,2)) %>%
ungroup() %>%
mutate(recency_segment = factor(recency_segment, levels = c("Inactive","Slight Inactive",
"Slight Active","Active"))) %>%
ggplot(aes(x = total_monetary, y = recency_segment, text = glue("Total Customer: {freq} ({percentage_cust})%
Total Monetary: £ {comma(total_monetary)}"), label = glue("{percentage_monetary}%")))+
geom_col(aes(fill = recency_segment))+
scale_fill_manual(values = c("#D68F91", "#B63639", "#ae2024", "#561011"))+
scale_x_continuous(labels = label_number(prefix = "£ ", big.mark = ","))+
labs(title = "Total Monetary based on Recency Segment", y = NULL, x = "Total Monetary")+
geom_text(aes(x = total_monetary+250000), hjust = -0.5)+
theme_minimal()
ggplotly(plot_total_monetary, tooltip = "text")%>%
layout(showlegend=FALSE) %>%
config(displayModeBar = F)Berdasarkan plot diatas dapat diketahui bahwa customer yang masih aktif memberikan besaran pembelian yang paling banyak, hal ini dapat diasumsikan bahwa customer yang aktif masih memberikan penjualan terbesar.
plot_total_monetary <- customer_rfm %>%
group_by(fm_segment) %>%
summarise(freq = n(),
percentage_cust = round((freq/nrow(customer_rfm))*100,2),
total_monetary = sum(monetary),
percentage_monetary = round((total_monetary/sum(customer_rfm$monetary))*100,2)) %>%
ungroup() %>%
mutate(fm_segment = factor(fm_segment, levels = c("Low Value","Medium Value",
"High Value","Special Value"))) %>%
ggplot(aes(x = total_monetary, y = fm_segment, text = glue("Total Customer: {freq} ({percentage_cust}%)
Total Monetary: £ {comma(total_monetary)}"), label = glue("{percentage_monetary}%")))+
geom_col(aes(fill = fm_segment))+
scale_fill_manual(values = c("#D68F91", "#B63639", "#ae2024", "#561011"))+
scale_x_continuous(labels = label_number(prefix = "£ ", big.mark = ","))+
labs(title = "Total Monetary based on Customer Value", y = NULL, x = "Total Monetary")+
geom_text(aes(x = total_monetary+250000), hjust = -0.5)+
theme_minimal()
ggplotly(plot_total_monetary, tooltip = "text")%>%
layout(showlegend=FALSE) %>%
config(displayModeBar = F)Sedangkan apabila dilihat dari value pada suatu customer, lebih banyak customer dengan segmen Low Value yang cenderung memberikan penjualan terbesar yaitu sebesar 35.75%. Sedangkan customer dengan segmen High Value memberikan penjualan terendah yaitu hanya sebesar 14.61% dari total penjualan yang ada.
Berdasarkan hasil segmentasi customer dapat diberikan rekomendasi dalam memastikan pelanggan tetap selalu loyal diantaranya: