Mini-challenge: đọc ba mô tả hệ thống
Ba mô tả feature nghe đều 'cần AI'. Tự phân loại paradigm, chỉ ra chỗ phép đo không đáng tin, và quyết định có nên học từ dữ liệu — một bài không cần model.
TL;DR: Ba mô tả dưới đây đều mở đầu bằng một câu quen thuộc: "cần AI để...". Nhưng một cái không cần model nào cả — luật đã có sẵn, cố định, phải giải thích được. Một cái đo rất đẹp trên tập test rồi sụp ở production, vì hai lỗi độc lập trong cách xây feature và cách chia dữ liệu. Một cái không có nhãn nào để so đúng-sai, nên "nghiệm thu" phải đổi hẳn cách nhìn. Bài này không dạy khái niệm mới — nó bắt bạn tự áp những gì đã học vào ba tình huống thật, trước khi đọc lời giải.
Ba scenario dưới đây đều đóng gói bằng một câu quen thuộc trên backlog: "làm cái model dự đoán X". Nghe giống nhau không có nghĩa là cùng một câu trả lời đúng — kỹ năng bài này luyện là phân biệt lúc nào "cần model" là đúng, lúc nào là phản xạ sai, và khi model đã chạy rồi thì làm sao biết con số đo có đáng tin.
Học từ dữ liệu chỉ đáng giá khi luật ánh xạ input sang output KHÔNG viết ra tường minh được, hoặc quá nhiều biến thể để liệt kê bằng tay. Khi luật đã có sẵn, cố định, và cần giải thích được cho người ngoài, rule-based vẫn là lựa chọn đúng — thêm model vào đó là thêm chi phí mà không đổi lấy gì.
Ba kiểu học của machine learning không khác nhau ở thuật toán, mà ở đúng một trục: model nhận tín hiệu gì để biết mình đúng hay sai. Có nhãn đúng cho từng mẫu là một loại tín hiệu; không có nhãn nào cả, chỉ có cấu trúc sẵn trong dữ liệu, là một loại tín hiệu khác — và nó đổi hẳn cách "chấm điểm" kết quả sau này.
Model chỉ học được từ nhãn đúng, và con số đo trên tập test chỉ đáng tin nếu tập đó thật sự tách biệt với những gì model đã thấy lúc train. "Tách biệt" không chỉ là không trùng dòng dữ liệu — còn phải hỏi tập test có đại diện đúng cho điều kiện lúc model chạy thật hay không.
Một model đo đẹp trên tập test nhưng hỏng khi chạy thật thường không phải vì thuật toán tệ, mà vì phép đo đã bị hỏng từ trước — hoặc model học vẹt đặc điểm riêng của tập train (overfitting), hoặc trong feature có thông tin lẽ ra không được biết tại thời điểm dự đoán (data leakage).
🎯 Đề bài — ba ticket nghe giống nhau
Bạn là kỹ sư data ở một ngân hàng số phát hành thẻ tín dụng. Ba ticket cùng rơi vào backlog trong một tuần.
Scenario 1 — Miễn phí thường niên thẻ tín dụng
Phòng sản phẩm đã ban hành và công bố chính sách: khách được miễn phí thường niên năm sau nếu tổng chi tiêu qua thẻ trong năm đạt một ngưỡng cụ thể theo hạng thẻ, và vẫn giữ đúng hạng thẻ đó tới cuối năm. Ngưỡng và hạng thẻ đã ghi rõ trong văn bản chính sách nội bộ; đội Compliance dùng đúng văn bản đó để trả lời khiếu nại của khách và phục vụ kiểm toán hàng năm.
Trưởng phòng Data mở ticket: "Bên mình có sẵn dữ liệu giao dịch nhiều năm, làm cái model dự đoán khách nào sẽ được miễn phí năm sau, để CSKH chủ động báo trước cho khách."
Scenario 2 — Model chấm điểm rủi ro giao dịch
Một đội khác đã xây xong model risk-scoring: mỗi giao dịch thẻ, tại thời điểm xin cấp phép (authorization), model trả một điểm rủi ro để hệ thống quyết định approve, decline, hay bắt xác thực thêm. Đánh giá offline trên tập test giữ lại 20% dữ liệu lịch sử, model đạt AUC 0.94 — AUC là điểm từ 0 đến 1 đo khả năng model xếp đúng giao dịch gian lận có điểm rủi ro cao hơn giao dịch hợp lệ, càng gần 1 càng tốt (dữ kiện giả định của scenario, không phải benchmark thật) — một con số rất đẹp. Team tự tin deploy.
Hai tháng sau khi lên production, catch rate — tỉ lệ giao dịch gian lận thật sự bị chặn đúng lúc — giảm sâu so với kỳ vọng từ AUC offline. Nhiều giao dịch gian lận vẫn lọt qua, dù thuộc loại model "từng học" trong tập test. Bạn được kéo vào chẩn đoán, và được đưa cho danh sách feature cùng cách chia tập:
-- Danh sach feature dung de train model risk-scoring
FEATURES = [
so_tien_giao_dich,
loai_the,
so_giao_dich_trong_24h_gan_nhat,
khoang_cach_dia_ly_so_voi_giao_dich_truoc_do,
trang_thai_tranh_chap, -- co trong kho du lieu lich su
]
LABEL = nhan_gian_lan -- 1 neu la gian lan, 0 neu khong
-- Cach chia tap de train va danh gia
function chiaTapDuLieu(danhSachGiaoDich):
xaoTronNgauNhien(danhSachGiaoDich) -- shuffle toan bo truoc khi cat
train <- danhSachGiaoDich[0 : 80%]
test <- danhSachGiaoDich[80% : 100%]
return train, test
Scenario 3 — Phân nhóm khách hàng
Đội marketing muốn chia toàn bộ khách hàng thẻ tín dụng thành các nhóm để thiết kế ưu đãi riêng cho từng nhóm — nhưng chưa ai định nghĩa trước các nhóm đó là gì. Không có cột "khách cao cấp" hay "khách thường" gán sẵn, không có nhãn nào cả. Thứ duy nhất có là hành vi: tần suất giao dịch mỗi tháng, giá trị trung bình một giao dịch, danh mục chi tiêu chính, số năm mở tài khoản.
Ticket ghi: "Dùng dữ liệu hành vi, tự động chia khách hàng thành các nhóm có ý nghĩa để mỗi nhóm nhận một chiến dịch khác nhau."
✍️ Phần việc của bạn
Trước khi cuộn xuống, hãy viết ra — trên giấy hoặc trong đầu, nhưng phải thành câu — cho cả ba scenario:
- Scenario 1: Bạn có nên xây model không? Trả lời có/không kèm đúng một lý do kỹ thuật (không phải "tôi thấy không cần"). Nếu không xây model, đề xuất cách làm thay thế.
- Scenario 2: Chỉ ra hai lỗi độc lập trong hai đoạn pseudocode trên — một ở phần khai báo feature, một ở hàm chia tập. Với mỗi lỗi, giải thích bằng cơ chế: vì sao nó khiến AUC đo trên tập test cao hơn thực tế, và vì sao catch rate ở production lại thấp hơn nhiều.
- Scenario 3: Đây là paradigm học nào trong ba kiểu đã học? Sau khi thuật toán chia khách hàng thành, giả sử, 4 nhóm — làm sao bạn biết kết quả đó "đúng"? Nêu cụ thể điều gì thay thế cho "so với nhãn thật" mà scenario 2 có nhưng scenario này không có.
💡 Gợi ý
Không có con số hay kết luận nào ở đây — chỉ là câu hỏi để bạn tự lần ra đáp án. Nếu chưa viết xong phần việc ở trên, quay lại làm trước.
- Scenario 1: Nếu liệt kê hết mọi trường hợp input có thể xảy ra (ngưỡng chi tiêu, hạng thẻ), bạn có viết ra được toàn bộ ánh xạ sang output đúng/sai bằng vài dòng điều kiện không? Nếu viết được, "học" ở đây còn học cái gì mà luật chưa có sẵn?
- Scenario 2, feature: Cột
trang_thai_tranh_chapcó giá trị vào đúng thời điểm hệ thống cần ra quyết định approve/decline, hay chỉ có sau khi một quy trình khác (điều tra khiếu nại) đã chạy xong? - Scenario 2, chia tập:
xaoTronNgauNhientrộn giao dịch mà không quan tâm thứ tự thời gian. Nếu hai giao dịch của cùng một chuỗi gian lận rơi vào cả train lẫn test, model cần tổng quát hoá hay chỉ cần nhớ lại? - Scenario 3: Nếu không có nhãn để so sánh, con số nào bạn CÓ THỂ tính được từ chính cách các nhóm được chia ra? Con số đó trả lời được câu hỏi "các nhóm tách biệt tốt về mặt toán học" — nhưng có trả lời được câu hỏi "các nhóm này có ích cho marketing" không?
✅ Lời giải
Scenario 1 → Rule-based, không cần model
Đây là bẫy chủ đích: scenario này không cần model nào cả. Luật miễn phí do phòng sản phẩm viết ra, đã công bố, và ánh xạ input (tổng chi tiêu, hạng thẻ) sang output (miễn/không miễn) là một điều kiện nhị phân viết được trong vài dòng — không có pattern ẩn nào cần khai phá từ dữ liệu, vì bản thân luật đã LÀ đáp án đầy đủ.
Ba lý do rule-based thắng tuyệt đối:
- Explainability là ràng buộc cứng. Compliance cần trả lời khách hàng dựa trên đúng điều khoản nào, kiểm toán cần đối chiếu quyết định với văn bản chính sách. Một model — kể cả model chính xác gần tuyệt đối — vẫn có thể lệch khỏi văn bản ở vài trường hợp biên, và khi lệch thì không ai giải thích được "vì sao model nói vậy" bằng đúng điều khoản đã ký. Rule-based khớp 100% với văn bản, vì nó chính là văn bản được viết lại thành code.
- Không có gì để học. Học từ dữ liệu có giá trị khi ánh xạ input–output không viết ra tường minh được. Ở đây luật đã tồn tại sẵn — train một model để nó "đoán lại" điều một câu truy vấn đã trả lời chính xác là lãng phí, và tệ hơn: model có thể học sai một phần luật mà không ai biết cho tới khi bị kiểm toán phát hiện.
- Chi phí vòng đời không đổi lấy gì. Model cần retrain khi drift, cần giám sát liên tục. Rule-based chỉ cần sửa một điều kiện khi chính sách đổi — và chính sách đổi ít, có kiểm soát qua quy trình duyệt.
Đề xuất thay thế: viết truy vấn/rule engine trực tiếp từ văn bản chính sách. Nếu sếp thật sự muốn "chủ động báo trước cho khách", bài toán đáng làm bằng model là một bài toán khác: dự đoán khách nào sẽ chạm ngưỡng chi tiêu vào cuối năm nếu xu hướng hiện tại tiếp diễn — đó là dự đoán tương lai chưa biết, khác hẳn việc áp một luật đã biết cho dữ liệu đã có.
Đây là hình ảnh soi gương với mini-challenge của module Embedding & RAG: một trong ba ticket ở đó cũng là bẫy "có tài liệu ⇒ tưởng phải RAG", trong khi câu trả lời đúng là bỏ hẳn phần hạ tầng phức tạp. Cùng một bài học ở tầng meta — nghe "cần AI" không có nghĩa là cần AI.
Scenario 2 → Hai lỗi độc lập: leakage ở feature, sai trục thời gian ở split
Lỗi 1 — data leakage ở cột trang_thai_tranh_chap. Giá trị cột này chỉ được điền SAU KHI một giao dịch đã bị khiếu nại và đội điều tra xử lý xong — tại đúng thời điểm hệ thống cần ra quyết định (lúc authorization, real-time), cột này chưa tồn tại, luôn ở trạng thái rỗng. Nhưng lúc train, cột này gần như đồng nghĩa với nhãn nhan_gian_lan — model học được một "phím tắt": chỉ cần nhìn cột leak này là đoán đúng gần hết, không cần học pattern hành vi thật. Đó là lý do AUC offline cao vọt: model không dự đoán, nó đọc trước một đáp án lỡ lọt vào tập feature. Khi lên production, cột leak luôn rỗng — tín hiệu quan trọng nhất mà model dựa vào biến mất, catch rate rơi tự do.
Lỗi 2 — chia tập ngẫu nhiên thay vì theo thời gian. xaoTronNgauNhien trộn toàn bộ giao dịch trước khi cắt 80/20, bất kể xảy ra lúc nào. Gian lận thẻ tín dụng không đứng yên — một chuỗi gian lận (fraud ring) đổi chiêu liên tục, và các giao dịch của cùng một chuỗi thường xảy ra gần nhau về thời gian. Khi trộn ngẫu nhiên, giao dịch của cùng một chuỗi có thể rơi cả vào train lẫn test — model không cần tổng quát hoá pattern gian lận, chỉ cần nhớ lại đặc điểm cụ thể của chuỗi đó vì đã thấy một phần anh em của nó lúc train. Test set vì vậy không còn mô phỏng đúng điều kiện thật của production, nơi model luôn phải dự đoán những chuỗi gian lận hoàn toàn chưa từng thấy ở tương lai.
Vì sao phải sửa cả hai. Hai lỗi cộng dồn theo hai cơ chế khác nhau: leakage làm model dựa vào một feature không khả dụng lúc production (lỗi ở CÁI GÌ được học); random split làm phép đo không phản ánh đúng việc dự đoán tương lai (lỗi ở CÁCH ĐO). Sửa leakage mà vẫn random split thì AUC vẫn bị thổi phồng do rò rỉ giữa các chuỗi gian lận gần nhau về thời gian. Sửa split thành time-based mà vẫn giữ cột leak thì con số đo trung thực hơn về trục thời gian, nhưng model production vẫn sụp vì thiếu đúng feature nó đã học dựa vào.
Cách sửa: (1) audit toàn bộ feature theo tiêu chí point-in-time (đúng-thời-điểm) — với mỗi cột, tự hỏi giá trị của nó có tồn tại đúng vào thời điểm cần dự đoán thật hay không, loại bỏ mọi cột chỉ có sau một quy trình downstream (điều tra, khiếu nại, chargeback); (2) chia tập theo thời gian — train trên một khoảng quá khứ, test trên một khoảng sau đó hoàn toàn tách biệt, mô phỏng đúng việc model production luôn dự đoán tương lai chưa thấy.
Scenario 3 → Unsupervised, và nghiệm thu không còn là "so với nhãn thật"
Đây là unsupervised: không có nhãn nào được gán trước cho segment nào tồn tại — input chỉ có các đặc trưng hành vi, không có cột target để so khớp đúng/sai. Tín hiệu duy nhất để "dạy" thuật toán là cấu trúc/độ giống nhau nội tại giữa các khách hàng: những khách có hành vi gần nhau được gom cùng nhóm. Đối chiếu với ba kiểu học: supervised học từ cặp (input, nhãn) đúng sẵn; ở đây không có vế nhãn.
Phần khó nhất, và cũng là điều hay bị bỏ sót: nghiệm thu bài này không giống nghiệm thu một classifier như scenario 2. Không có ground truth khách quan để so kết quả thuật toán, nên không có một con số accuracy hay AUC duy nhất để chốt đúng/sai. "Chia ra 4 nhóm" hay "chia ra 6 nhóm" đều có thể hội tụ về mặt thuật toán — không có đáp số số học để phân định cái nào đúng hơn.
Điều thay thế cho "so với nhãn thật":
- Đánh giá nội tại (thống kê thuần): đo các nhóm có tách biệt rõ về mặt toán học không, kết quả có ổn định khi chạy lại nhiều lần không. Loại đo này chỉ cho biết cấu trúc có gọn theo nghĩa toán học, không cho biết cấu trúc đó có ý nghĩa với công việc kinh doanh.
- Đánh giá bằng người có chuyên môn nghiệp vụ: đưa các nhóm cho đội marketing xem, hỏi các nhóm này có khớp với hiểu biết thực tế về khách hàng không, có đủ khác biệt để thiết kế chiến dịch riêng không. Đây là bước quyết định thật sự — một phán đoán có cơ sở, không phải một con số.
- Đánh giá qua kết quả xuôi dòng: chạy thử chiến dịch theo từng nhóm rồi đo phản hồi thực tế — nhưng đây là vòng lặp chậm, chỉ có được sau khi đã triển khai.
Đối lập rõ với scenario 2: model risk-scoring có nhãn thật (một giao dịch có phải gian lận hay không, biết chắc sau điều tra) nên nghiệm thu là so khớp với ground truth — đo được bằng một con số. Phân nhóm khách hàng không có ground truth để so — nghiệm thu chuyển từ "đo" sang "thuyết phục người có chuyên môn".
Khung một hình
Hai câu hỏi lọc cho mọi ticket "nghe cần AI", áp lần lượt và dẫn ra ba nhánh kết quả (lần lượt là lời giải Scenario 1, 3, 2):

