Kết quả khác nhau từ RandomForest qua caret và gói RandomForest cơ bản


14

Tôi hơi bối rối: Làm thế nào các kết quả của một Mô hình được đào tạo thông qua caret khác với mô hình trong gói ban đầu? Tôi đọc Có cần tiền xử lý trước khi dự đoán bằng FinalModel của RandomForest với gói caret không? nhưng tôi không sử dụng bất kỳ tiền xử lý nào ở đây.

Tôi đã huấn luyện các Rừng ngẫu nhiên khác nhau bằng cách sử dụng gói caret và điều chỉnh cho các giá trị mtry khác nhau.

> cvCtrl = trainControl(method = "repeatedcv",number = 10, repeats = 3, classProbs = TRUE, summaryFunction = twoClassSummary)
> newGrid = expand.grid(mtry = c(2,4,8,15))
> classifierRandomForest = train(case_success ~ ., data = train_data, trControl = cvCtrl, method = "rf", metric="ROC", tuneGrid = newGrid)
> curClassifier = classifierRandomForest

Tôi thấy mtry = 15 là tham số tốt nhất trên training_data:

> curClassifier
 ...
Resampling results across tuning parameters:

mtry  ROC    Sens   Spec   ROC SD   Sens SD  Spec SD
 4    0.950  0.768  0.957  0.00413  0.0170   0.00285
 5    0.951  0.778  0.957  0.00364  0.0148   0.00306
 8    0.953  0.792  0.956  0.00395  0.0152   0.00389
10    0.954  0.797  0.955  0.00384  0.0146   0.00369
15    0.956  0.803  0.951  0.00369  0.0155   0.00472

ROC was used to select the optimal model using  the largest value.
The final value used for the model was mtry = 15. 

Tôi đã đánh giá mô hình với Đường cong ROC và ma trận nhầm lẫn:

##ROC-Curve
predRoc = predict(curClassifier, test_data, type = "prob")
myroc = pROC::roc(test_data$case_success, as.vector(predRoc[,2]))
plot(myroc, print.thres = "best")

##adjust optimal cut-off threshold for class probabilities
threshold = coords(myroc,x="best",best.method = "closest.topleft")[[1]] #get optimal cutoff threshold
predCut = factor( ifelse(predRoc[, "Yes"] > threshold, "Yes", "No") )


##Confusion Matrix (Accuracy, Spec, Sens etc.)
curConfusionMatrix = confusionMatrix(predCut, test_data$case_success, positive = "Yes")

Ma trận nhầm lẫn kết quả và độ chính xác:

Confusion Matrix and Statistics
      Reference
Prediction   No  Yes
   No  2757  693
   Yes  375 6684

           Accuracy : 0.8984
 ....

Bây giờ tôi đã đào tạo một Rorest ngẫu nhiên với cùng các tham số và cùng training_data bằng cách sử dụng gói RandomForest cơ bản:

randomForestManual <- randomForest(case_success ~ ., data=train_data, mtry = 15, ntree=500,keep.forest=TRUE)
curClassifier = randomForestManual

Một lần nữa tôi đã tạo dự đoán cho test_data giống như trên và đánh giá ma trận nhầm lẫn với cùng mã như trên. Nhưng bây giờ tôi có các biện pháp khác nhau:

Confusion Matrix and Statistics

      Reference
Prediction   No  Yes
       No  2702  897
       Yes  430 6480

           Accuracy : 0.8737 
           ....

Lý do là gì? Tôi đang thiếu gì?


3
Bạn đã sử dụng cùng một giá trị cho hạt giống ngẫu nhiên cho cả hai mô hình?
mmmmmmmmmm

Tôi nghĩ vậy. Tôi đặt hạt giống sớm hơn trong mã khi tách tập dữ liệu thành dữ liệu huấn luyện và kiểm tra, sau đó huấn luyện mô hình caret, sau đó huấn luyện mô hình rf "gốc". Vì vậy, hạt giống nên giữ nguyên một lần khi bắt đầu, không nên?
Malte

Tôi đã cố gắng chèn một set.seed khác trực tiếp trước khi đào tạo mô hình rf "gốc". Thật không may, không giải quyết vấn đề.
Malte

3
Bạn nên kiểm tra điều này bằng cách sử dụng seedsđối số củatrainControl
topepo 15/03/2015

Câu trả lời:


4

Tôi nghĩ rằng câu hỏi trong khi hơi tầm thường và "lập trình" lúc đầu đọc chạm đến hai vấn đề chính rất quan trọng trong Thống kê hiện đại:

  1. độ tái lập của kết quả và
  2. thuật toán không xác định.

Lý do cho các kết quả khác nhau là hai quy trình được đào tạo sử dụng các hạt ngẫu nhiên khác nhau. Các khu rừng ngẫu nhiên sử dụng một tập hợp con ngẫu nhiên từ các biến của bộ dữ liệu đầy đủ làm các ứng cử viên cho mỗi lần phân tách (đó là mtryđối số và liên quan đến phương thức không gian con ngẫu nhiên ) cũng như các túi (tập hợp bootstrap) bộ dữ liệu ban đầu để giảm phương sai của mô hình. Hai quy trình lấy mẫu ngẫu nhiên nội bộ này được cho là không xác định giữa các lần chạy khác nhau của thuật toán. Thứ tự ngẫu nhiên mà việc lấy mẫu được thực hiện được kiểm soát bởi các hạt ngẫu nhiên được sử dụng. Nếu cùng một hạt giống được sử dụng, người ta sẽ nhận được kết quả chính xác như nhau trong cả hai trường hợp trong đó randomForestthói quen được gọi; cả nội bộ trongcaret::traincũng như bên ngoài khi lắp một khu rừng ngẫu nhiên bằng tay. Tôi đính kèm một đoạn mã đơn giản để hiển thị trường hợp này. Xin lưu ý rằng tôi sử dụng một số lượng cây rất nhỏ (đối số ntree:) để tiếp tục luyện tập nhanh, nó thường lớn hơn nhiều.

