DHDataHọc
Lý thuyếtBài 6/87 phút đọc+10 XP

Phân khúc hành vi

Bạn sẽ học được

  • Phân khúc hành vi khác phân khúc nhân khẩu thế nào.
  • Tiêu chí của một phân khúc dùng được.
  • Phân khúc theo mức sử dụng bằng CASE và NTILE.
  • Mô hình RFM cho khách hàng giao dịch.
  • Theo dõi phân khúc dịch chuyển theo thời gian.
  • Những lỗi làm phân khúc vô dụng.

Khái niệm cốt lõi

Phân khúc hành vi chia người dùng theo việc họ làm, không theo việc họ là ai.

Nhân khẩu: tuổi, giới tính, thành phố. Hành vi: số ngày hoạt động, số đơn, mức chi, tính năng đã dùng.

Phân khúc hành vi hữu ích hơn cho quyết định sản phẩm vì nó chỉ ra hành vi nào cần thay đổi. Nhân khẩu thường không đổi được bằng cách sửa sản phẩm.

Tiêu chí phân khúc dùng được

Một phân khúc tốt phải:

  1. Loại trừ nhau: mỗi người thuộc đúng một nhóm.
  2. Phủ hết: mọi người dùng đều có nhóm, kể cả nhóm "không hoạt động".
  3. Đo được: định nghĩa bằng cột có trong dữ liệu, không bằng cảm nhận.
  4. Ổn định: cùng một người không nhảy nhóm mỗi ngày vô cớ.
  5. Cỡ mẫu đủ: nhóm vài chục người không dùng để kết luận.

Nếu hai nhóm chồng lấn, tổng các nhóm sẽ lớn hơn tổng người dùng — lỗi rất phổ biến khi viết CASE thiếu nhánh ELSE.

Phân khúc theo mức sử dụng

Cách đơn giản nhất: đếm số ngày hoạt động trong 30 ngày.

code
WITH nguoi AS (
  SELECT
    user_id,
    COUNT(DISTINCT occurred_at::date) AS so_ngay
  FROM events
  WHERE occurred_at >= CURRENT_DATE - INTERVAL '30 days'
  GROUP BY 1
)
SELECT
  CASE
    WHEN so_ngay >= 20 THEN 'cao'
    WHEN so_ngay >= 8  THEN 'trung_binh'
    WHEN so_ngay >= 2  THEN 'thap'
    ELSE 'mot_lan'
  END AS nhom,
  COUNT(*) AS so_nguoi,
  ROUND(100.0 * COUNT(*) / SUM(COUNT(*)) OVER (), 1) AS ty_le_pct
FROM nguoi
GROUP BY 1
ORDER BY 3 DESC;

Lưu ý: người không có sự kiện nào trong 30 ngày không xuất hiện trong nguoi. Muốn phủ hết, bắt đầu từ bảng người dùng và LEFT JOIN:

code
SELECT
  CASE
    WHEN n.so_ngay IS NULL THEN 'khong_hoat_dong'
    WHEN n.so_ngay >= 20 THEN 'cao'
    WHEN n.so_ngay >= 8  THEN 'trung_binh'
    WHEN n.so_ngay >= 2  THEN 'thap'
    ELSE 'mot_lan'
  END AS nhom,
  COUNT(*) AS so_nguoi
FROM users u
LEFT JOIN nguoi n USING (user_id)
GROUP BY 1;

Phân khúc theo phân vị

Khi muốn chia đều số người thay vì đặt ngưỡng tuyệt đối, dùng NTILE:

code
WITH chi_tieu AS (
  SELECT
    user_id,
    SUM((properties->>'value')::numeric) AS tong_chi
  FROM events
  WHERE event_name = 'checkout_completed'
    AND occurred_at >= CURRENT_DATE - INTERVAL '90 days'
  GROUP BY 1
)
SELECT
  user_id,
  tong_chi,
  NTILE(4) OVER (ORDER BY tong_chi) AS tu_phan_vi
FROM chi_tieu;

NTILE(4) chia thành bốn nhóm đều nhau theo thứ tự chi tiêu: 1 là nhóm chi ít nhất, 4 là nhóm chi nhiều nhất.

Ưu điểm: luôn có nhóm cân bằng. Nhược điểm: ngưỡng thay đổi theo dữ liệu, nên so sánh giữa hai thời kỳ phải cẩn thận — người ở "nhóm 4" tháng này có thể chỉ chi bằng nửa "nhóm 4" tháng trước.

Mô hình RFM

Với sản phẩm có giao dịch, RFM là phân khúc chuẩn:

ChữNghĩaĐo
R (Recency)Gần đây nhấtSố ngày từ lần mua cuối
F (Frequency)Tần suấtSố đơn trong kỳ
M (Monetary)Giá trịTổng chi trong kỳ
code
WITH rfm AS (
  SELECT
    user_id,
    CURRENT_DATE - MAX(occurred_at)::date AS recency_ngay,
    COUNT(*) AS frequency,
    SUM((properties->>'value')::numeric) AS monetary
  FROM events
  WHERE event_name = 'checkout_completed'
    AND occurred_at >= CURRENT_DATE - INTERVAL '180 days'
  GROUP BY 1
),
diem AS (
  SELECT
    user_id,
    recency_ngay,
    frequency,
    monetary,
    NTILE(5) OVER (ORDER BY recency_ngay DESC) AS r,
    NTILE(5) OVER (ORDER BY frequency) AS f,
    NTILE(5) OVER (ORDER BY monetary) AS m
  FROM rfm
)
SELECT
  user_id, r, f, m,
  CASE
    WHEN r >= 4 AND f >= 4 AND m >= 4 THEN 'trung_thanh'
    WHEN r >= 4 AND f <= 2 THEN 'moi'
    WHEN r <= 2 AND f >= 3 THEN 'co_nguy_co_roi'
    WHEN r <= 2 AND f <= 2 THEN 'da_mat'
    ELSE 'trung_gian'
  END AS nhom
