Sử dụng python cụm phân cấp

Trước khi tải bộ dữ liệu, chỉ sử dụng các tính năng số rồi truy xuất những khách hàng đã từ bỏ sử dụng dịch vụ

#=========================
#    K-means clustering
#=========================

# Load data: 
rm[list = ls[]]

library[tidyverse]

read_csv["//raw.githubusercontent.com/treselle-systems/customer_churn_analysis/master/WA_Fn-UseC_-Telco-Customer-Churn.csv"] -> all_data

# Filter customers churned: 

all_data %>% 
  filter[Churn == "Yes"] %>% 
  select[tenure, MonthlyCharges, TotalCharges, customerID] -> raw_data

Là một nhóm thuật toán dựa trên khoảng cách nên K-mean phân cụm rất nhạy cảm với các ngoại lệ. Để loại bỏ/hạn chế ảnh hưởng của các ngoại lệ, chúng ta có thể sử dụng tiêu chuẩn hóa 0-1 cho tất cả các tính năng

# Customer ID: 

churned_ID % 
  select[-customerID] %>% 
  mutate_all[function[x] {[x - min[x]] / [max[x] - min[x]]}] -> data_scaled

Thuật toán phân cụm K-mean đòi hỏi phải xác định trước cụm số K. Chúng ta có thể tìm số cụm tối ưu bằng phương pháp khuỷu tay như sau

# Calculate WSS from a range of k: 
wss2 % filter[k == 4], color = "red", size = 3] + 
  scale_x_continuous[breaks = seq[1, 10, by = 1]] + 
  labs[title = "Figure 1: The Optimal Number of Clusters, Elbow Method", x = "Number of Clusters [K]"] + 
  theme[panel.grid.minor = element_blank[]]

Tốc độ giảm của WSS Chậm lại nếu k vượt quá 4. Do vậy k tối ưu được lựa chọn sẽ là 4. Chúng ta thực hiện phân cụm với k = 4

# k = 4: 
set.seed[123]
km.res4 % 
  mutate[cluster = paste0["Group", km.res4$cluster]] -> data_clustered2

Hình ảnh hóa 4 cụm khách hàng [Hình 2]

# Plot customer groups: 
library[factoextra]

fviz_cluster[km.res4, 
             data = data_scaled,
             palette = "jco", 
             ellipse.type = "euclid", 
             star.plot = TRUE,
             repel = TRUE] + 
  labs[title = "Figure 2: Customer Clusters by K-means Clustering", 
       caption = "Source: IBM Watson Telco Customer Churn Data"] + 
  theme_minimal[] + 
  theme[axis.text = element_blank[]] + 
  theme[plot.margin = unit[rep[0.5, 4], "cm"]] + 
  theme[legend.position = "top"]

Bảng 1 mô tả chân dung của 4 nhóm khách hàng này

library[kableExtra] # For presenting table. 

data_clustered2 %>% 
  group_by[cluster] %>% 
  summarise[avg_ten = mean[tenure], avg_m_charges = mean[MonthlyCharges], total_charges = sum[TotalCharges], N = n[]] %>% 
  mutate[per_obs = N / sum[N]] %>% 
  mutate[per_charges = total_charges / sum[total_charges]] %>% 
  mutate_if[is.numeric, function[x] {round[x, 2]}] -> des1

des1 %>% 
  kbl[caption = "Table 1: Customer Characteristics, K-means", escape = TRUE] %>%
  kable_classic[full_width = FALSE, html_font = "Cambria"]

Bảng 1. Đặc điểm khách hàng, K-meansclusteravg_tenavg_m_chargestotal_chargesNper_obsper_chargesGroup16. 4982. 87452332. 48200. 440. 16Nhóm232. 7284. 43993167. 23710. 200. 35Nhóm357. 4099. 571302633. 12280. 120. 46Nhóm46. 7938. 10114794. 34500. 240. 04

Căn cứ vào Bảng 1 chúng ta có thể thấy Group3 là nhóm khách hàng đã từng mang lại giá trị cao nhất cho công ty. Nhóm này có 228 khách hàng, chỉ chiếm 12% tổng số khách hàng đã bỏ nhưng mang lại 46% tổng doanh thu. Đây cũng là nhóm khách hàng gắn bố lâu dài nhất với công ti với thời gian sử dụng dịch vụ trung bình là gần 56 tháng, tiêu dùng lớn với phí dịch vụ trung bình hàng tháng là gần 100$. Để một tập khách hàng có giá tốt như vậy bỏ qua thì công ty có lẽ cần phải tìm hiểu nguyên nhân tại sao để từ đó Ngăn chặn/hạn chế việc làm mất thêm những khách hàng tốt

