Я немного растерялся: чем могут отличаться результаты обученной модели с помощью каретки от модели в оригинальной упаковке? Я прочитал , нужна ли предварительная обработка перед прогнозированием с использованием FinalModel из RandomForest с пакетом Caret? но я не использую никакой предварительной обработки здесь.
Я тренировал разные случайные леса, используя набор карет и настраивая их для разных значений mtry.
> 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 - лучший параметр для 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.
Я оценил модель с помощью кривой 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 с теми же параметрами и теми же данными training_data, используя базовый пакет 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
....
Какова причина? Что мне не хватает?
seeds
аргументtrainControl
Ответы:
Я думаю, что этот вопрос, хотя и несколько тривиальный и «программный», на первый взгляд, затрагивает две основные проблемы, которые очень важны в современной статистике:
Причина для разных результатов состоит в том, что две процедуры обучаются с использованием разных случайных семян. В случайных лесах используется случайное подмножество из переменных полного набора данных в качестве кандидатов при каждом разбиении (это
mtry
аргумент и относится к методу случайного подпространства ), а также пакеты (начальные загрузки) исходного набора данных для уменьшения дисперсии модели. Эти две процедуры внутренней случайной выборки считаются недетерминированными между различными прогонами алгоритма. Случайный порядок, в котором производится выборка, контролируется используемыми случайными семенами. Если бы использовались одни и те же семена, можно было бы получить одинаковые результаты в обоих случаях, когдаrandomForest
вызывается процедура; как внутриcaret::train
а также внешне при подгонке случайного леса вручную. Я прилагаю простой фрагмент кода, чтобы продемонстрировать это. Обратите внимание, что я использую очень небольшое количество деревьев (аргумент:)ntree
для быстрой тренировки, обычно оно должно быть намного больше.На этом этапе и
caret.train
объект,fitRFcaret
иrandomForest
объект, определенный вручнуюfitRFmanual
, были обучены с использованием одних и тех же данных, но, что важно, с использованием одинаковых случайных начальных чисел при подборе их окончательной модели. Таким образом, когда мы попытаемся предсказать использование этих объектов, и поскольку мы не выполняем предварительную обработку наших данных, мы получим те же точные ответы.Просто, чтобы прояснить это позже, немного подробнее:
predict(xx$finalModel, testData)
иpredict(xx, testData)
будет отличаться, если установитьpreProcess
опцию при использованииtrain
. С другой стороны, приfinalModel
непосредственном использовании это эквивалентно использованиюpredict
функции из модели (predict.randomForest
здесь) вместоpredict.train
; предварительная обработка не происходит. Очевидно, что в сценарии, изложенном в исходном вопросе, где предварительная обработка не выполняется, результаты будут такими же, как при использовании объекта,finalModel
подобранного вручную,randomForest
илиcaret.train
объекта.Я настоятельно рекомендую вам всегда устанавливать случайное начальное число, используемое R, MATLAB или любой другой программой. В противном случае вы не можете проверить воспроизводимость результатов (что в порядке, это может быть не конец света), а также не исключить ошибку или внешний фактор, влияющий на производительность процедуры моделирования (что, да, это отстой). Многие ведущие алгоритмы ML (например, усиление градиента, случайные леса, экстремальные нейронные сети) действительно используют определенные процедуры внутренней передискретизации во время своих этапов обучения, поэтому установка случайных начальных состояний перед (или иногда даже внутри) их этапом обучения может быть важной.
источник
train
чтобы это точно эквивалентноrandomForest
? Я пытался,method="none"
но не уверен, как установить начальное значение для одного значения. Благодарю.preProcess
или как васrandomForest
обучают с самого начала. В общем, предполагая, что у нас нет шагов предварительной обработки, мы должны убедиться, что оба семени и используемые гиперпараметры (здесь только чтоmtry
) одинаковы.Прогнозы от
curClassifier
не совпадают с прогнозами поcurClassifier$finalModel
ссылке . Вы воспроизвелиfinalModel
и сравниваете его сpredict.train
объектом.источник
predict
должны (и действительно делают) давать одинаковые прогнозы в случае, когда исследуется OP. Я разъясняю этот момент немного больше в своем посте.