Mục đích của việc phát triển mô hình dự đoán là tạo ra một mô hình có độ chính xác cao khi kiểm tra trên bộ dữ liệu độc lập với dữ liệu train (gọi là unseen data
).
Trong bài viết này, chúng ta cùng tìm hiểu hai phương pháp đánh giá một XGBoost model:
train
và test
dataset.k-fold cross-validation
.
Bạn hoàn toàn có thể áp dụng những phương pháp trong bài này cho những ML models khác. Tại vì dạo này mình đang tìm hiểu vê XGBoost model nên mình lấy XGBoost model làm ví dụ thôi.1. Phương pháp 1: Sử dụng train-test set
Đây là phương pháp đơn giản nhất để đánh giá một ML model. Từ tập dữ liệu ban đầu, ta chia thành 2 phần, gọi là train set
và test set
theo tỉ lệ nhất định (thường là 7:3, 8:2 hoặc thậm chí 9:1 tùy theo kích thước của tập và đặc trưng của tập dữ liệu). Sau đó, tiến hành train model trên train set
rồi sử dụng model đã train đó để dự đoán trên tập test set
. Dựa trên kết quả của dự đoán để đưa ra đánh giá chất lượng của model.
Ưu điểm của phương pháp này là nhanh. Nó sẽ phù hợp để áp dụng khi bài toán của bạn đáp ứng ít nhất 1 trong 2 tiêu chí sau:
Nếu điều kiện thứ 2 không thỏa mãn mà ta vẫn sử dụng phương pháp này thì sẽ gặp phải vấn đề high variance
. Tức là khi 2 tập train set
và test set
chứa những đại diện khác nhau của vấn đề cần dự đoán thì kết quả đánh giá trên tập test set
không thể hiện đúng chất lượng của model.
Thư viện scikit-learn
cung cấp hàm train_test_split()
giúp chúng ta thực hiện việc chia dữ liệu:
# split data into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.33, random_state=7)
Source code dưới đây sử dụng Pima Indians onset of diabetes
dataset để train XGBoost model và đánh giá model theo phương pháp này:
# train-test split evaluation of XGBoost model
from numpy import loadtxt
from XGBoost import XGBClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# load data
dataset = loadtxt('pima-indians-diabetes.csv', delimiter=",")
# split data into X and y
X = dataset[:,0:8]
Y = dataset[:,8]
# split data into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.33, random_state=7)
# fit model on training data
model = XGBClassifier()
model.fit(X_train, y_train)
# make predictions for test data
predictions = model.predict(X_test)
# evaluate predictions
accuracy = accuracy_score(y_test, predictions)
print("Accuracy: %.2f%%" % (accuracy * 100.0))
Chạy code trên thu được kết quả:
Accuracy: 74.02%
2. Phương pháp 2: k-fold cross-validation
Cross-validation
là phương pháp mở rộng của phương pháp bên trên để hạn chế được vấn đề high variance
. Các bước tiến hành của nó như sau:
k
phần (k=5,10,…), mỗi phần gọi là một fold
. - train model trên k-1
fold và đánh giá trên fold còn lại.k
lần bước bên trên để mỗi fold trong tập dữ liệu đều có cơ hội trở thành test set
.
Sau khi toàn bộ quá trình kết thúc ta sẽ có k
kết quả đánh giá khác nhau, kêt quả cuối cùng sẽ được tổng hợp dựa vào trung bình (mean
) và độ lệch chuẩn (standard deviation
) của k
kết quả đó.Phương pháp này cho kết quả đánh giá tin cậy hơn so với phương pháp sử dụng train-test set
bởi vì nó được train và đánh giá nhiều lần trên các tập dữ liệu khác nhau. Việc lựa chọn k
cũng cần phải xem xét sao cho kích thước của mỗi fold đủ lớn để dữ liệu trong mỗi fold mang tính đại diện cao về mặt thống kê của toàn bộ dữ liệu. Thực nghiệm cho thấy k=5 hoặc k=10 là lựa chọn tốt nhất cho hầu hết các trường hợp. Hãy sử dụng 2 giá trị này trước khi thử nghiệm với các giá trị khác.
Thư viện scikit-learn
cung cấp lớp KFold
để sử dụng phương pháp này. Đầu tiên, khai báo đối tượng KFold
và chỉ ra giá trị của k
. Sau đó sử dụng hàm cross_val_score()
để bắt đầu đánh giá model.
kfold = KFold(n_splits=10, random_state=7)
results = cross_val_score(model, X, Y, cv=kfold)
Code đầy đủ như bên dưới:
# k-fold cross validation evaluation of XGBoost model
from numpy import loadtxt
from XGBoost import XGBClassifier
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
# load data
dataset = loadtxt('pima-indians-diabetes.csv', delimiter=",")
# split data into X and y
X = dataset[:,0:8]
Y = dataset[:,8]
# CV model
model = XGBClassifier()
kfold = KFold(n_splits=10, random_state=7)
results = cross_val_score(model, X, Y, cv=kfold)
print("Accuracy: %.2f%% (%.2f%%)" % (results.mean()*100, results.std()*100))
Chạy code trên thu được kết quả:
Accuracy: 73.96% (4.77%)
Nếu bài toán là multi-classification
hoặc dữ liệu bị mất cân bằng (imbalanced
) giữa các lớp (số lượng mẫu giữa các lớp chênh lệch nhau lớn) thì ta có thể sử dụng lớp StratifiedKFold
thay vì KFold
của thư viện scikit-learn
. Việc làm này có tác dụng làm cho sự phân phối dữ liệu trong mỗi fold giống nhau hơn, nâng cao hiệu quả của model.
# stratified k-fold cross validation evaluation of XGBoost model
from numpy import loadtxt
from XGBoost import XGBClassifier
from sklearn.model_selection import StratifiedKFold
from sklearn.model_selection import cross_val_score
# load data
dataset = loadtxt('pima-indians-diabetes.csv', delimiter=",")
# split data into X and y
X = dataset[:,0:8]
Y = dataset[:,8]
# CV model
model = XGBClassifier()
kfold = StratifiedKFold(n_splits=10, random_state=7)
results = cross_val_score(model, X, Y, cv=kfold)
print("Accuracy: %.2f%% (%.2f%%)" % (results.mean()*100, results.std()*100))
Chạy code trên được output là:
Accuracy: 73.57% (4.39%)
Có thể thấy ràng variance
có sự giảm nhẹ trong kết quả.
3. Lựa chọn phương pháp đánh giá nào?
k-fold cross-validation
là phương pháp tốt nhất cho việc đánh giá hiệu năng của một ML model trong hầu hết mọi trường hợp.stratified cross-validation
để đảm bảo sự thống nhất về mặt phân phối dữ liệu khi dữ liệu có nhiều lớp cần dự đoán và bị mất cân bằng giữa các lớp.train-test set
trong trường hợp thuật toán train mất nhiều thời gian để hội tụ và số lượng mẫu của dữ liệu rất lớn.Lời khuyên hợp lý nhất là hãy thử nghiệm nhiều lần và tìm ra phương pháp phù hợp với bài toán của bạn sao cho nhanh nhất có thể. Phương pháp được coi là phù hợp khi nó kết quả đánh giá của nó đáp ứng đúng (hoặc gần đúng) yêu cầu bài toán đặt ra ban đầu. Lời khuyên cuối cùng (từ kinh nghiệm thực tế của tác giả):
10-fold cross-validation
cho bài toán regression
.stratified 10-fold-validation
cho bài toán classification
.4. Kết luận
Trong bài viết này, chúng ta đã cùng tìm 2 phương pháp phổ biến đánh gía hiệu quả của một ML model nói chung, XGBoost mode nói riêng:
train-test set
k-fold cross-validation
Ngoài ra, mình cũng đưa vài lời khuyên cho các bạn trong viêc lựa chọn phương pháp nào để áp dụng trong bài toán của các bạn!Trong bài tiếp theo, chúng ta sẽ tìm hiểu cách thức visualize
XGBoost model để hiểu sâu hơn bản chất của nó.
Toàn bộ source code của bài này các bạn có thể tham khảo trên github cá nhân của mình tại github.
Bài viết có tham khảo tại tham khảo