Cross-Validation
Kiểm định chéo. Xoay vòng 5 đề thi thử
Một đề thi thử không nói lên gì
Bạn làm một đề thi thử và được 9 điểm. Bạn có chắc mình giỏi thật không? Biết đâu hôm đó may đề dễ. Hôm sau làm đề khác được 5. Rồi 7. Rồi 8. Chỉ khi làm nhiều đề khác nhau và tính trung bình, bạn mới biết thực lực.
Đó chính là cross-validation trong ML. Kiểm định chéo chia dữ liệu thành K phần bằng nhau, rồi xoay vòng: mỗi lượt một phần làm “đề thi”, K-1 phần còn lại làm “sách ôn”. K điểm đánh giá rồi tính trung bình. Đó là thực lực mô hình.
Bạn đã biết chia K phần và xoay vòng. Dataset có 500 mẫu. So K = 2 với K = 500 (leave-one-out). Đánh đổi chính là gì?
Bên dưới là minh hoạ K-Fold. Chọn K để đổi số phần, bấm từng fold để xem phần nào đang làm test, hoặc bấm Play để xem xoay vòng tự động.
Hình minh họa
Điểm từng fold
Quan sát: K càng lớn, mỗi phần (fold) càng nhỏ, nhưng tổng số lượt huấn luyện cũng tăng theo, tốn thời gian hơn.
Một đề không nói lên gì. K đề cho ta trung bình đáng tin.Mỗi mẫu trong dataset đều được thử làm “đề thi” đúng 1 lần, và “sách ôn” (K-1) lần. Điểm cuối cùng không phải một con số mà là cặp (trung bình, độ lệch chuẩn).
Độ lệch chuẩn thấp nghĩa là mô hình ổn định. Độ lệch chuẩn cao nghĩa là có fold đặc biệt dễ hoặc khó, nên kiểm tra dữ liệu có cân đối không.
Bên dưới là dataset 20 hàng, chia thành 5 fold (4 hàng mỗi fold). Bấm “Tiếp tục” để xem 5 lượt huấn luyện. Mỗi lượt, một fold chuyển thành test (màu), 4 fold còn lại là train (xám).
Lượt 1. Fold F1 làm test
Lượt này: 4 hàng của Fold 1 là “đề thi”; 16 hàng còn lại (Fold 2, 3, 4, 5) là “sách ôn”. Kết quả: 85.0%.
Leave-One-Out CV (LOO) là K-Fold với K = n (n là số mẫu dataset). Khi nào dùng LOO hợp lý nhất?
Bạn chạy 5-Fold CV và nhận được scores [95%, 50%, 93%, 48%, 94%]. Trung bình là 76%. Điểm đáng chú ý là gì?
Giải thích
K-Fold Cross-Validation là cách nhân bản phép đo hiệu năng. Dataset được chia thành K phần bằng nhau. Ta lặp K lần: mỗi lần, 1 phần làm test, K-1 phần còn lại làm train. Có K điểm đánh giá, từ đó tính trung bình và độ lệch chuẩn.
Kèm theo là độ lệch chuẩn, đo tính ổn định của ước lượng:
Các biến thể thường gặp (ngắn gọn)
K-Fold thường
Chia ngẫu nhiên K phần đều nhau. Mặc định cho hồi quy, phân loại cân bằng.
Stratified K-Fold
Giữ tỷ lệ lớp trong mỗi fold. Bắt buộc cho phân loại mất cân bằng.
Leave-One-Out
K = n (mỗi lần 1 mẫu test). Dùng khi dataset rất nhỏ.
Time Series Split
Luôn train quá khứ, test tương lai. Bắt buộc cho dữ liệu có thứ tự thời gian.
Group K-Fold
Giữ các mẫu cùng nhóm (bệnh nhân, user) trong cùng một fold để tránh data leakage.
Repeated K-Fold
Chạy K-Fold nhiều lần với seed khác. Ước lượng cực kỳ ổn định, tính được khoảng tin cậy.
KHÔNG được fit scaler / feature selection / imputer trên toàn bộ dữ liệutrước khi CV. Phải đặt trong một pipeline để mỗi fold có preprocessing riêng. Nếu không, thông tin từ test lọt vào train, kết quả CV “ảo” (lạc quan hơn thực tế).
Khi nào nên dùng cross-validation vs train/val/test split?
- Dataset nhỏ (< 10k mẫu): CV để tận dụng tối đa dữ liệu.
- Dataset lớn (> 100k mẫu): train/val/test split một lần là đủ, variance tự nhiên đã thấp.
- Cần báo cáo khoa học hoặc benchmark chính thức: Repeated K-Fold hoặc Nested CV.
- Có time series, group hoặc mất cân bằng: dùng biến thể tương ứng (TimeSeriesSplit, GroupKFold, StratifiedKFold).
Sáu tình huống thực tế. Chọn biến thể CV nào?
| Bài toán | Dataset | CV đề xuất |
|---|---|---|
| Phát hiện gian lận thẻ tín dụng (0.5% gian lận) | 1 triệu giao dịch | Stratified 5-Fold |
| Phân loại X-quang phổi (500 bệnh nhân) | 5.000 ảnh | Group 5-Fold theo bệnh nhân |
| Dự báo giá điện theo giờ | 8.760 giờ × 5 năm | Time Series Split |
| Hồi quy giá nhà | 20.000 mẫu | K-Fold thường (K=10) |
| Nhận dạng giọng nói đa người | 10k clip, 200 speaker | Group 5-Fold theo speaker |
| Publication benchmark về NLP | 50k văn bản | Repeated Stratified 5-Fold |
Checklist 6 điểm trước khi báo cáo kết quả CV
- Preprocessing nằm trong pipeline (fit riêng mỗi fold)?
- Đã dùng Stratified nếu dữ liệu mất cân bằng?
- Đã dùng Time Series Split nếu có thứ tự thời gian?
- Đã dùng Group K-Fold nếu có nhóm tự nhiên?
- Báo cáo kèm cả mean VÀ std (không chỉ mean)?
- Nếu so sánh model: khoảng (mean ± std) có chồng lấn không? Nếu chồng → chưa chắc khác nhau.
Ba sai lầm phổ biến khi dùng cross-validation
Fit StandardScaler trên toàn bộ X trước khi chạy cross_val_score
Vì sao sai: Scaler đã biết mean/std của test fold nên leakage. Kết quả CV lạc quan hơn thực tế 3-8%.
Đặt scaler TRONG pipeline. Scaler fit riêng trên mỗi fold train, rồi transform fold test.
Shuffle dữ liệu chuỗi thời gian rồi K-Fold
Vì sao sai: Tương lai (fold train) biết quá khứ (fold test). Mô hình không phải học dự đoán, mà học nội suy.
Dùng TimeSeriesSplit. Luôn train trước test, không bao giờ ngược lại.
Báo cáo 'độ chính xác 87%' mà không kèm độ lệch chuẩn
Vì sao sai: Có thể đây là 87% ± 9% (rất không ổn định) hoặc 87% ± 1% (rất ổn định). Hai tình huống khác hẳn.
Luôn báo cáo (mean ± std) của K fold. Nếu cần so sánh 2 mô hình, dùng paired test.
- Chia một lần là một đề thi may rủi. Chia K phần và xoay vòng cho K đề, trung bình ổn định hơn.
- K=5 hoặc K=10 là mặc định. Báo cáo luôn kèm mean ± std. Std cao là cờ đỏ.
- Stratified cho phân loại mất cân bằng, Time Series Split cho dữ liệu thời gian, Group K-Fold cho dữ liệu có nhóm tự nhiên.
- Cạm bẫy: fit preprocessing TRƯỚC CV sẽ gây leakage. Luôn đặt scaler/encoder trong pipeline để mỗi fold có preprocessing riêng.
- Leave-One-Out chỉ dùng khi dataset cực nhỏ. Repeated K-Fold khi cần báo cáo khoa học với khoảng tin cậy.
Kiểm tra hiểu biết
Tại sao cross-validation tốt hơn chia train/test một lần?