FROM diem;

Điểm R đảo chiều: recency nhỏ (mua gần đây) là tốt, nên ORDER BY recency_ngay DESC để người mua gần nhất nhận điểm 5.

Cách đọc nhóm:

  • Trung thành: mua gần, mua nhiều, chi cao — giữ nguyên trải nghiệm.
  • Mới: mua gần nhưng ít — cần onboarding và gợi ý sản phẩm thứ hai.
  • Có nguy cơ rời: từng mua nhiều nhưng lâu rồi chưa quay lại — ưu tiên nhắc lại.
  • Đã mất: lâu không mua, ít mua — chi phí giành lại cao, cân nhắc bỏ.

RFM chỉ dùng được khi mỗi người dùng gắn với một mã khách hàng ổn định. Nếu một người có nhiều tài khoản, RFM sẽ chia họ thành nhiều người.

Phân khúc dịch chuyển

Phân khúc không phải nhãn cố định. Theo dõi sự dịch chuyển giữa hai tháng:

code
WITH thang_nay AS (
  SELECT user_id, CASE WHEN COUNT(*) >= 5 THEN 'cao' ELSE 'thap' END AS nhom
  FROM events
  WHERE occurred_at >= date_trunc('month', CURRENT_DATE)
  GROUP BY 1
),
thang_truoc AS (
  SELECT user_id, CASE WHEN COUNT(*) >= 5 THEN 'cao' ELSE 'thap' END AS nhom
  FROM events
  WHERE occurred_at >= date_trunc('month', CURRENT_DATE) - INTERVAL '1 month'
    AND occurred_at <  date_trunc('month', CURRENT_DATE)
  GROUP BY 1
)
SELECT
  COALESCE(t.nhom, 'khong_co') AS thang_truoc,
  COALESCE(n.nhom, 'khong_co') AS thang_nay,
  COUNT(*) AS so_nguoi
FROM thang_truoc t
FULL OUTER JOIN thang_nay n USING (user_id)
GROUP BY 1, 2
ORDER BY 1, 2;

Ma trận dịch chuyển cho thấy ai đi lên, ai đi xuống, ai mới vào, ai rời đi. Đây là bảng hữu ích hơn nhiều so với việc chỉ báo cáo tỷ lệ từng nhóm.

Lỗi làm phân khúc vô dụng

  • Quá nhiều nhóm: 20 nhóm cho 5.000 người dùng khiến mỗi nhóm quá nhỏ để kết luận. Bắt đầu với 3–5 nhóm.
  • Ngưỡng tuỳ tiện: chọn 5 ngày vì "thấy hợp lý" mà không có lý do. Ghi lý do hoặc dùng phân vị.
  • Nhóm không phủ hết: thiếu ELSE làm một phần người dùng biến mất khỏi báo cáo.
  • Trộn nhân khẩu và hành vi: nhóm "nam, 25–34, dùng nhiều" không giúp quyết định gì.
  • Kết luận nhân quả: "người dùng nhiều tính năng giữ chân tốt hơn" chưa chứng minh dùng nhiều tính năng gây ra giữ chân.
  • Phân khúc theo dữ liệu tương lai: dùng tổng chi 12 tháng để dự đoán hành vi tháng 1 là rò rỉ thông tin.

Thực hành

  1. Chia người dùng thành bốn nhóm theo số ngày hoạt động, có nhóm "không hoạt động".
  2. Tính phân bố chi tiêu theo NTILE(4).
  3. Tính R, F, M cho 90 ngày và gán nhóm.
  4. Dựng ma trận dịch chuyển giữa hai tháng.
  5. Kiểm tra tổng các nhóm có bằng tổng người dùng không.

Lỗi thường gặp

Triệu chứngNguyên nhânCách sửa
Tổng nhóm lớn hơn tổng ngườiNhóm chồng lấn, thiếu ELSEDùng CASE phủ hết, kiểm tra tổng
Nhóm quá nhỏChia quá nhiều nhómGộp lại, tối thiểu vài trăm người
Ngưỡng đổi mỗi thángDùng NTILEChốt ngưỡng tuyệt đối hoặc ghi rõ
RFM saiNhiều tài khoản/ngườiGộp theo mã khách hàng
Kết luận nhân quảChỉ thấy tương quanDùng thử nghiệm A/B
Phân khúc bất ổnĐịnh nghĩa theo hành vi ngắn hạnDùng cửa sổ dài hơn

Tóm tắt

  • Phân khúc hành vi chia theo việc người dùng làm, hữu ích cho quyết định sản phẩm.
  • Phân khúc phải loại trừ nhau, phủ hết, đo được, ổn định và đủ mẫu.
  • CASE cho ngưỡng cố định, NTILE cho nhóm đều nhau.
  • RFM chia khách hàng theo recency, frequency, monetary.
  • Theo dõi dịch chuyển giữa các kỳ, không chỉ tỷ lệ từng nhóm.

Dùng ← → để chuyển bài