🎯 BÀI TOÁN
Có: 2,666 users, mỗi user vào các pages khác nhau (DealHot, Mission, Voucher,...)
Muốn: Chia users thành các nhóm có hành vi giống nhau
Ví dụ:
- Nhóm 1: Thích săn deal (hay vào DealHot, Voucher)
- Nhóm 2: Thích chơi mission (hay vào Mission, CreateMission)
- Nhóm 3: Thích chat (hay vào ChatRoom, ReferralFriend)
I) K-MEANS - PHÂN NHÓM ĐƠN GIẢN NHẤT
💡 Ý tưởng chính
Giống như phân học sinh thành các nhóm học:
- Thầy giáo chọn 5 bạn làm nhóm trưởng (ngẫu nhiên)
- Các bạn còn lại tìm nhóm trưởng "giống mình nhất" để vào nhóm đó
- Nhóm trưởng mới = trung bình của các bạn trong nhóm
- Lặp lại bước 2-3 đến khi không ai đổi nhóm nữa
📖 Ví dụ thực tế
Từ data piggi_metrics.csv, lấy 7 users:
User 664402: Profile(3), UpdateProfile(1) → 4 lượt
User 581242: EmbeddedBrowser(1) → 1 lượt
User 665300: GetMissionPoint(1), Mission(2), Profile(1) → 4 lượt
User 273471: Voucher(1), DealHot(1) → 2 lượt
User 184423: Profile(1), ReferralFriend(1) → 2 lượt
User 665302: Mission(1), CreateMission(1) → 2 lượt
User 121: DealHot(1) → 1 lượt
Chuyển sang vector (đếm lượt vào từng page):
Mission DealHot Profile Voucher Social
User 665300: 3 0 1 0 0
User 665302: 2 0 0 0 0
User 664402: 0 0 4 0 0
User 273471: 0 1 0 1 0
User 121: 0 1 0 0 0
User 184423: 0 0 1 0 1
User 581242: 0 0 0 0 0
Chạy K-Means với k=3:
Bước 1: Chọn 3 nhóm trưởng ngẫu nhiên
- Nhóm trưởng 1: User 665300 (Mission nhiều)
- Nhóm trưởng 2: User 273471 (Deal)
- Nhóm trưởng 3: User 664402 (Profile nhiều)
Bước 2: Các user tìm nhóm trưởng giống mình
- User 665302 giống User 665300 → Nhóm 1 (Mission)
- User 121 giống User 273471 → Nhóm 2 (Deal)
- User 184423 giống User 664402 → Nhóm 3 (Profile/Social)
- User 581242 (ít tương tác) → Nhóm 3
Bước 3: Tính nhóm trưởng mới
- Nhóm 1: Mission trung bình cao
- Nhóm 2: DealHot, Voucher trung bình cao
- Nhóm 3: Profile, social features
Bước 4: Lặp lại cho đến khi hội tụ...
Kết quả cuối:
- Nhóm 1 (Mission Players): User 665300, 665302
- Nhóm 2 (Deal Hunters): User 273471, 121
- Nhóm 3 (Profile/Social Users): User 664402, 184423, 581242
✅ Ưu điểm
- Nhanh - Chạy với 2,666 users trong vài giây
- Đơn giản - Dễ hiểu, dễ code
- Kết quả rõ ràng - Mỗi user chỉ thuộc 1 nhóm duy nhất
❌ Nhược điểm
- Phải biết trước số nhóm (k) - Muốn chia thành mấy nhóm?
- Nhạy với "outliers" - User lạ sẽ kéo nhóm lệch
- Kết quả khác nhau mỗi lần chạy - Do chọn nhóm trưởng ngẫu nhiên
🎯 Khi nào dùng?
✅ Khi bạn biết muốn chia thành bao nhiêu nhóm (vd: 5 nhóm)
✅ Khi cần kết quả nhanh
✅ Khi users khá đồng đều (không có user quá lạ)
II) DBSCAN - TÌM NHÓM BẠN ĐÔNG ĐÚC
💡 Ý tưởng chính
Giống như tìm nhóm bạn trong lớp học:
- Nếu bạn có ít nhất 5 người bạn thân (trong bán kính gần) → Bạn là "người nổi"
- Bạn của "người nổi" → Cùng nhóm
- Nếu bạn không có đủ 5 bạn thân và cũng không phải bạn của "người nổi" → Loner (outlier)
Không cần biết trước số nhóm!
📖 Ví dụ thực tế với data piggi_metrics.csv
Từ 21 dòng data đầu tiên, ta có:
User 665300: Mission(2), GetMissionPoint(1), Profile(1) → Mission-focused
User 665302: Mission(1), CreateMission(1) → Mission-focused
User 200165: Mission(1) → Mission-focused
↓ 3 users này "gần nhau" vì đều thích Mission
User 273471: Voucher(1), DealHot(1) → Deal-focused
User 121: DealHot(1) → Deal-focused
User 82777: FlashsaleEmbedded(1) → Deal-focused
↓ 3 users này "gần nhau" vì đều thích săn deal
User 664402: Profile(3), UpdateProfile(1) → OUTLIER
↓ Chỉ vào Profile, không giống ai → Lẻ loi
User 581242: EmbeddedBrowser(1) → OUTLIER
User 294132: ChatRoom(1) → OUTLIER
DBSCAN tự động phát hiện:
Set parameters: eps=0.5, min_samples=3
Bước 1: Tìm vùng đông đúc
- Vùng Mission: 3 users gần nhau → Nhóm 1 ✅
- Vùng Deal: 3 users gần nhau → Nhóm 2 ✅
Bước 2: Đánh dấu outliers
- User 664402: Không có đủ 3 neighbors → Outlier ⚠️
- User 581242: Không thuộc nhóm nào → Outlier ⚠️
- User 294132: ChatRoom độc lập → Outlier ⚠️
Kết quả:
- Nhóm 1 (Mission Players): User 665300, 665302, 200165
- Nhóm 2 (Deal Hunters): User 273471, 121, 82777
- Outliers: User 664402, 581242, 294132 (hành vi lạ, không thuộc nhóm chính)
✅ Ưu điểm
- Không cần biết số nhóm trước - Tự động tìm
- Tìm được outliers - User có hành vi lạ (VIP, bot, test accounts)
- Nhóm hình dạng bất kỳ - Không bắt buộc hình tròn
❌ Nhược điểm
- Khó chọn tham số - "Bao xa là gần?" "Bao nhiêu bạn là đủ đông?"
- Chậm hơn K-Means - Với 2,666 users vẫn OK
- Không tốt nếu mật độ khác nhau - Vùng đông ít khác biệt quá
🎯 Khi nào dùng?
✅ Khi KHÔNG biết có bao nhiêu nhóm
✅ Khi muốn tìm users lạ (VIP, bot)
✅ Khi các nhóm có kích thước/mật độ tương đương
III) GMM - MỖI NGƯỜI CÓ NHIỀU MẶT
💡 Ý tưởng chính
Khác với K-Means (mỗi user chỉ thuộc 1 nhóm), GMM cho phép:
User A có thể:
- 60% là "Deal Lover"
- 35% là "Mission Player"
- 5% là "Social User"
Giống như một người có nhiều sở thích:
- Bạn An: 70% thích bóng đá, 30% thích game
- Bạn Bình: 50% thích bóng đá, 50% thích đọc sách
📖 Ví dụ thực tế với data piggi_metrics.csv
User 664402 từ data thực:
2026-05-20 15:56:44 → Profile
2026-05-20 15:56:45 → UpdateProfile
2026-05-20 15:56:46 → Profile
Hành vi thực tế: Profile(3), UpdateProfile(1)
Giả sử user này còn có thêm data:
- Profile: 15 lần
- Mission: 8 lần
- DealHot: 3 lần
K-Means nói: User này thuộc nhóm "Profile User" (100%)
GMM nói: User này có nhiều mặt:
- 60% Profile/Settings User (quan tâm cài đặt)
- 35% Mission Player (thỉnh thoảng chơi mission)
- 5% Deal Hunter (ít quan tâm deals)
Insight:
→ User này chủ yếu vào chỉnh sửa profile, NHƯNG cũng thích missions
→ Recommend: Personalization features + Mission notifications
→ Không nên spam Deal notifications vì chỉ 5% quan tâm
✅ Ưu điểm
- Linh hoạt - User có thể thuộc nhiều nhóm
- Realistic - Người thật thường có nhiều sở thích
- Cung cấp xác suất - Biết độ tin cậy
❌ Nhược điểm
- Phức tạp hơn - Khó hiểu hơn K-Means
- Chậm hơn - Tính toán nhiều hơn
- Vẫn cần biết số nhóm - Như K-Means
🎯 Khi nào dùng?
✅ Khi users có nhiều sở thích (không rõ ràng 1 nhóm)
✅ Khi cần recommendation đa dạng
✅ Khi muốn xác suất thay vì nhóm cứng
IV) PHÂN LOẠI THEO RFD - ĐÁNH GIÁ MỨC ĐỘ TƯƠNG TÁC
💡 Ý tưởng chính
Không phân loại theo "thích gì" mà phân loại theo "tương tác như thế nào":
3 tiêu chí:
- R (Recency): Lần cuối vào app cách đây bao lâu?
- F (Frequency): Vào app bao nhiêu lần?
- D (Diversity): Vào bao nhiêu pages khác nhau?
📖 Ví dụ thực tế với data piggi_metrics.csv
Phân tích 3 users từ data thực:
User 665300:
Từ data: GetMissionPoint(1), Mission(2), Profile(1) trong ngày 2026-05-20
- Recency: 2026-05-20 (hôm nay = data mới nhất) → R = 5 ✅
- Frequency: 4 lượt trong data này → F = 3 (trung bình) ⚠️
- Diversity: 3 pages khác nhau (Mission, GetMissionPoint, Profile) → D = 3 ⚠️
→ Xếp hạng: 5-3-3 = "Potential Loyalist"
(Active gần đây, nhưng chưa dùng nhiều features)
User 664402:
Từ data: Profile(3), UpdateProfile(1) trong ngày 2026-05-20
- Recency: 2026-05-20 (hôm nay) → R = 5 ✅
- Frequency: 4 lượt → F = 3 ⚠️
- Diversity: 2 pages (Profile, UpdateProfile) → D = 2 ⚠️
→ Xếp hạng: 5-3-2 = "Loyal but Focused"
(Active, nhưng chỉ quan tâm Profile features)
User 581242:
Từ data: EmbeddedBrowser(1) trong ngày 2026-05-20
- Recency: 2026-05-20 (hôm nay) → R = 5 ✅
- Frequency: 1 lượt duy nhất → F = 1 ❌
- Diversity: 1 page → D = 1 ❌
→ Xếp hạng: 5-1-1 = "New User"
(Mới vào lần đầu hoặc người dùng thụ động)
Insight:
- Tất cả đều active (R=5) vì data chỉ có 1 ngày (2026-05-20)
- User 665300 explore nhiều nhất → Tiềm năng cao
- User 664402 chỉ focus vào Profile → Cần khuyến khích dùng features khác
- User 581242 mới vào → Cần onboarding
🎭 Các nhóm users
| Nhóm | Đặc điểm | Action |
|---|---|---|
| Champions (5-5-5) | Active, hay vào, explore nhiều | VIP treatment, early access |
| Loyal Customers (5-5-2) | Active, hay vào, nhưng chỉ thích vài tính năng | Giữ chân, đừng thay đổi features họ thích |
| New Users (5-1-1) | Mới vào lần đầu | Onboarding, hướng dẫn |
| At Risk (2-4-3) | Lâu không vào, nhưng từng active | Gửi email "We miss you", tặng voucher |
| Lost (1-1-1) | Đã bỏ app | Win-back campaign, hoặc để yên |
✅ Ưu điểm
- Đơn giản - Chỉ 3 con số, dễ hiểu
- Business-friendly - Marketing team hiểu ngay
- Nhanh - Tính toán 2,666 users trong < 1 giây
- Actionable - Biết ngay làm gì với từng nhóm
❌ Nhược điểm
- Không nói user thích page nào - Chỉ nói mức độ tương tác
- Quá đơn giản - Bỏ qua nhiều thông tin chi tiết
- Cần data dài hạn - Recency cần ít nhất vài tuần data
🎯 Khi nào dùng?
✅ Khi cần phân loại nhanh để marketing
✅ Khi muốn kết quả dễ giải thích
✅ KẾT HỢP với thuật toán khác để biết user thích gì
V) RULE-BASED - LẬP LUẬT THỦ CÔNG
💡 Ý tưởng chính
Bạn tự quy định luật, không dùng AI:
NẾU user vào DealHot > 30 lần
→ Gắn nhãn "Deal Lover"
NẾU user vào Mission > 20 lần
→ Gắn nhãn "Mission Player"
NẾU user không vào app > 30 ngày
→ Gắn nhãn "Churn Risk"
Giống như thầy cô chấm điểm theo thang điểm cố định.
📖 Ví dụ thực tế với data piggi_metrics.csv
Áp dụng rules cho users thực:
Rule 1: Mission Player
IF count_Mission >= 2 THEN "mission_player"
User 665300: Mission(2) + GetMissionPoint(1) → Tổng 3 → ✅ "mission_player"
User 665302: Mission(1) + CreateMission(1) → Tổng 2 → ✅ "mission_player"
User 200165: Mission(1) → ❌ Không đủ
Rule 2: Deal Hunter
IF (count_DealHot >= 1 OR count_Voucher >= 1) THEN "deal_hunter"
User 273471: DealHot(1) + Voucher(1) → ✅ "deal_hunter"
User 121: DealHot(1) → ✅ "deal_hunter"
User 82777: FlashsaleEmbedded(1) → ✅ "deal_hunter"
Rule 3: Profile Focused
IF count_Profile >= 2 AND count_other_pages < 2 THEN "profile_focused"
User 664402: Profile(3) + UpdateProfile(1) → ✅ "profile_focused"
User 184423: Profile(1) → ❌ Không đủ
Rule 4: Chuỗi hành vi (Sequence)
Từ data thực:
2026-05-20 15:56:44 User 664402 Profile
2026-05-20 15:56:45 User 664402 UpdateProfile
2026-05-20 15:56:46 User 664402 Profile
Rule: IF path = ["Profile" → "UpdateProfile" → "Profile"]
THEN "edit_then_verify" (Sửa profile rồi check lại)
→ User 664402: ✅ Match pattern này
Kết quả phân loại:
- Mission Players: 665300, 665302
- Deal Hunters: 273471, 121, 82777
- Profile Focused: 664402
- Uncategorized: 581242, 184423, 294132, 568861, 145593, 200165
🎯 Case Study
Công ty muốn tìm users "sắp mua hàng":
Rule: "Ready to Buy"
IF (vào DealHot > 5 lần trong 3 ngày qua
AND vào Voucher > 2 lần
AND chưa Order trong 7 ngày qua)
THEN gửi push notification "Flash Sale 50% - Chỉ 2 giờ!"
→ Conversion rate tăng vì đúng timing!
✅ Ưu điểm
- Dễ hiểu 100% - Ai cũng đọc được
- Kiểm soát hoàn toàn - Bạn quyết định mọi thứ
- Không cần training - Viết rule là xong
- Giải thích được cho sếp - "Em làm theo logic này..."
❌ Nhược điểm
- Không tự học - Không tìm ra patterns mới
- Cần domain knowledge - Phải hiểu business sâu
- Khó maintain - 100 rules sẽ rối loạn
- Rules có thể conflict - Rule 1 nói A, Rule 2 nói B
🎯 Khi nào dùng?
✅ Khi business logic rõ ràng
✅ Khi cần giải thích cho non-tech team
✅ Khi bắt đầu (chưa có data để train ML)
✅ KẾT HỢP với ML - ML tìm patterns, Rules finalize
VI) HIERARCHICAL - XÂY DỰNG CÂY GIA PHẢ
💡 Ý tưởng chính
Giống như vẽ cây gia phả:
Tất cả Users
/ \
Active Users Inactive Users
/ \
Deal Lovers Mission Players
/ \
Heavy Light
Bắt đầu từ mỗi user = 1 nhóm riêng, merge dần các user giống nhau.
📖 Ví dụ thực tế với data piggi_metrics.csv
Lấy 6 users từ data thực:
User 665300: Mission(3), Profile(1) → Mission-heavy
User 665302: Mission(1), CreateMission(1) → Mission-heavy
User 273471: DealHot(1), Voucher(1) → Deal-heavy
User 121: DealHot(1) → Deal-heavy
User 664402: Profile(3), UpdateProfile(1) → Profile-heavy
User 184423: Profile(1), ReferralFriend(1) → Mixed
Quá trình merge (từ dưới lên):
Ban đầu: [665300] [665302] [273471] [121] [664402] [184423]
Bước 1: 665300 và 665302 giống nhất (cùng Mission) → Merge
[665300,665302] [273471] [121] [664402] [184423]
Bước 2: 273471 và 121 giống nhất (cùng Deal) → Merge
[665300,665302] [273471,121] [664402] [184423]
Bước 3: 664402 và 184423 gần nhau (cùng Profile) → Merge
[665300,665302] [273471,121] [664402,184423]
Bước 4: Mission group và Deal group merge
[665300,665302,273471,121] [664402,184423]
Bước 5: Merge tất cả
[665300,665302,273471,121,664402,184423]
Dendrogram (cây phân cấp):
User: 665300 665302 273471 121 664402 184423
| | | | | |
└───────┘ └──────┘ └───────┘
│ │ │
└───────────────┘ │
│ │
└──────────────────────┘
Cắt cây ở độ cao khác nhau:
-
Cắt cao (2 nhóm):
- [665300, 665302, 273471, 121] = Active Users
- [664402, 184423] = Profile Users
-
Cắt trung bình (3 nhóm):
- [665300, 665302] = Mission Players
- [273471, 121] = Deal Hunters
- [664402, 184423] = Profile Users
Cắt thấp (6 nhóm): Mỗi user riêng lẻ
📊 Dendrogram (Cây phân cấp)
User: A B E C D
| | | | |
└────┘ | └────┘
│ │ │
└──────┘ │
│ │
└─────────┘
→ Nhìn vào cây, quyết định cắt ở đâu!
✅ Ưu điểm
- Không cần biết số nhóm trước - Cắt ở đâu cũng được
- Visualization đẹp - Dendrogram trực quan
- Hiểu được hierarchy - Nhóm con, nhóm cha
- Deterministic - Chạy lại kết quả giống nhau
❌ Nhược điểm
- Chậm - Với > 10,000 users sẽ rất lâu
- Không thể undo - Merge sai không rollback được
- Memory lớn - Phải lưu toàn bộ relationships
🎯 Khi nào dùng?
✅ Khi muốn khám phá (exploratory analysis)
✅ Khi cần hiểu structure/hierarchy
✅ Khi data nhỏ-trung bình (< 5,000 users)
✅ Khi cần present cho leadership (dendrogram đẹp!)
VII) HDBSCAN - BẢN NÂNG CẤP CỦA DBSCAN
💡 Ý tưởng chính
DBSCAN nhưng thông minh hơn:
- DBSCAN: "Bao xa là gần?" → 1 con số cố định
- HDBSCAN: "Tự động điều chỉnh cho từng vùng"
Giống như:
- DBSCAN: "Trong bán kính 5m có ≥ 5 người → nhóm bạn"
- HDBSCAN: "Ở chỗ đông → 3m, ở chỗ vắng → 10m cũng OK"
📖 Ví dụ thực tế với data piggi_metrics.csv
Từ 21 dòng data, giả sử có thêm nhiều users tạo ra 2 vùng mật độ khác nhau:
Vùng đông đúc - Mission Players (10 users gần nhau):
665300: Mission(3), Profile(1)
665302: Mission(1), CreateMission(1)
200165: Mission(1)
... + 7 users khác cũng thích Mission
Vùng thưa thớt - VIP/Diverse Users (3 users xa nhau):
664402: Profile(3), UpdateProfile(1), DealHot(5), Mission(8), ChatRoom(2)
→ User đa dạng, vào nhiều thứ
581242: EmbeddedBrowser(8), ChatRoom(5), Loyalty(3)
→ User đa dạng khác
294132: ChatRoom(10), ReferralFriend(8), Mission(4)
→ User xã hội hóa
DBSCAN với eps=0.5, min_samples=3:
✅ Tìm được vùng Mission (10 users đông đúc)
❌ Bỏ sót 3 VIP users (xa nhau, không đủ min_samples=3)
→ 3 VIP users bị gán là outliers (sai!)
HDBSCAN tự động:
Bước 1: Phát hiện vùng Mission đông đúc
→ Tạo Cluster 1 với 10 users
Bước 2: Phát hiện 3 VIP users tuy xa nhau nhưng có pattern riêng
→ Tự điều chỉnh: "Ở vùng này, chỉ cần 2 users gần nhau cũng OK"
→ Tạo Cluster 2 với 3 VIP users
Bước 3: Các users lẻ loi thật sự (EmbeddedBrowser(1), ...) → Outliers
Kết quả:
- DBSCAN: 1 cluster (Mission) + 3 VIP bị nhầm outliers
- HDBSCAN: 2 clusters (Mission + VIP) + outliers thật sự ✅
→ HDBSCAN thông minh hơn, tự thích nghi với mật độ khác nhau!
✅ Ưu điểm
- Tự động hóa cao - Ít cần tune parameters
- Tốt nhất cho density-based - State-of-the-art
- Handle varied density - Mật độ khác nhau OK
- Outlier scores - Cho điểm từ 0-1 (không chỉ yes/no)
❌ Nhược điểm
- Phức tạp - Khó hiểu thuật toán
- Cần thư viện riêng - Không có sẵn trong sklearn
- Chậm hơn K-Means - Nhưng nhanh hơn DBSCAN
🎯 Khi nào dùng?
✅ Thay thế DBSCAN - Better version
✅ Khi có nhóm đông/thưa khác nhau
✅ Khi muốn tự động hóa (ít tune)
✅ Đề xuất cho production - Robust, chất lượng cao
📊 SO SÁNH BẰNG VÍ DỤ HẰNG NGÀY
| Thuật toán | Giống như... | Khi nào dùng? |
|---|---|---|
| K-Means | Chia lớp thành các tổ học | Biết cần mấy nhóm, cần nhanh |
| DBSCAN | Tìm nhóm bạn trong quán cafe đông người | Tìm outliers, không biết số nhóm |
| GMM | Phân loại người có nhiều sở thích | User không rõ ràng 1 nhóm |
| RFD | Xếp hạng khách hàng thân thiết | Marketing, đơn giản, nhanh |
| Rule-Based | Quy định của công ty | Logic business rõ ràng |
| Hierarchical | Vẽ cây gia phả | Khám phá, visualization |
| HDBSCAN | Tìm nhóm bạn thông minh (tự động) | Production, chất lượng cao |
Top comments (0)