Різні результати від randomForest за допомогою карети та базового пакету randomForest


14

Я трохи розгублений: як результати тренованої моделі за допомогою карети можуть відрізнятися від моделі в оригінальній упаковці? Читаю, чи потрібна попередня обробка перед прогнозуванням за допомогою FinalModel of RandomForest з пакетом caret?але я тут не використовую жодної попередньої обробки.

Я навчав різні випадкові ліси, використовуючи пакет карет і налаштовуючи різні значення.

> 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

Я знайшов mtry = 15 найкращим параметром у навчальних_даних:

> 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. 

Я оцінив модель за допомогою кривої ROC та матриці плутанини:

##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")

Отримана матриця плутанини та точність:

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

           Accuracy : 0.8984
 ....

Тепер я тренував Random Rorest з тими ж параметрами і тими ж навчальними даними, використовуючи базовий пакет randomForest:

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

Знову я створив передбачення для тих самих test_data, як вище, і оцінив матрицю плутанини з тим же кодом, що і вище. Але зараз у мене були різні заходи:

Confusion Matrix and Statistics

      Reference
Prediction   No  Yes
       No  2702  897
       Yes  430 6480

           Accuracy : 0.8737 
           ....

В чому причина? Що я пропускаю?


3
Чи використовували ви однакове значення для випадкового насіння для обох моделей?
мммммммммм

Я думаю так. Я встановив насіння раніше в коді, коли розбивав набір даних на дані навчання і тестування, потім тренував модель карети, потім тренував "оригінальну" модель rf. Тож насіння має залишатися таким же, як тільки встановлено на початку, чи не так?
Мальте

Я намагався вставити ще один set.seed безпосередньо перед тренуванням "оригінальної" rf-моделі. На жаль, це не вирішує проблему.
Мальте

3
Ви повинні перевірити це, використовуючи seedsаргументtrainControl
topepo

Відповіді:


4

Я думаю, що питання, хоча дещо тривіальне та «програмне» на першому читанні, стосується двох основних питань, які є дуже важливими в сучасній статистиці:

  1. відтворюваність результатів та
  2. недетерміновані алгоритми.

Причиною різних результатів є те, що дві процедури тренуються, використовуючи різні випадкові насіння. Випадкові ліси використовують випадкові підмножини зі змінних повного набору даних як кандидати при кожному розбитті (це mtryаргумент і стосується методу випадкового підпростору ), а також мішки (агрегати завантажувальної машини) для початкового набору даних, щоб зменшити дисперсію моделі. Ці дві внутрішні випадкові процедури вибірки вважаються не детермінованими між різними прогонами алгоритму. Випадковий порядок здійснення вибірки контролюється випадковим використанням насіння. Якби використовували одне і те ж насіння, можна було б отримати однакові результати в обох випадках, коли randomForestназивається рутина; як внутрішньо в Росіїcaret::trainа також зовні при встановленні випадкового лісу вручну. Я додаю простий фрагмент коду, щоб показати це. Зверніть увагу, що я використовую дуже малу кількість дерев (аргумент:), ntreeщоб продовжувати тренуватись швидко, це, як правило, значно більше.

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) 

На даний момент як caret.trainоб'єкт, fitRFcaretтак і визначений вручну randomForestоб’єкт fitRFmanualпройшли навчання з використанням одних і тих же даних, але важливо, використовуючи ті самі випадкові насіння під час встановлення їх остаточної моделі. Таким чином, коли ми спробуємо передбачити використання цих об'єктів і оскільки ми не проводимо попередньої обробки наших даних, ми отримаємо однакові точні відповіді.

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

Просто для уточнення цього пізніше вкажіть трохи далі: predict(xx$finalModel, testData)і predict(xx, testData)буде іншим, якщо встановити preProcessваріант при використанні train. З іншого боку, при finalModelпрямому використанні він еквівалентний з використанням predictфункції з встановленої моделі ( predict.randomForestтут) замість predict.train; попереднього відбору не відбувається. Очевидно, що в сценарії, викладеному в первісному запитанні, коли не проводиться попередня обробка, результати будуть однаковими при використанні об'єкта, finalModelвстановленого вручну randomForestабо caret.trainоб'єкта.

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

Я настійно пропоную вам завжди встановлювати випадкові насіння, використовувані R, MATLAB або будь-якою іншою програмою. В іншому випадку ви не можете перевірити відтворюваність результатів (що гаразд, це може бути не кінець світу), а також не виключити помилку чи зовнішній фактор, що впливає на ефективність процедури моделювання (що так, це начебто смокче). Багато провідних алгоритмів МЛ (наприклад, збільшення градієнтів, випадкові ліси, екстремальні нейронні мережі) використовують певні внутрішні процедури перестановки під час фаз навчання, встановлюючи випадкові стани насіння до (а іноді навіть у межах) фази їх навчання.


Важливою частиною було встановлення аргументу насіння явно у "trainControl", використовуючи аргумент "насіння"
Malte

Так, звісно. Я хотів переконатися, що питання, чому це потрібно, було повністю прояснено.
usεr11852 повідомляє Відновити Монік

Як я бігаю train так, щоб це було рівнозначно randomForest? Я спробував, method="none"але не впевнений, як встановити насіння на єдине значення. Спасибі.
Саймон Вудвард

Вибачте, але незрозуміло, чи є у вас якісь справи, preProcessабо як ви randomForestнавчаєтесь для початку. Загалом, припускаючи, що у нас немає етапів попередньої обробки, нам потрібно гарантувати, що і насінні, і використовувані гіперпараметри (тут тільки mtry) однакові.
usεr11852 повідомляє

0

Прогнози з боку curClassifierне збігаються з прогнозами за curClassifier$finalModel посиланням . Ви відтворили finalModelі порівнюєте його з predict.trainоб'єктом.


1
Хоча те, що ви говорите, є істинним, але, на жаль, трохи не введено в оману в нинішніх умовах, оскільки ОП не проводить попередньої обробки. Обидва predictповинні (і насправді) дають однакові прогнози у випадку, коли досліджується ОП. Я уточнюю це питання трохи більше у своєму дописі.
usεr11852 каже Відновити Моніку
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.