Giới thiệu chung về AUC và vai trò của nó trong mô hình dự báo

AUC (Area Under the Curve), hay còn gọi là diện tích dưới đường ROC (Receiver Operating Characteristic), là một trong những chỉ số quan trọng nhất để đánh giá hiệu suất của các mô hình phân loại, đặc biệt là trong các bài toán nhị phân. Khi chúng ta xây dựng một mô hình dự báo (ví dụ: dự đoán khách hàng sẽ rời bỏ dịch vụ, phát hiện gian lận, chẩn đoán bệnh…), việc đo lường độ chính xác, độ nhạy (sensitivity) và độ đặc hiệu (specificity) là rất cần thiết. AUC cung cấp một cách tổng hợp để so sánh các mô hình mà không phụ thuộc vào một ngưỡng quyết định cố định.

  • Giá trị AUC nằm trong khoảng 0, 1:
  • AUC = 0.5: mô hình không tốt hơn ngẫu nhiên.
  • AUC > 0.5: mô hình có khả năng phân biệt tốt hơn ngẫu nhiên.
  • AUC = 1: mô hình hoàn hảo (không có lỗi nào).

Vì vậy, việc vẽ đồ thị ROC và tính AUC là bước không thể thiếu trong quy trình kiểm định mô hình, và R là một trong những ngôn ngữ lập trình mạnh mẽ, linh hoạt để thực hiện công việc này.

Trong bài viết này, chúng ta sẽ:

  1. Giới thiệu các gói (packages) phổ biến trong R hỗ trợ tính toán và vẽ ROC/AUC.
  2. Hướng dẫn chi tiết cách chuẩn bị dữ liệu, huấn luyện mô hình và dự đoán xác suất.
  3. Trình bày cách vẽ ROC curve, tính AUC bằng các hàm chuẩn và tùy biến.
  4. So sánh các mô hình bằng cách vẽ nhiều ROC trên cùng một biểu đồ.
  5. Giới thiệu một số kỹ thuật nâng cao: cross‑validation, bootstrap confidence intervals, và việc vẽ Precision‑Recall curve (PRC) cho các tập dữ liệu mất cân bằng.
  6. Đưa ra một ví dụ thực tế (dữ liệu “Pima Indians Diabetes” và “German Credit”) để minh hoạ toàn bộ quy trình.

1. Chuẩn bị môi trường R: Cài đặt và load các package cần thiết

Trước khi bắt đầu, chúng ta cần cài đặt một số package thường được sử dụng:

# Cài đặt (chỉ chạy một lần)
install.packages(c("pROC", "ROCR", "caret", "e1071", "ggplot2", "dplyr")) # Load các package
library(pROC) # Hàm roc(), auc(), plot.roc()
library(ROCR) # Đối tượng prediction, performance
library(caret) # Đánh giá mô hình, cross-validation
library(e1071) # SVM, Naive Bayes, v.v.
library(ggplot2) # Vẽ đồ thị tùy biến
library(dplyr) # Xử lý dữ liệu
  • pROC: Được phát triển bởi Xavier Robin, hỗ trợ tính AUC, vẽ ROC, và tính confidence intervals bằng bootstrap.
  • ROCR: Cung cấp một khung làm việc dạng “prediction → performance”. Thích hợp cho việc vẽ nhiều curve trên cùng một plot.
  • caret: Gói “Classification And REgression Training” giúp chuẩn hoá quy trình huấn luyện, kiểm tra, và tối ưu siêu tham số.
  • ggplot2: Để tạo các biểu đồ đẹp, tùy biến màu sắc, theme, và thêm annotation.

2. Bước 1: Chuẩn bị dữ liệu và phân chia train‑test

2.1. Ví dụ 1 – Dữ liệu Pima Indians Diabetes (có sẵn trong package mlbench)

