Model Evaluation & Selection
Đánh giá và chọn mô hình
5 model candidate cùng dự đoán gian lận thẻ. Model A accuracy 98,4%, Model B accuracy 97,9%. A thắng?
Hình minh họa
4 model đã huấn luyện — chọn cái nào?
Bốn model dưới đây đã chạy xong trên cùng tập dữ liệu phát hiện gian lận. Con số của chúng được thiết kế để không model nào thống trị: mỗi model mạnh ở một trục khác nhau. Bạn kéo trọng số cho từng metric — dashboard sẽ sắp xếp lại thứ hạng ngay tức khắc. Hãy thử:
- Chỉ quan tâm accuracy → ai lên đầu?
- Tăng weight recall (sợ bỏ sót gian lận) → thứ tự đổi ra sao?
- Cần latency thấp cho thanh toán realtime → ai rơi xuống?
Tỉ lệ dự đoán đúng trên toàn bộ test set
Trong các ca báo gian lận, bao nhiêu đúng là gian lận?
Trong các ca gian lận thật, model bắt được bao nhiêu?
Trung bình điều hòa của precision và recall
Thời gian chấm 1000 giao dịch (ms) — càng thấp càng tốt
Thời gian huấn luyện một lần (phút) — càng thấp càng tốt
F1 cao nhất, inference nhanh, nhưng train lâu và cần tuning nhiều tham số. Ứng viên hàng đầu cho production.
Cân bằng tốt giữa precision và recall. Train nhanh, nhưng inference chậm hơn logistic vì phải hỏi cả trăm cây.
Recall tốt nhất — bắt được nhiều ca gian lận nhất. Bù lại train lâu nhất và inference chậm nhất. Chọn nó khi chi phí bỏ sót cao.
Siêu nhanh, dễ giải thích, accuracy cao ngất — nhưng chính accuracy cao đang đánh lừa bạn. Nó bỏ sót hơn nửa số ca gian lận.
Metrics không phải một loại. Mỗi bài toán có nhóm metrics riêng. Bấm qua 4 tab dưới để thấy visual + một đoạn code sklearn nhỏ cho mỗi nhóm.
Kéo ngưỡng (threshold) để thấy confusion matrix đổi ra sao. Threshold thấp: bắt nhiều gian lận (recall cao) nhưng báo động giả nhiều (precision thấp). Threshold cao: ngược lại.
from sklearn.metrics import (
precision_score, recall_score, f1_score, roc_auc_score,
)
# y_true: nhãn thật, y_pred: dự đoán (0/1), y_proba: xác suất
print("Precision:", precision_score(y_true, y_pred))
print("Recall: ", recall_score(y_true, y_pred))
print("F1: ", f1_score(y_true, y_pred))
print("ROC AUC: ", roc_auc_score(y_true, y_proba))Chọn model không phải tìm “model tốt nhất” — mà là biên soạn một bộ yêu cầu rồi tìm model thoả mãn nó.
Bộ yêu cầu thường gồm: metric chính (tuỳ bài toán), ràng buộc thời gian (train, inference), khả năng giải thích (cho khách hàng, quy định), và chi phí (tính toán, bảo trì). Khi bạn đã viết bộ yêu cầu, model trả lời gần như hiện ra.
Model X được quảng cáo: ROC AUC = 0,95. Bạn triển khai thử — accuracy chỉ 55%. Chuyện gì xảy ra?
Giải thích
Đánh giá và chọn mô hình đi theo vòng lặp 4 bước: huấn luyện → dự đoán → đo lường → so sánh. Mỗi vòng lặp cho bạn thêm hiểu biết để tinh chỉnh: đổi hyperparameter, thêm feature, hoặc chuyển hẳn sang model khác.
Quy trình 5 bước so sánh model khoa học
Trước khi mở editor, hãy viết ra giấy: bài toán là classification hay regression? Dữ liệu cân bằng không? Latency giới hạn bao nhiêu? Chi phí sai âm (bỏ sót) vs sai dương (báo giả) khác nhau ra sao? Bộ yêu cầu này là la bàn — mọi quyết định sau đó đều nhìn nó.
ROC AUC — công thức một dòng, ý nghĩa một đời
ROC AUC là xác suất model đưa ra score cao hơn cho một mẫu dương ngẫu nhiên so với một mẫu âm ngẫu nhiên:
Nói ngắn gọn: đưa model hai giao dịch — một gian lận thật, một bình thường. AUC = 0,95 nghĩa là 95% số lần model xếp giao dịch gian lận có score cao hơn. AUC 0,50 = đoán mò. AUC 1,0 = hoàn hảo. Biểu đồ dưới cho 3 mức AUC:
Average Precision (AP) — bạn bè thân thiết của AUC cho dữ liệu mất cân bằng
AP là diện tích dưới precision-recall curve. Khi gian lận chỉ chiếm 1% dữ liệu, AUC có thể cao giả tạo (vì TN rất nhiều). AP nhìn trực tiếp vào đường precision-recall — phản ánh thực chất hơn. Quy tắc: dữ liệu mất cân bằng trên 1:20 → ưu tiên AP hơn AUC.
Code: cross_val_score + GridSearchCV trong 13 dòng
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score
models = {
"LogReg": LogisticRegression(max_iter=1000, random_state=42),
"RandomForest": RandomForestClassifier(n_estimators=100, random_state=42),
}
for name, m in models.items():
scores = cross_val_score(m, X, y, cv=5, scoring="f1_weighted")
print(f"{name}: F1 = {scores.mean():.3f} +/- {scores.std():.3f}")from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier
param_grid = {
"n_estimators": [100, 300],
"max_depth": [None, 8, 16],
"min_samples_leaf": [1, 4],
}
grid = GridSearchCV(RandomForestClassifier(random_state=42),
param_grid, cv=5, scoring="f1", n_jobs=-1)
grid.fit(X_train, y_train)
print("Best:", grid.best_params_, "score:", grid.best_score_)sklearn.metrics.classification_report(y_true, y_pred) in ra precision, recall, F1 cho từng lớp, macro-avg, weighted-avg. Luôn in báo cáo này song song với accuracy để phát hiện bất cân bằng sớm.
Sơ đồ quyết định: chọn metric theo bài toán
- Không có model 'tốt nhất' chung — chỉ có model phù hợp nhất cho bộ yêu cầu cụ thể của bài toán.
- Accuracy bị đánh lừa khi dữ liệu mất cân bằng — luôn kèm precision/recall/F1 hoặc AP.
- ROC AUC đo khả năng xếp hạng; accuracy đo trên một threshold — hai câu chuyện khác nhau.
- Cross-validation 5-fold + báo cáo mean ± std, không chỉ một con số.
- Latency, train time, khả năng giải thích luôn nằm cùng bàn cân với F1 — đừng chỉ nhìn một trục.
Kiểm tra hiểu biết
Bạn có 4 model dự đoán gian lận. Tất cả đều đạt accuracy 98%. Nên nhìn vào đâu tiếp theo?