Evaluating Models - Đánh giá mô hình
Evaluating Models - Đánh giá mô hình
Hãy tưởng tượng một học sinh chuẩn bị thi đại học. Bạn đưa cho em đó 10 bộ đề thi thử kèm đáp án chi tiết. Em đó ngồi cày ngày đêm và học thuộc làu từng dấu chấm, dấu phẩy. Khi bạn kiểm tra lại trên đúng 10 bộ đề đó, em đạt 10 điểm tuyệt đối.
Nhưng ngày thi thật, phòng thi phát ra một bộ đề mới toanh với các con số đã được thay đổi. Em đó hoang mang và chỉ đạt 3 điểm.
Hiện tượng này xảy ra y hệt trong Machine Learning:
Một mô hình đạt độ chính xác 100% trên dữ liệu nó đã học chưa chắc là một mô hình tốt. Nó có thể chỉ là một kẻ học vẹt (Overfitting).
Mục tiêu tối thượng của Machine Learning không phải là nhớ lại quá khứ, mà là Khả năng tổng quát hóa (Generalization): Học quy luật cốt lõi từ dữ liệu cũ để đưa ra quyết định chính xác trên dữ liệu hoàn toàn mới trong tương lai.
1. Loss Function - Đo lường “nỗi đau” khi đoán sai
Để dạy máy tính biết nó đang sai ở đâu và sai nhiều hay ít, ta cần một chiếc thước đo gọi là Hàm mất mát (Loss Function):
Trong đó là đáp án thật (ground truth), còn là kết quả mô hình dự đoán.
1.1 0-1 Loss (Dành cho Phân loại)
Đoán đúng thì không phạt (), đoán sai thì phạt :
- Ưu điểm: Cực kỳ dễ hiểu.
- Hạn chế: Hàm này gián đoạn, không có đạo hàm, nên không thể dùng phương pháp Gradient Descent để tối ưu hóa trọng số.
1.2 L1 Loss - Sai số tuyệt đối (MAE: Mean Absolute Error)
Thường dùng cho bài toán Hồi quy (Regression):
- Đặc tính: Đo khoảng cách sai lệch thực tế. Nếu dự đoán giá nhà 3 tỷ nhưng thực tế là 3.5 tỷ, lỗi là tỷ.
- Ưu điểm lớn: Rất bền vững trước dữ liệu ngoại lai (Robust to outliers). Nếu có một vài mẫu bị nhập sai số liệu cực lớn, L1 không bị kéo lệch quá đà.
1.3 L2 Loss - Sai số bình phương (MSE: Mean Squared Error)
Cũng dùng cho bài toán Hồi quy, nhưng bình phương sai số lên:
- Đặc tính: Phạt theo hàm mũ. Sai lệch nhỏ () phạt rất nhẹ (), nhưng sai lệch lớn () phạt cực nặng ().
- Đi sâu vào bản chất toán học: L2 Loss có đạo hàm trơn tru và liên tục ở mọi điểm, rất thuận lợi cho tối ưu toán học. Tuy nhiên, nó cực kỳ nhạy cảm với outliers. Một điểm dữ liệu rác có sai số khổng lồ có thể bẻ cong toàn bộ đường hồi quy của mô hình.
2. Phân chia dữ liệu: Train - Validation - Test
Để kiểm tra xem học sinh có thực sự hiểu bài hay chỉ học vẹt, ta bắt buộc phải giấu đề thi thật đi. Tập dữ liệu ban đầu phải được chia tách rõ ràng:
Vai trò của từng tập dữ liệu:
- Training Set: Là sách giáo khoa và bài tập về nhà. Thuật toán quét qua tập này nhiều lần để tối ưu các tham số nội tại (weights , bias ).
- Validation Set (Tập kiểm định): Là các bài kiểm tra 15 phút trên lớp. Người kỹ sư dùng tập này để thử nghiệm: Nên chọn hay cho k-NN? Nên chọn hay cho SVM? Mô hình nào đạt điểm cao nhất trên Validation Set sẽ được chọn.
- Test Set (Tập kiểm thử độc lập): Là đề thi tốt nghiệp cuối kỳ. Tuyệt đối không được cho mô hình hay người kỹ sư nhìn thấy tập này trong quá trình huấn luyện và tinh chỉnh! Chỉ khi nào đã chốt mô hình cuối cùng, ta mới mang Test Set ra đánh giá một lần duy nhất để báo cáo hiệu năng thực tế.
🚨 Cảnh báo Data Snooping: Nếu bạn lấy Test Set ra để tune tham số hoặc chọn mô hình, bạn đã biến Test Set thành một phần của quá trình học. Điểm số báo cáo lúc này là một lời nói dối ngọt ngào!
3. Bản chất cốt lõi: Bias - Variance Tradeoff
Mọi sai số trong Machine Learning thực chất đều xuất phát từ cuộc chiến giằng co giữa hai thế lực: Độ lệch (Bias) và Phương sai (Variance).
3.1 Trực giác đời thường
- High Bias (Độ lệch cao - Underfitting): Giống như một người bảo thủ, đầu óc đóng kín. Bạn giải thích bao nhiêu ví dụ họ cũng chỉ khăng khăng giữ một định kiến đơn giản ban đầu.
- Dấu hiệu: Điểm trên Training Set rất thấp, điểm trên Test Set cũng rất thấp.
- High Variance (Phương sai cao - Overfitting): Giống như một người nhạy cảm, lo âu thái quá. Gặp bất kỳ trường hợp cá biệt hay hạt bụi nào cũng coi là chân lý và tự phức tạp hóa vấn đề.
- Dấu hiệu: Điểm trên Training Set gần như tuyệt đối (99-100%), nhưng điểm trên Test Set rớt thảm hại (50-60%).
3.2 Đi sâu vào bản chất: Phân rã lỗi toán học (Bias-Variance Decomposition)
Với bất kỳ bài toán hồi quy nào, kỳ vọng sai số bình phương trên dữ liệu mới luôn có thể phân rã thành đúng 3 thành phần:
- (Sai lệch bản chất): Sai số do các giả định đơn giản hóa quá mức của mô hình (ví dụ: dùng đường thẳng để xấp xỉ một đường cong parabolic).
- (Độ dao động): Mức độ nhạy cảm của mô hình đối với sự thay đổi của tập dữ liệu huấn luyện. Nếu ta thay đổi một vài mẫu trong train set mà mô hình thay đổi hình dạng chóng mặt High Variance.
- (Nhiễu tự nhiên không thể giảm): Nhiễu ngẫu nhiên vốn có của thế giới thực (dù thuật toán có hoàn hảo đến đâu cũng không thể xóa bỏ).
4. Regularization - Phanh hãm độ phức tạp
Làm thế nào để ngăn chặn một mô hình phức tạp rơi vào cái bẫy Overfitting? Ta dùng kỹ thuật Chính quy hóa (Regularization).
Ý tưởng: Thêm một “khoản tiền phạt” (Penalty) vào hàm mất mát nếu mô hình cố tình dùng các trọng số quá lớn:
Trong đó là hệ số điều khiển lực phanh.
Hai loại Regularization phổ biến nhất:
| Tiêu chí | L2 Regularization (Ridge) | L1 Regularization (Lasso) |
|---|---|---|
| Công thức phạt | ||
| Hành vi trọng số | Kéo tất cả trọng số về rất gần 0, nhưng hiếm khi bằng đúng 0. | Có xu hướng triệt tiêu hẳn nhiều trọng số về đúng bằng 0! |
| Ứng dụng thực tế | Làm cho mô hình mượt mà, ổn định hơn khi các đặc trưng bị đa cộng tuyến. | Hoạt động như một công cụ tự động chọn lọc đặc trưng (Feature Selection). Đặc trưng nào vô dụng sẽ bị gán để loại bỏ. |
- Nếu : Không có phanh phạt Dễ bị Overfitting.
- Nếu quá lớn: Lực phanh quá mạnh ép mọi trọng số Mô hình trở nên trơ lì, bị Underfitting.
5. k-Fold Cross-Validation: Tận dụng từng giọt dữ liệu
Nếu bạn chỉ có một tập dữ liệu nhỏ (ví dụ vài trăm mẫu), việc cắt hẳn 20-30% ra làm Test Set sẽ khiến lượng dữ liệu dùng để học bị hao hụt nghiêm trọng. Hơn nữa, kết quả đánh giá có thể bị may rủi do những điểm dữ liệu “dễ” hoặc “khó” vô tình rơi vào test set.
Giải pháp là k-Fold Cross-Validation (Kiểm định chéo k-lần):
Thuật toán từng bước:
- Chia toàn bộ tập dữ liệu thành phần bằng nhau (thường chọn hoặc ).
- Lặp vòng:
- Ở vòng , lấy phần thứ làm Validation set.
- Dùng phần còn lại gộp lại làm Training set.
- Huấn luyện mô hình và ghi nhận điểm số hiệu năng .
- Điểm số cuối cùng là trung bình cộng của lần chạy:
💡 Kinh nghiệm: Báo cáo chuẩn công nghiệp không chỉ đưa ra điểm trung bình , mà còn kèm theo độ lệch chuẩn (ví dụ: ). Nếu quá lớn, mô hình của bạn đang chạy rất bất ổn trên các lát cắt dữ liệu khác nhau.
6. Cái bẫy của Accuracy và Ma trận nhầm lẫn (Confusion Matrix)
Rất nhiều người mới học AI tự hào khoe: “Mô hình của tôi đạt độ chính xác (Accuracy) 99.9%!” Nhưng 99.9% có thể là một thảm họa lừa đảo.
Kịch bản thực tế: Chẩn đoán căn bệnh hiểm nghèo
Giả sử trong 10.000 người dân, có đúng 10 người thực sự nhiễm bệnh hiểm nghèo (tỷ lệ ). Một bạn sinh viên lười biếng viết một chương trình AI chỉ có đúng một dòng:
def predict(patient):
return "KHONG_BENH" # Luôn luôn đoán Không bệnh!
Độ chính xác của hàm này là bao nhiêu?
(Với người đoán đúng trên tổng số người).
Con số 99.9% nghe như mơ, nhưng hệ thống này đã bỏ sót 100% bệnh nhân thực sự, khiến họ mất đi cơ hội cứu sống. Khi dữ liệu bị mất cân bằng lớp (Imbalanced Data), Accuracy hoàn toàn vô dụng!
Ma trận nhầm lẫn (Confusion Matrix)
Để nhìn xuyên qua bức màn dối trá của Accuracy, ta dùng bảng 4 ô thần thánh:
| Dự đoán là DƯƠNG TÍNH (Positive) | Dự đoán là ÂM TÍNH (Negative) | |
|---|---|---|
| Thực tế DƯƠNG TÍNH (Có bệnh) | True Positive (TP) Đoán có bệnh Thật sự có bệnh (Bắt đúng bệnh) | False Negative (FN) Đoán không bệnh Nhưng thực tế có bệnh (Bỏ sót kẻ địch!) |
| Thực tế ÂM TÍNH (Không bệnh) | False Positive (FP) Đoán có bệnh Nhưng thực tế khỏe mạnh (Báo động giả!) | True Negative (TN) Đoán không bệnh Thật sự khỏe mạnh (Xác nhận chuẩn) |
7. Bộ ba thước đo sống còn: Precision, Recall và F1-Score
Từ Confusion Matrix, ta định nghĩa 3 chỉ số then chốt:
7.1 Precision (Độ chuẩn xác) - “Đã báo là phải đúng!”
Trong số tất cả những lần mô hình hô to “Dương tính!”, có bao nhiêu phần trăm là đúng sự thật?
- Khi nào cần Precision cực cao? Khi cái giá của việc Báo động giả (False Positive) quá đắt.
- Ví dụ: Bộ lọc email Spam. Nếu nó báo nhầm một email nhận việc quan trọng của bạn thành Spam và ném vào thùng rác (False Positive), bạn sẽ mất sự nghiệp. Người dùng thà chịu nhìn thấy vài cái mail rác còn hơn bị mất mail quan trọng.
7.2 Recall (Độ bao phủ / Nhạy) - “Thà bắt nhầm còn hơn bỏ sót!”
Trong toàn bộ số người thực sự bị bệnh ngoài đời, mô hình đã tóm được bao nhiêu phần trăm?
- Khi nào cần Recall cực cao? Khi cái giá của việc Bỏ sót (False Negative) là chết người.
- Ví dụ: Phát hiện khối u ung thư, phát hiện giao dịch rửa tiền khủng bố, cảnh báo động đất/sóng thần. Báo động nhầm đi khám lại không sao, nhưng nếu bỏ sót một ca bệnh nặng thì bệnh nhân có thể tử vong.
7.3 F1-Score: Sự cân bằng hoàn hảo
Nếu bạn muốn một con số duy nhất để dung hòa giữa Precision và Recall, ta dùng F1-Score:
❓ Tại sao F1 lại dùng Trung bình điều hòa (Harmonic Mean) mà không dùng Trung bình cộng bình thường? Bởi vì Trung bình điều hòa trừng phạt rất nặng sự thiên lệch! Nếu một mô hình có Precision = nhưng Recall = (hoặc ngược lại), trung bình cộng sẽ cho ra (nghe vẫn tạm được), nhưng F1-Score sẽ lập tức rớt thẳng đứng về . F1 chỉ cao khi cả Precision và Recall đều đồng thời ở mức tốt!
8. Bốn cạm bẫy thực chiến “chết người” khi triển khai AI (Production Pitfalls)
Đây là những kinh nghiệm xương máu mà các kỹ sư AI thực thụ rút ra sau nhiều lần thất bại đau đớn:
8.1 Rò rỉ dữ liệu khi tiền xử lý (Preprocessing Leakage)
- Sai lầm phổ biến: Tải dữ liệu về, gọi
StandardScaler().fit_transform(X)trên toàn bộ dataset rồi mới gọitrain_test_split(). - Hậu quả: Khi tính trung bình và độ lệch chuẩn trên toàn bộ dữ liệu, thông tin phân phối của Test Set đã rò rỉ vào Training Set. Mô hình đạt điểm cao ảo khi test nhưng thất bại ngoài đời.
- Giải pháp: Luôn luôn dùng
Pipelinecủa scikit-learn. Scaler chỉ được phép.fit()trên Training Set!
8.2 Rò rỉ dữ liệu chuỗi thời gian (Temporal Leakage)
- Sai lầm phổ biến: Dự đoán giá cổ phiếu ngày mai nhưng lại dùng hàm
train_test_split(shuffle=True)ngẫu nhiên. - Hậu quả: Mô hình lấy dữ liệu của ngày thứ Sáu để học cách dự đoán cho ngày thứ Ba! Trong thế giới thực, bạn không bao giờ có cỗ máy thời gian để biết trước tương lai.
- Giải pháp: Với dữ liệu có yếu tố thời gian, bắt buộc phải chia theo mốc thời gian (Time-based Split: Dùng năm 2021-2023 để train, năm 2024 để test).
8.3 Định luật Goodhart (Goodhart’s Law)
“Khi một thước đo trở thành mục tiêu, nó không còn là một thước đo tốt.”
Nếu bạn đánh giá đội ngũ kỹ sư bằng số lượng bug tìm được, họ sẽ tự tạo ra bug dễ rồi tự fix. Nếu bạn tối ưu AI bằng thời lượng xem video (Watch time), AI của bạn sẽ học cách lan truyền tin giả giật gân và thuyết âm mưu vì chúng kích thích sự tò mò của con người nhất. Hãy luôn cảnh giác với các hệ quả tiêu cực ngoài ý muốn khi chọn metric.
8.4 Hiện tượng Trôi dạt dữ liệu (Data Drift & Concept Drift)
Một mô hình phân loại email rác chạy hoàn hảo vào năm 2020 sẽ bị phế thải vào năm 2026. Tại sao? Vì kẻ lừa đảo liên tục đổi mới từ ngữ, công nghệ thay đổi, và hành vi người dùng dịch chuyển. Một mô hình AI đưa vào vận hành thực tế không bao giờ là “xong một lần là xong mãi mãi”. Hệ thống bắt buộc phải có cơ chế giám sát liên tục (Continuous Monitoring) và tái huấn luyện (Retraining) định kỳ.
9. Code mẫu chuẩn công nghiệp với scikit-learn
Dưới đây là một template hoàn chỉnh và an toàn tuyệt đối, tuân thủ mọi nguyên tắc chống rò rỉ dữ liệu:
import numpy as np
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split, cross_val_score, StratifiedKFold
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import make_pipeline
from sklearn.metrics import classification_report, confusion_matrix
# 1. Tạo giả lập dữ liệu mất cân bằng (90% lớp 0, 10% lớp 1)
X, y = make_classification(
n_samples=1000, n_features=10, weights=[0.9, 0.1], random_state=42
)
# 2. Tách Train / Test an toàn có giữ nguyên tỷ lệ lớp (stratify=y)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
# 3. Đóng gói Scaler và Model vào Pipeline để chống Data Leakage
pipeline = make_pipeline(
StandardScaler(),
LogisticRegression(C=1.0, class_weight="balanced") # class_weight hỗ trợ imbalanced
)
# 4. Kiểm định chéo 5-Fold trên Training Set
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
cv_scores = cross_val_score(pipeline, X_train, y_train, cv=cv, scoring="f1")
print(f"F1 Cross-Validation: {cv_scores.mean():.4f} (+/- {cv_scores.std():.4f})")
# 5. Huấn luyện trên toàn bộ Train Set và đánh giá duy nhất 1 lần trên Test Set
pipeline.fit(X_train, y_train)
y_pred = pipeline.predict(X_test)
# 6. Báo cáo toàn diện: Confusion Matrix và Precision/Recall/F1
print("\nMa trận nhầm lẫn:")
print(confusion_matrix(y_test, y_pred))
print("\nBáo cáo phân loại chi tiết:")
print(classification_report(y_test, y_pred, target_names=["Bình thường (0)", "Nguy cơ (1)"]))
10. Câu hỏi tự kiểm tra & Thảo luận
1. Bạn xây dựng mô hình AI phát hiện người mang vũ khí qua cửa an ninh sân bay. Bạn sẽ ưu tiên tối ưu hóa Precision hay Recall? Tại sao?
Bắt buộc phải ưu tiên Recall! Việc chặn nhầm một hành khách vô tội để kiểm tra lại vali (False Positive) chỉ gây chậm trễ vài phút. Nhưng nếu để lọt dù chỉ một khẩu súng thật lên máy bay (False Negative) thì hậu quả sẽ là thảm họa khủng bố cướp đi sinh mạng của hàng trăm người.
2. Tại sao gọi việc chuẩn hóa (Scaling) toàn bộ tập dữ liệu trước khi train_test_split là hành vi “Rò rỉ dữ liệu” (Data Leakage)?
Vì hàm chuẩn hóa cần tính giá trị trung bình và phương sai của toàn bộ dữ liệu. Nếu bạn tính trên cả tập Test, các giá trị và này đã chứa đựng thông tin của các mẫu trong tương lai. Mô hình khi train vô tình được “nhìn lén” phân phối của bài thi test, dẫn đến kết quả đánh giá không còn khách quan.
3. Mô hình của bạn có Training Error = 1% nhưng Test Error = 35%. Đây là triệu chứng của bệnh gì? Bạn sẽ kê đơn thuốc nào để chữa?
Đây là triệu chứng kinh điển của Overfitting (High Variance). Đơn thuốc điều trị:
- Thu thập thêm dữ liệu huấn luyện mới.
- Thêm Regularization (tăng hệ số phạt của L1/L2 hoặc giảm tham số trong SVM/Logistic Regression).
- Giảm bớt số lượng đặc trưng không cần thiết (Feature Selection).
- Giảm bớt độ phức tạp của mô hình (ví dụ: tăng trong k-NN, giảm độ sâu của cây quyết định).
11. Tài liệu tham khảo
- CS50 AI Lecture 4 - Evaluating Hypotheses, Overfitting, Regularization, Cross-Validation.
- Hastie, T., Tibshirani, R., & Friedman, J., The Elements of Statistical Learning, Springer (Chương về Model Assessment and Selection).
- Scikit-learn Documentation: Model Evaluation and Scoring Metrics, Common Pitfalls and Recommended Practices.
- Goodhart, C. A. E. (1984), Problems of Monetary Management: The U.K. Experience.