Giới thiệu

Chắc các bạn đều biết về 2 package rất phổ biến hiện nay cho Machine learning trong R đó là caret và mlr. Cú pháp của cả 2 đều đã được Bs. Lê Ngọc Khả Nhi giới thiệu rất chi tiết trong năm 2016. Tuy nhiên đối với người biết sử dụng cả 2 packagse, sẽ nhanh chóng nhận ra ưu điểm và nhược điểm của mỗi bên.

Trong khi caret cung cấp một quy trình tích hợp Tuning, Training và Resample cùng lúc, thì mlr phân biệt ra 3 quy trình riêng biệt và có cú pháp phức tạp hơn caret nhiều. Do đó nhiều bạn chắc chắn sẽ ưa chuộng dùng caret hơn mlr, và thực ra đa số trường hợp, hàm train( ) của caret sẽ cho ra kết quả chính xác hơn so với hàm train của mlr cho 1 learner không tinh chỉnh.

Tuy nhiên, nhược điểm của caret đó là 1 quy trình kiểm định (validation) rất nghèo nàn so với mlr. Trong khi mlr cung cấp hơn 30 tiêu chí khác nhau để kiểm định 1 classification model, thì caret chỉ cung cấp 1 confusion matrix với 12 tiêu chí mà thôi. Ước gì ta có thể dùng mlr để kiểm định 1 mô hình dựng bằng caret thì hay biết mấy phải không các bạn ?

Điều này mới nghe có vẻ bất khả thi, vì hàm performance( ) trong mlr chỉ nhận diện object output thuộc lớp predict mlr. Tuy nhiên, sau khi phân tích cấu trúc bên trong object predict mlr, ta sẽ nhận ra rằng thực chất những thông tin chủ chốt đều chứa trong 1 dataframe ; đây là 1 điều rất tốt, vì ta có thể hoán chuyển dữ liệu của dataframe này bằng dữ liệu predict từ mô hình caret. Lúc này ta có thể dùng mlr để kiểm định mô hình của caret (và mở rộng ra, là cho bất cứ mô hình nào có kết quả predict là probability và classes.

Tutorial sau đây sẽ hướng dẫn các bạn chiêu thức vừa nêu trên :

Ta sẽ dùng caret để dựng một mô hình cây kiểu CART trên dataset Biopsy : Dataset biopsy bao gồm :

Class là biến kết quả: phân loại khối u vú: lành tính hay ác tính V1 tới V9 là thang điểm tế bào học trên mẫu sinh thiết theo 9 tiêu chí, đều là biến kiểu số, thứ hạng

Mục tiêu của chúng ta là xây dựng một mô hình CART cho phép phân loại khối u vú dựa vào giá trị của một hay nhiều tiêu chí tế bào học (Chắc bạn còn nhớ đây là bài tutorial đầu tiên mà Bs. Nhi đã trình bày năm 2016)

#Tải dataset

data=read.csv("http://vincentarelbundock.github.io/Rdatasets/csv/MASS/biopsy.csv")%>%as_tibble()%>%.[,c(3:12)]

data=na.omit(data)

#Chia subset

set.seed(123)
idTrain=caret::createDataPartition(y=data$class, p=0.8,list=FALSE)

trainset=data[idTrain,]
testset=data[-idTrain,]
set.seed(333)
CART<-caret::train(class~.,
                  data=trainset,
                  method="rpart",
                  preProcess = NULL,
                  tuneLength=5,
                  trControl = caret::trainControl(method = "repeatedcv", number=10,repeats=10,verboseIter = FALSE,summaryFunction=caret::multiClassSummary)
)

Caret chỉ có thể kiểm định mô hình đến mức này mà thôi :

predcart<-testset%>%mutate(.,Predicted=predict(CART,.))

confusionMatrix(predcart$Predicted, reference=predcart$class,positive ="malignant",mode="everything")
## Confusion Matrix and Statistics
## 
##            Reference
## Prediction  benign malignant
##   benign        87         5
##   malignant      1        42
##                                           
##                Accuracy : 0.9556          
##                  95% CI : (0.9058, 0.9835)
##     No Information Rate : 0.6519          
##     P-Value [Acc > NIR] : <2e-16          
##                                           
##                   Kappa : 0.9001          
##  Mcnemar's Test P-Value : 0.2207          
##                                           
##             Sensitivity : 0.8936          
##             Specificity : 0.9886          
##          Pos Pred Value : 0.9767          
##          Neg Pred Value : 0.9457          
##               Precision : 0.9767          
##                  Recall : 0.8936          
##                      F1 : 0.9333          
##              Prevalence : 0.3481          
##          Detection Rate : 0.3111          
##    Detection Prevalence : 0.3185          
##       Balanced Accuracy : 0.9411          
##                                           
##        'Positive' Class : malignant       
## 

Bây giờ ta sẽ dùng mlr để dựng 1 mô hình CART khác trên cùng dataset, lưu ý là 2 mô hình mlr và caret sẽ khác nhau, vì mô hình mlr chưa qua tinh chỉnh, kết quả của nó chắc chắn sẽ tệ hơn nhiều so với caret.

library(mlr)

tasktrain=mlr::makeClassifTask(data=trainset,target="class",positive = "malignant")
tasktest=mlr::makeClassifTask(data=testset,target="class",positive = "malignant")

learnerCART = makeLearner("classif.rpart", predict.type = "prob")

mlrCART=mlr::train(learnerCART,tasktrain)

Thực ra ta không quan tâm đến điều này, ta chỉ cần object mlr để xuất ra kết quả dự báo, thứ mà ta sẽ thay thế phần lõi bằng kết quả predict của caret

mets=list(auc,bac,f1,tpr,tnr,mmce,brier,ber,fpr,fnr)

predmlr=predict(mlrCART,tasktest)

#Kết quả dự báo thuộc lớp mlr nằm ở trong object predmlr, và là 1 dataframe

head(predmlr$data)
##   id     truth prob.benign prob.malignant response
## 1  1    benign   0.9823009     0.01769912   benign
## 2  2    benign   0.9823009     0.01769912   benign
## 3  3    benign   0.9823009     0.01769912   benign
## 4  4    benign   0.9823009     0.01769912   benign
## 5  5 malignant   1.0000000     0.00000000   benign
## 6  6    benign   0.9823009     0.01769912   benign
newpredmlr=predmlr

#Ta sẽ gán kết quả dự báo thuộc lớp caret vào datframe này

caretprob=predict(CART,testset,type="prob")
caretclass=predict(CART,testset,type="raw")

newpredmlr$data<-predmlr$data%>%mutate(prob.benign=caretprob$benign,prob.malignant=caretprob$malignant,response=caretclass)

head(newpredmlr$data)
##   id     truth prob.benign prob.malignant response
## 1  1    benign    1.000000     0.00000000   benign
## 2  2    benign    0.952381     0.04761905   benign
## 3  3    benign    1.000000     0.00000000   benign
## 4  4    benign    1.000000     0.00000000   benign
## 5  5 malignant    1.000000     0.00000000   benign
## 6  6    benign    1.000000     0.00000000   benign

Bây giờ mlr có thể kiểm định mô hình caret rồi :

performance(newpredmlr,mets)
##        auc        bac         f1        tpr        tnr       mmce 
## 0.96506286 0.94112669 0.93333333 0.89361702 0.98863636 0.04444444 
##      brier        ber        fpr        fnr 
## 0.04448073 0.05887331 0.01136364 0.10638298

Các bạn sẽ thấy là kết quả này chính xác và phù hợp với Confusion matrix của caret.

Tạm biệt các bạn và hẹn gặp lại