Rừng ngẫu nhiên hầu như không phải là một hộp đen. Chúng dựa trên các cây quyết định, rất dễ diễn giải:
#Setup a binary classification problem
require(randomForest)
data(iris)
set.seed(1)
dat <- iris
dat$Species <- factor(ifelse(dat$Species=='virginica','virginica','other'))
trainrows <- runif(nrow(dat)) > 0.3
train <- dat[trainrows,]
test <- dat[!trainrows,]
#Build a decision tree
require(rpart)
model.rpart <- rpart(Species~., train)
Điều này dẫn đến một cây quyết định đơn giản:
> model.rpart
n= 111
node), split, n, loss, yval, (yprob)
* denotes terminal node
1) root 111 35 other (0.68468468 0.31531532)
2) Petal.Length< 4.95 77 3 other (0.96103896 0.03896104) *
3) Petal.Length>=4.95 34 2 virginica (0.05882353 0.94117647) *
Nếu Petal.Lipse <4.95, cây này phân loại quan sát là "khác". Nếu nó lớn hơn 4,95, nó phân loại quan sát là "virginica". Một khu rừng ngẫu nhiên là một tập hợp nhiều cây như vậy, trong đó mỗi cây được huấn luyện trên một tập hợp con ngẫu nhiên của dữ liệu. Mỗi cây sau đó "bỏ phiếu" cho phân loại cuối cùng của mỗi quan sát.
model.rf <- randomForest(Species~., train, ntree=25, proximity=TRUE, importance=TRUE, nodesize=5)
> getTree(model.rf, k=1, labelVar=TRUE)
left daughter right daughter split var split point status prediction
1 2 3 Petal.Width 1.70 1 <NA>
2 4 5 Petal.Length 4.95 1 <NA>
3 6 7 Petal.Length 4.95 1 <NA>
4 0 0 <NA> 0.00 -1 other
5 0 0 <NA> 0.00 -1 virginica
6 0 0 <NA> 0.00 -1 other
7 0 0 <NA> 0.00 -1 virginica
Bạn thậm chí có thể kéo từng cây riêng lẻ ra khỏi rf và xem cấu trúc của chúng. Định dạng hơi khác so với rpart
mô hình, nhưng bạn có thể kiểm tra từng cây nếu bạn muốn và xem cách mô hình hóa dữ liệu.
Hơn nữa, không có mô hình nào thực sự là một hộp đen, bởi vì bạn có thể kiểm tra các phản hồi dự đoán so với phản hồi thực tế cho từng biến trong bộ dữ liệu. Đây là một ý tưởng tốt cho dù bạn đang xây dựng mô hình nào:
library(ggplot2)
pSpecies <- predict(model.rf,test,'vote')[,2]
plotData <- lapply(names(test[,1:4]), function(x){
out <- data.frame(
var = x,
type = c(rep('Actual',nrow(test)),rep('Predicted',nrow(test))),
value = c(test[,x],test[,x]),
species = c(as.numeric(test$Species)-1,pSpecies)
)
out$value <- out$value-min(out$value) #Normalize to [0,1]
out$value <- out$value/max(out$value)
out
})
plotData <- do.call(rbind,plotData)
qplot(value, species, data=plotData, facets = type ~ var, geom='smooth', span = 0.5)
Tôi đã bình thường hóa các biến số (chiều dài và chiều rộng cánh hoa và cánh hoa) thành phạm vi 0-1. Phản hồi cũng là 0-1, trong đó 0 là khác và 1 là virginica. Như bạn có thể thấy rừng ngẫu nhiên là một mô hình tốt, ngay cả trên bộ thử nghiệm.
Ngoài ra, một khu rừng ngẫu nhiên sẽ tính toán các mức độ quan trọng khác nhau, có thể rất nhiều thông tin:
> importance(model.rf, type=1)
MeanDecreaseAccuracy
Sepal.Length 0.28567162
Sepal.Width -0.08584199
Petal.Length 0.64705819
Petal.Width 0.58176828
Bảng này biểu thị mức độ loại bỏ từng biến làm giảm độ chính xác của mô hình. Cuối cùng, có nhiều mảnh đất khác bạn có thể thực hiện từ một mô hình rừng ngẫu nhiên, để xem những gì đang diễn ra trong hộp đen:
plot(model.rf)
plot(margin(model.rf))
MDSplot(model.rf, iris$Species, k=5)
plot(outlier(model.rf), type="h", col=c("red", "green", "blue")[as.numeric(dat$Species)])
Bạn có thể xem các tệp trợ giúp cho từng chức năng này để hiểu rõ hơn về những gì chúng hiển thị.