install.packages("mlbench")
library(mlbench) data(PimaIndiansDiabetes2) # Dữ liệu có missing values
df <- na.omit(PimaIndiansDiabetes2) # Loại bỏ các dòng NA set.seed(123)
train_idx <- createDataPartition(df$diabetes, p = 0.7, list = FALSE)
train <- dftrain_idx, test <- df-train_idx, 

2.2. Ví dụ 2 – Dữ liệu German Credit (cũng có trong caret)

Cách Vẽ Auc Trong R
Cách Vẽ Auc Trong R
data(GermanCredit)
df2 <- GermanCredit set.seed(456)
train_idx2 <- createDataPartition(df2$Class, p = 0.7, list = FALSE)
train2 <- df2train_idx2, test2 <- df2-train_idx2, 

Lưu ý: Khi làm việc với dữ liệu mất cân bằng (ví dụ: tỷ lệ 1:10 giữa lớp dương và âm), chúng ta có thể cân bằng lại bằng oversampling (SMOTE) hoặc undersampling. Gói caret cung cấp hàm upSample() và downSample().

3. Bước 2: Huấn luyện mô hình và lấy dự đoán xác suất

Trong ví dụ này, chúng ta sẽ sử dụng Logistic Regression và Random Forest để so sánh.

3.1. Logistic Regression

# Logistic trên dữ liệu Pima
model_logi <- glm(diabetes ~ ., data = train, family = binomial) # Dự đoán xác suất trên tập test
prob_logi <- predict(model_logi, newdata = test, type = "response")

3.2. Random Forest (gói randomForest)

install.packages("randomForest")
library(randomForest) set.seed(789)
model_rf <- randomForest(diabetes ~ ., data = train, ntree = 500, importance = TRUE) # Dự đoán xác suất (class 1 = "pos")
prob_rf <- predict(model_rf, newdata = test, type = "prob"), "pos"

4. Bước 3: Tính AUC và vẽ ROC Curve bằng pROC

4.1. Tính AUC

Cách Vẽ Auc Trong R
Cách Vẽ Auc Trong R
# Logistic
roc_logi <- roc(response = test$diabetes, predictor = prob_logi, levels = c("neg", "pos"))
auc_logi <- auc(roc_logi)
print(paste("AUC Logistic:", round(auc_logi, 4))) # Random Forest
roc_rf <- roc(response = test$diabetes, predictor = prob_rf, levels = c("neg", "pos"))
auc_rf <- auc(roc_rf)
print(paste("AUC Random Forest:", round(auc_rf, 4)))

4.2. Vẽ ROC đơn lẻ

plot(roc_logi, col = "blue", lwd = 2, main = "ROC Curve - Logistic vs Random Forest", print.auc = TRUE, print.auc.y = 0.4) plot(roc_rf, col = "red", lwd = 2, add = TRUE)
legend("bottomright", legend = c("Logistic", "Random Forest"), col = c("blue", "red"), lwd = 2)

Kết quả sẽ cho ta một biểu đồ ROC với hai đường cong, mỗi đường có AUC hiển thị.

4.3. Thêm Confidence Interval (Bootstrap)

ci_logi <- ci.auc(roc_logi, boot.n = 2000, conf.level = 0.95)
ci_rf <- ci.auc(roc_rf, boot.n = 2000, conf.level = 0.95) print(ci_logi)
print(ci_rf)

Ta có thể hiển thị các khoảng tin cậy trên biểu đồ:

plot(roc_logi, col = "blue", lwd = 2, main = "ROC Curve with 95% CI", print.auc = TRUE) plot(ci_logi, type = "shape", col = "#0000FF40", add = TRUE) plot(roc_rf, col = "red", lwd = 2, add = TRUE)
plot(ci_rf, type = "shape", col = "#FF000040", add = TRUE) legend("bottomright", legend = c("Logistic", "RF"), col = c("blue", "red"), lwd = 2)

5. Bước 4: Vẽ ROC bằng ROCR – Khi cần vẽ nhiều mô hình cùng lúc