Ở nhánh supervised, "AUC đẹp trên tập test" chỉ đáng tin nếu feature không leak và tập test mô phỏng đúng điều kiện production — đó là lý do scenario 2 không dừng ở việc chọn paradigm mà còn phải chẩn đoán phép đo.
🎓 Mở rộng
- Ba scenario trong bài này không phải trường hợp hiếm — chúng là ba câu hỏi lặp lại ở hầu hết mọi ticket "làm AI cho X": có luật cố định sẵn không, phép đo có đang bị hỏng theo cách âm thầm không, và có nhãn nào để so sánh không.
- Data leakage và random-split-thay-vì-time-split trong scenario 2 là hai lỗi rất phổ biến trong thực tế — không riêng gì gian lận thẻ, mà ở mọi bài toán dự đoán trên dữ liệu có trục thời gian (churn, giá, nhu cầu). Thói quen tự hỏi "cột này/tập test này có tồn tại đúng vào thời điểm cần dự đoán thật không" áp được cho hầu hết pipeline dạng này.
- "Không có nhãn thì nghiệm thu bằng phán đoán chuyên môn thay vì con số" ở scenario 3 không phải điểm yếu của unsupervised — đó là bản chất bài toán. Nhầm lẫn phổ biến là cố ép một con số đơn lẻ "chứng minh" một kết quả phân nhóm, trong khi câu hỏi thật sự luôn cần người hiểu nghiệp vụ trả lời.
✨ Điều bạn vừa làm được
- Nhận diện được lúc nào một ticket "cần AI" thực chất không cần model nào — kỹ năng hiếm và giá trị hơn việc biết xây model.
- Chẩn đoán được hai lớp lỗi độc lập (leakage ở feature, sai trục thời gian ở split) từ mô tả một pipeline, và giải thích được cơ chế mỗi lỗi thổi phồng con số đo offline.
- Phân biệt được lúc nào bài toán là unsupervised, và vì sao nghiệm thu một kết quả không nhãn phải đổi hẳn cách nhìn so với nghiệm thu một classifier.
Bài tiếp theo: Tổng kết module — cheat sheet & tự đánh giá
Bài này đáng gửi cho bạn học cùng?
Copy link đã gắn nguồn — dán group, chat, hoặc LinkedIn.
Bài này có giúp bạn hiểu bản chất không?
Hỏi đáp về bài này
Chưa có câu hỏi
Có gì chưa rõ trong bài? Đặt câu hỏi đầu tiên — câu trả lời từ cộng đồng giúp bạn (và người sau).
Đặt câu hỏi đầu tiên