Bảng 1 cũng chỉ ra rằng Group2 là nhóm khách hàng tốt thứ hai. Còn Nhóm1 là nhóm khách hàng mang lại ít giá trị nhất cho công ti và đây cũng là nhóm khách hàng chiếm số lượng lớn nhất

Giả sử công ti muốn lôi kéo những khách hàng đã bỏ rơi điều này trở lại bằng cách, ví dụ, gọi điện đề xuất cho khách hàng những ưu đãi bất kỳ đó, chẳng hạn như giảm cho họ 5% phí thanh toán hàng tháng kỳ lạ. Mặt khác, giả sử rằng nguồn lực thời gian và nhân lực hạn chế nên công ti chỉ có khả năng bao che/gọi điện chỉ cho 100 khách hàng thì đương nhiên vẫn ưu tiên chăm sóc Group3 trước. Tuy nhiên, nhóm này có tới 220 khách hàng nên cách tiếp cận đơn giản nhất cho việc lựa chọn là sắp xếp 228 khách hàng này theo tiêu chí tổng phí thanh toán [hoặc phí trung bình tháng] và chỉ có 100 khách hàng đầu tiên. Cụ thể những khách hàng này có ID được xác định như sau

data_clustered2 %>% 
  mutate[customerID = churned_ID] %>% 
  filter[cluster == "Group3"] %>% 
  arrange[-MonthlyCharges] %>% 
  slice[1:100] %>% 
  pull[customerID] -> group3_top100_ID

# The first-potential customers: 
head[group3_top100_ID]

________số 8

Sau khi xác định được 100 khách hàng với mức giá hợp lý nhất để thu hút trở lại, công ty có thể kết hợp với các thông tin khác nữa về khách hàng [như giới tính, tuổi, nghề nghiệp] để đưa ra các hành động thu hút

Kế tiếp là công ti cần đánh giá/ước lượng tác động về mặt doanh thu tháng [hoặc tổng doanh thu] sẽ như thế nào nếu thực hiện chính sách lôi kéo trở lại những khách hàng này bằng chính sách giảm giá 5%. Giả sử như bộ phận chăm sóc khách hàng của công ty, dựa trên những hiểu biết và kinh nghiệm, chỉ ra rằng nếu thực hiện chính sách giảm giá như vậy thì tỷ lệ thành công sẽ là 20%. Tức là nếu gọi điện/email cho 10 khách hàng thì sẽ có 2 khách hàng sẵn sàng quay lại sử dụng dịch vụ của công ty. Chúng ta có thể ước lượng doanh thu mà công ty sẽ thu lại được với giả định rằng hành vi tiêu dùng của họ vẫn tuân theo các mô hình như đã từng bằng Mô phỏng Monte Carlo [5000 lần] như sau

# Discount rate 5%: 
discount_rate % 
  filter[cluster == "Group3"] %>% 
  arrange[-MonthlyCharges] %>% 
  slice[1:100] %>% 
  sample_n[20] %>% 
  pull[TotalCharges] %>% 
  sum[] -> charges_20
  
  return[charges_20*[1 - discount_rate]]
  
}

sapply[1:5000, calculate_charges20] -> charges_20_simulation

df_income % 
  ggplot[aes[income]] + 
  geom_density[alpha = 0.3, fill = "blue", color = "blue"] + 
  geom_histogram[aes[y = ..density..], fill = "red", color = "red", alpha = 0.3] + 
  geom_vline[xintercept = mean[df_income$income], color = "green", size = 1.1] + 
  theme[text = element_text[size = 10]] + 
  theme[axis.text.y = element_blank[]] + 
  scale_x_continuous[labels = scales::dollar] + 
  labs[x = NULL, y = NULL, 
       title = "Figure 3: Total Charges from 20 Customers", 
       subtitle = "Monte Carlo Simulation, 5000 Interactions", 
       caption = "Data Source: IBM Data"]

Hình 3 cho thấy nếu

  • Tỷ lệ thành công khi kéo trở lại khách hàng bị bỏ rơi là 20%
  • Hành vi sử dụng của những khách hàng này vẫn lặp lại mẫu như đã từng
  • Tỷ lệ chiết khấu là 5%

Thì có thể nói gần như chắc chắn rằng tổng doanh thu mà công ti có thể đã ở đâu đó trong khoảng 100. 000 đến 140. 000$

Chủ Đề