ROCR cho phép tạo đối tượng prediction rồi dùng performance để tính TPR, FPR, AUC, v.v.

# Đối tượng prediction
pred_logi <- prediction(prob_logi, test$diabetes)
pred_rf <- prediction(prob_rf, test$diabetes) # Performance: TPR vs FPR
perf_logi <- performance(pred_logi, "tpr", "fpr")
perf_rf <- performance(pred_rf, "tpr", "fpr") # Vẽ
plot(perf_logi, col = "darkgreen", lwd = 2, main = "ROC Curves via ROCR", xlab = "False Positive Rate", ylab = "True Positive Rate")
plot(perf_rf, col = "orange", lwd = 2, add = TRUE) # Thêm đường chéo ngẫu nhiên
abline(0, 1, lty = 2, col = "gray") # AUC
auc_logi_rocr <- performance(pred_logi, "auc")@y.values1
auc_rf_rocr <- performance(pred_rf, "auc")@y.values1 legend("bottomright", legend = c(paste0("Logistic AUC = ", round(auc_logi_rocr,4)), paste0("RF AUC = ", round(auc_rf_rocr,4))), col = c("darkgreen", "orange"), lwd = 2)

ROCR rất hữu ích khi bạn muốn vẽ các curve khác nhau (Precision‑Recall, Lift, Gain, …) chỉ bằng một thay đổi tham số.

6. Bước 5: So sánh nhiều mô hình trên cùng một plot – Gói ggplot2 + pROC

Nếu muốn một biểu đồ đẹp, có legend, theme, và lưu dưới dạng PNG/PDF, chúng ta có thể chuyển dữ liệu ROC sang data frame và dùng ggplot.