library(caret)

set.seed(321)
trainData <- twoClassSim(5000, linearVars = 3, noiseVars = 9)
testData  <- twoClassSim(5000, linearVars = 3, noiseVars = 9)

set.seed(432)
mySeeds <- sapply(simplify = FALSE, 1:26, function(u) sample(10^4, 3))
cvCtrl = trainControl(method = "repeatedcv", number = 5, repeats = 5, 
                      classProbs = TRUE, summaryFunction = twoClassSummary, 
                      seeds = mySeeds)

fitRFcaret = train(Class ~ ., data = trainData, trControl = cvCtrl, 
                   ntree = 33, method = "rf", metric="ROC")

set.seed( unlist(tail(mySeeds,1))[1])
fitRFmanual <- randomForest(Class ~ ., data=trainData, 
                            mtry = fitRFcaret$bestTune$mtry, ntree=33) 

Tại thời điểm này, cả caret.trainđối tượng fitRFcaretcũng như randomForestđối tượng được xác định thủ công fitRFmanualđã được đào tạo sử dụng cùng một dữ liệu nhưng quan trọng là sử dụng cùng một hạt giống ngẫu nhiên khi lắp mô hình cuối cùng của chúng. Như vậy khi chúng tôi sẽ cố gắng dự đoán bằng cách sử dụng các đối tượng này và vì chúng tôi không xử lý trước dữ liệu của mình, chúng tôi sẽ nhận được cùng một câu trả lời chính xác.

all.equal(current =  as.vector(predict(fitRFcaret, testData)), 
          target = as.vector(predict(fitRFmanual, testData)))
# TRUE

Chỉ cần làm rõ điều này sau một chút nữa: predict(xx$finalModel, testData)predict(xx, testData)sẽ khác nếu người ta đặt preProcesstùy chọn khi sử dụng train. Mặt khác, khi sử dụng finalModeltrực tiếp, nó tương đương với việc sử dụng predictchức năng từ mô hình được trang bị ( predict.randomForestở đây) thay vì predict.train; không có dự đoán trước diễn ra. Rõ ràng trong kịch bản được nêu trong câu hỏi ban đầu khi không xử lý trước được thực hiện, kết quả sẽ giống nhau khi sử dụng finalModel, randomForestđối tượng được gắn thủ công hoặc caret.trainđối tượng.

all.equal(current =  as.vector(predict(fitRFcaret$finalModel, testData)), 
          target = as.vector(predict(fitRFmanual, testData)))
 # TRUE

all.equal(current =  as.vector(predict(fitRFcaret$finalModel, testData)),
          target = as.vector(predict(fitRFcaret, testData)))
# TRUE

Tôi thực sự khuyên bạn nên luôn luôn đặt hạt giống ngẫu nhiên được sử dụng bởi R, MATLAB hoặc bất kỳ chương trình nào khác được sử dụng. Mặt khác, bạn không thể kiểm tra độ tái lập của các kết quả (mà OK, nó có thể không phải là kết thúc của thế giới) cũng như không loại trừ một lỗi hoặc yếu tố bên ngoài ảnh hưởng đến hiệu suất của một quy trình mô hình hóa (vâng, đó là loại hút). Rất nhiều thuật toán ML hàng đầu (ví dụ: tăng cường độ dốc, rừng ngẫu nhiên, mạng lưới thần kinh cực đoan) sử dụng các quy trình lấy mẫu nội bộ nhất định trong các giai đoạn đào tạo của chúng, đặt trạng thái hạt giống ngẫu nhiên trước (hoặc đôi khi ngay cả trong giai đoạn đào tạo của chúng có thể rất quan trọng.


Phần quan trọng là thiết lập đối số hạt rõ ràng trong "trainControl" bằng cách sử dụng đối số "hạt giống"
Malte

Phải, tất nhiên. Tôi muốn chắc chắn rằng vấn đề là tại sao điều này lại cần thiết, đã được làm rõ hoàn toàn.
usεr11852 nói Phục hồi Monic

Làm thế nào để tôi chạy trainđể nó chính xác tương đương randomForest? Tôi đã thử method="none"nhưng không chắc chắn làm thế nào để đặt hạt giống thành giá trị duy nhất. Cảm ơn.
Simon Woodward

Xin lỗi nhưng không rõ nếu bạn có bất kỳ preProcesshoặc làm thế nào randomForestđược đào tạo để bắt đầu. Nói chung, giả sử chúng tôi không có các bước xử lý trước, chúng tôi cần đảm bảo rằng cả hạt giống siêu đường kính (ở đây chỉ mtry) được sử dụng là như nhau.
usεr11852 nói Phục hồi Monic

0

Dự đoán từ curClassifierkhông giống như dự đoán từ curClassifier$finalModel liên kết . Bạn đã sao chép finalModelvà đang so sánh nó với predict.trainđối tượng.


1
Mặc dù những gì bạn nói là đúng, nhưng thật không may là một chút sai lệch trong cài đặt hiện tại vì OP không xử lý trước được thực hiện. Cả hai predictnên (và thực sự) đưa ra dự đoán giống nhau trong trường hợp OP khám phá. Tôi làm rõ điểm này hơn một chút trong bài viết của tôi.
usεr11852 nói Phục hồi Monic
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.