XGBoost – Bài 5: Đánh giá hiệu năng của XGBoost model

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:

  • Sử dụng traintest dataset.
  • Sử dụng 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 settest 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:

  • Tập dữ liệu có kích thước lớn (hàng triệu mẫu) và có cơ sở để tin rằng cả 2 phần dữ liệu đều đại diện đầy đủ cho tất cả các khía cạnh của vấn đề cần dự đoán (để chắc chắn hơn về điều này, ta có thể xáo trộn ngẫu nhiên tập dữ liệu trước khi chia)
  • Thuật toán train của model rất lâu để hội tụ.

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 settest 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:

  • Xáo trộn dữ liệu một cách ngẫu nhiên.
  • Chia tập dữ liệu ban đầu thành 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.
  • Lặp 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?

  • Nói chung, 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.
  • Sử dụng 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.
  • Sử dụng 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ả):

  • Sử dụng 10-fold cross-validation cho bài toán regression.
  • Sử dụng 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:

  • Sử dụng train-test set
  • Sử dụng 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.

Xem bài viết gốc tại đây.

Leave a Reply

Your email address will not be published. Required fields are marked *