Cách Vẽ Auc Trong R
Cách Vẽ Auc Trong R
# Hàm chuyển ROC thành data frame
roc_to_df <- function(roc_obj, model_name){ data.frame( fpr = rev(roc_obj$specificities), # specificity = 1 - FPR tpr = rev(roc_obj$sensitivities), model = model_name )
} df_roc <- bind_rows( roc_to_df(roc_logi, "Logistic"), roc_to_df(roc_rf, "Random Forest")
) # Vẽ bằng ggplot
ggplot(df_roc, aes(x = fpr, y = tpr, colour = model)) + geom_line(size = 1.2) + geom_abline(slope = 1, intercept = 0, linetype = "dashed", colour = "gray50") + labs(title = "ROC Curve Comparison (ggplot2)", x = "False Positive Rate (1 - Specificity)", y = "True Positive Rate (Sensitivity)", colour = "Model") + theme_minimal(base_size = 14) + annotate("text", x = 0.6, y = 0.2, label = paste0("Logistic AUC = ", round(auc_logi,3), "\n", "RF AUC = ", round(auc_rf,3)), colour = "black", size = 5, hjust = 0)

Kết quả là một biểu đồ sạch, có legend, và có thể lưu:

ggsave("roc_comparison.png", width = 8, height = 6, dpi = 300)

7. Bước 6: Đánh giá mô hình bằng Cross‑Validation và Bootstrap AUC

7.1. Cross‑validation với caret

control <- trainControl(method = "cv", number = 5, classProbs = TRUE, summaryFunction = twoClassSummary, savePredictions = "final") set.seed(101)
model_cv_logi <- train(diabetes ~ ., data = train, method = "glm", family = binomial(), trControl = control, metric = "ROC") # tối ưu AUC print(model_cv_logi)

caret sẽ tự động tính AUC trung bình qua 5‑fold CV và trả về giá trị tốt nhất.

7.2. Bootstrap confidence interval cho AUC (pROC)

set.seed(202)
boot_auc <- roc(response = test$diabetes, predictor = prob_logi, boot.n = 2000, ci = TRUE, ci.alpha = 0.95, stratified = TRUE) print(boot_auc$ci) # 95% CI

Bootstrap giúp chúng ta hiểu độ ổn định của AUC, đặc biệt khi mẫu test không lớn.

8. Khi nào nên dùng Precision‑Recall Curve thay vì ROC?

ROC curve vẫn là tiêu chuẩn, nhưng đối với dữ liệu mất cân bằng (ví dụ: tỷ lệ dương chỉ 5% tổng mẫu), ROC có thể quá lạc quan vì FPR được tính trên số lượng âm lớn. Precision‑Recall (PR) lại tập trung vào Precision (Positive Predictive Value) và Recall (Sensitivity), phản ánh tốt hơn khả năng mô hình tìm ra các trường hợp dương thực sự.

8.1. Vẽ PR Curve bằng PRROC

Cách Vẽ Auc Trong R
Cách Vẽ Auc Trong R
install.packages("PRROC")
library(PRROC) pr_logi <- pr.curve(scores.class0 = prob_logitest$diabetes == "pos", scores.class1 = prob_logitest$diabetes == "neg", curve = TRUE) plot(pr_logi, main = "Precision‑Recall Curve - Logistic")

Bạn cũng có thể so sánh PR curve giữa các mô hình tương tự như ROC.

9. Thực hành: Đánh giá mô hình Credit Scoring trên dữ liệu German Credit

9.1. Chuẩn bị dữ liệu

dfc <- GermanCredit %>% mutate(Class = ifelse(Class == "Good", 0, 1)) # 1 = Bad credit set.seed(321)
train_idxc <- createDataPartition(dfc$Class, p = 0.7, list = FALSE)
trainc <- dfctrain_idxc, testc <- dfc-train_idxc, 

9.2. Mô hình Gradient Boosting (xgboost)

install.packages("xgboost")
library(xgboost) # Chuyển dữ liệu sang ma trận số
train_matrix <- model.matrix(Class ~ . -1, data = trainc)
test_matrix <- model.matrix(Class ~ . -1, data = testc) dtrain <- xgb.DMatrix(data = train_matrix, label = trainc$Class)
dtest <- xgb.DMatrix(data = test_matrix, label = testc$Class) params <- list( objective = "binary:logistic", eval_metric = "auc", max_depth = 4, eta = 0.1, subsample = 0.8, colsample_bytree = 0.8
) set.seed(777)
xgb_model <- xgb.train(params = params, data = dtrain, nrounds = 150, watchlist = list(train = dtrain), verbose = 0) prob_xgb <- predict(xgb_model, dtest)

9.3. ROC và AUC

roc_xgb <- roc(response = testc$Class, predictor = prob_xgb)
auc_xgb <- auc(roc_xgb)
print(paste("AUC XGBoost:", round(auc_xgb,4)))
plot(roc_xgb, col = "purple", lwd = 2, main = "ROC Curve – German Credit (XGBoost)", print.auc = TRUE)

Kết quả thường cho AUC khoảng 0.76‑0.80, là mức tốt cho bài toán credit scoring.

10. Tổng hợp các lưu ý quan trọng khi vẽ AUC trong R

Yếu tố Mô tả Lời khuyên
Chọn package pROC, ROCR, PRROC, caret Dùng pROC cho AUC chuẩn, ROCR cho đa dạng metric, PRROC cho dữ liệu mất cân bằng
Dữ liệu cân bằng Tỷ lệ lớp dương/âm Cân bằng lại (SMOTE, up/down sampling) hoặc dùng PR curve
Xác suất vs nhãn AUC yêu cầu dự đoán dưới dạng xác suất (hoặc decision value) Đừng dùng nhãn cắt cố định; luôn truyền type = "response" (logistic) hoặc type = "prob" (RF)
Cross‑validation Đánh giá mô hình không phụ thuộc vào một split caret::train(..., method = "cv") hoặc rsample
Bootstrap CI Đánh giá độ tin cậy của AUC ci.auc() trong pROC, số vòng bootstrap ≥ 2000 để ổn định
Nhiều mô hình So sánh ROC của các mô hình Gộp các đối tượng roc thành data frame và dùng ggplot2
Biểu đồ đẹp Thêm legend, annotation, theme ggplot2 + geom_line, annotate, theme_minimal
Precision‑Recall Khi dữ liệu mất cân bằng PRROC::pr.curve hoặc precrec

11. Các lỗi thường gặp và cách khắc phục

Cách Vẽ Auc Trong R
Cách Vẽ Auc Trong R
  1. Lỗi “Error in roc.default: response must be binary”
  2. Kiểm tra biến response có đúng là factor với 2 mức (ví dụ: levels = c("neg","pos")).
  3. Nếu biến là số (0/1), chuyển thành factor: test$diabetes <- factor(test$diabetes, levels = c(0,1), labels = c("neg","pos")).

  4. AUC > 1 hoặc < 0

  5. Thường do nhầm lẫn giữa predictor và response hoặc đưa vào roc() một vector xác suất đã được đảo ngược (số lớn là class âm). Kiểm tra levels và direction = "auto".

  6. Không có Confidence Interval khi dùng ci.auc

  7. Cần bật boot.n hoặc ci = TRUE và chắc chắn rằng roc đã được tính (không phải roc.curve).

  8. ROC curve không hiển thị đầy đủ

  9. Khi dùng add = TRUE trong plot.roc, cần chắc chắn rằng trục và giới hạn (xlim, ylim) đủ rộng. Có thể dùng plot.roc(..., xlim = c(0,1), ylim = c(0,1)).

  10. Cảnh báo “Number of non‑NA cases is less than 5”

  11. Do dữ liệu test quá ít hoặc có quá nhiều missing. Kiểm tra lại na.omit và cân nhắc tăng kích thước mẫu.

12. Kết luận

Việc vẽ AUC trong R không chỉ là một bước kiểm tra mà còn là một công cụ mạnh mẽ để so sánh, tối ưu và truyền đạt hiệu suất mô hình dự báo. Nhờ vào các package như pROC, ROCR, caret và ggplot2, chúng ta có thể:

  • Tính toán AUC một cách chuẩn xác, kèm confidence interval.
  • Vẽ ROC curve đẹp mắt, tùy biến màu sắc, line type, và annotation.
  • So sánh nhiều mô hình trên cùng một biểu đồ, giúp quyết định mô hình nào phù hợp hơn cho dự án.
  • Áp dụng các kỹ thuật nâng cao như cross‑validation, bootstrap, và Precision‑Recall curve cho dữ liệu mất cân bằng.

Bằng cách thực hiện các bước từ chuẩn bị dữ liệu, huấn luyện mô hình, dự đoán xác suất, tính AUC, tới vẽ và tùy biến đồ thị, bạn sẽ có một quy trình hoàn chỉnh, dễ tái sử dụng và có thể mở rộng cho bất kỳ bài toán phân loại nào. Hãy áp dụng những kiến thức này vào dự án thực tế của bạn và nâng cao độ tin cậy của các mô hình dự báo!

Tài liệu tham khảo

  1. Robin, X., Turck, N., Hainard, A., et al. (2026). pROC: an open-source package for R and S+ to analyze and compare ROC curves. BMC Bioinformatics.
  2. Sing, T., Sander, O., Beerenwinkel, N., & Lengauer, T. (2005). ROCR: visualizing classifier performance in R. Bioinformatics.
  3. Kuhn, M. (2026). caret: Classification and Regression Training. R package version 6.0‑90.
  4. Chen, T., & Guestrin, C. (2026). XGBoost: A scalable tree boosting system. Proceedings of the 22nd ACM SIGKDD.

Chúc bạn thành công trong việc vẽ AUC và nâng cao hiệu suất mô hình trong R!

Rate this post
Mục nhập này đã được đăng trong Blog. Đánh dấu trang permalink.

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *