Chia tập train/validation/test
Bạn sẽ học được
- Vì sao cần ba tập train, validation và test.
- Chia dữ liệu đúng cách với dữ liệu mất cân bằng.
- Chia theo thời gian cho dữ liệu chuỗi.
- Chia theo nhóm để tránh cùng một khách xuất hiện ở hai tập.
- Những cách dùng tập test làm hỏng đánh giá.
Khái niệm cốt lõi
Ba tập có ba nhiệm vụ khác nhau:
| Tập | Dùng để | Được xem bao nhiêu lần |
|---|---|---|
| Train | Học tham số | Nhiều lần |
| Validation | Chọn mô hình và siêu tham số | Nhiều lần |
| Test | Ước lượng hiệu năng cuối cùng | Một lần |
Nếu dùng test để chọn siêu tham số, test trở thành validation và mất khả năng ước lượng khách quan.
Tỷ lệ phổ biến 60/20/20. Với dữ liệu nhỏ, dùng cross-validation thay cho validation cố định — bài 7 sẽ làm.
Ví dụ chia
10.000 khách, 5% huỷ tức 500 ca dương:
| Tập | Số dòng | Ca huỷ |
|---|---|---|
| Train | 6.000 | 300 |
| Validation | 2.000 | 100 |
| Test | 2.000 | 100 |
Nếu chia ngẫu nhiên không stratify, tập test có thể chỉ có 60 ca huỷ — đủ ít để một vài dự đoán sai làm thay đổi kết luận.
Stratify
from sklearn.model_selection import train_test_split
X_tmp, X_test, y_tmp, y_test = train_test_split(
X, y, test_size=0.2, stratify=y, random_state=42
)
X_train, X_val, y_train, y_val = train_test_split(
X_tmp, y_tmp, test_size=0.25, stratify=y_tmp, random_state=42
)test_size=0.25 trên 80% còn lại cho ra 20% tổng. Đây là cách chia ba tập từ hai lần gọi.
stratify giữ tỷ lệ lớp ở mỗi tập. Với bài toán mất cân bằng, đây không phải tuỳ chọn mà là bắt buộc.
Chia theo thời gian
Với dữ liệu có thời gian, chia ngẫu nhiên gây rò rỉ: mô hình học từ tương lai để dự đoán quá khứ.
train = df[df["event_date"] <= "2024-12-31"]
val = df[(df["event_date"] >= "2025-01-01") & (df["event_date"] <= "2025-03-31")]
test = df[(df["event_date"] >= "2025-04-01") & (df["event_date"] <= "2025-06-30")]Ba quy tắc:
- Train luôn là quá khứ so với validation và test.
- Không xáo trộn thứ tự thời gian.
- Kiểm tra phân phối giữa các kỳ; nếu doanh thu tăng mạnh, mô hình huấn luyện trên kỳ cũ có thể kém trên kỳ mới.
Chia theo nhóm
Nếu mỗi khách có nhiều dòng (nhiều đơn, nhiều phiên), chia ngẫu nhiên đặt cùng một khách ở cả train và test. Mô hình chỉ cần nhớ khách đó là đủ — điểm test bị thổi phồng.
from sklearn.model_selection import GroupShuffleSplit
splitter = GroupShuffleSplit(n_splits=1, test_size=0.2, random_state=42)
train_idx, test_idx = next(splitter.split(X, y, groups=df["customer_id"]))Dấu hiệu cần chia theo nhóm: có cột định danh lặp lại, và mô hình cho điểm rất cao bất thường.
Dùng test sai cách
Ba cách làm hỏng tập test:
- Xem test nhiều lần và chỉnh mô hình. Sau vài chục lần, test đã đóng vai validation.
- Chọn mô hình tốt nhất theo test. Con số cuối cùng là của mô hình may mắn, không phải mô hình tốt.
- Huấn luyện lại trên train + test sau khi chọn. Không còn gì để đánh giá.
Cách đúng: chọn mọi thứ trên validation, chỉ chạm test một lần ở cuối, và ghi lại con số đó trước khi triển khai.
Kiểm tra sau khi chia
print("Train:", len(X_train), y_train.mean().round(3))
print("Val: ", len(X_val), y_val.mean().round(3))
print("Test: ", len(X_test), y_test.mean().round(3))Ba tỷ lệ phải xấp xỉ nhau. Chênh lệch lớn nghĩa là chia sai hoặc dữ liệu có vấn đề theo thời gian.
Kiểm tra thêm: không có customer_id nào xuất hiện ở cả train và test nếu chia theo nhóm; khoảng thời gian của ba tập không chồng lấn nếu chia theo thời gian.
Lỗi thường gặp
- Chỉ chia hai tập: không có validation, phải dùng test để chọn mô hình.
- Không stratify: tập test thiếu ca dương.
- Chia ngẫu nhiên dữ liệu thời gian: rò rỉ tương lai.
- Cùng khách ở hai tập: điểm test cao giả tạo.
- Xem test quá nhiều lần: test mất tính độc lập.
- Huấn luyện lại trên toàn bộ dữ liệu trước khi báo cáo: con số báo cáo không còn đúng.
- Không kiểm tra phân phối sau chia: không phát hiện lệch.
Thực hành
- Chia 10.000 dòng thành 60/20/20 có stratify.
- Kiểm tra số ca dương ở mỗi tập.
- Chia dữ liệu thời gian thành ba kỳ không chồng lấn.
- Dùng
GroupShuffleSplittheocustomer_id. - Giải thích vì sao dùng test để chọn
Clà sai.
Lỗi thường gặp
| Triệu chứng | Nguyên nhân | Cách sửa |
|---|---|---|
| Test quá ít ca dương | Không stratify | stratify=y |
| Điểm test cao hơn thực tế | Cùng khách ở hai tập | Chia theo nhóm |
| Mô hình kém khi triển khai | Chia ngẫu nhiên dữ liệu thời gian | Chia theo mốc thời gian |
| Không tái lập được | Không đặt seed | random_state |
| Kết quả cuối quá đẹp | Chọn mô hình trên test | Chọn trên validation |
Tóm tắt
- Train học, validation chọn, test đánh giá một lần.
- Luôn stratify khi lớp mất cân bằng.
- Dữ liệu thời gian phải chia theo mốc thời gian.
- Dữ liệu lặp theo đối tượng phải chia theo nhóm.
- Chạm test một lần và ghi lại con số trước khi triển khai.
Use ← → to move between lessons