Estoy un poco confundido: ¿cómo pueden los resultados de un modelo entrenado a través de caret diferir del modelo en el paquete original? Yo leo si se necesita un procesamiento previo antes de la predicción usando FinalModel de RandomForest con el paquete caret? pero no uso ningún preprocesamiento aquí.
Entrené a diferentes bosques aleatorios usando el paquete de caret y sintonizando diferentes valores 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
Encontré que mtry = 15 es el mejor parámetro en 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.
Evalué el modelo con una curva ROC y una matriz de confusió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")
La matriz de confusión resultante y la precisión:
Confusion Matrix and Statistics
Reference
Prediction No Yes
No 2757 693
Yes 375 6684
Accuracy : 0.8984
....
Ahora entrené un Rorest Random con los mismos parámetros y los mismos datos de entrenamiento usando el paquete básico randomForest:
randomForestManual <- randomForest(case_success ~ ., data=train_data, mtry = 15, ntree=500,keep.forest=TRUE)
curClassifier = randomForestManual
Nuevamente, creé predicciones para los mismos test_data de arriba y evalué la matriz de confusión con el mismo código que arriba. Pero ahora tengo diferentes medidas:
Confusion Matrix and Statistics
Reference
Prediction No Yes
No 2702 897
Yes 430 6480
Accuracy : 0.8737
....
¿Cuál es la razón? ¿Qué me estoy perdiendo?

seedsargumento detrainControlRespuestas:
Creo que la pregunta, aunque algo trivial y "programática" en primera lectura, toca dos cuestiones principales que son muy importantes en las estadísticas modernas:
La razón de los diferentes resultados es que los dos procedimientos se entrenan utilizando diferentes semillas aleatorias. Los bosques aleatorios usan un subconjunto aleatorio de las variables del conjunto de datos completo como candidatos en cada división (esa es la
mtryargumento y se relaciona con el método de subespacio aleatorio ), así como bolsas el conjunto de datos original de (agregados de arranque) para disminuir la varianza del modelo. Estos dos procedimientos de muestreo aleatorio interno no son deterministas entre diferentes ejecuciones del algoritmo. El orden aleatorio en que se realiza el muestreo está controlado por las semillas aleatorias utilizadas. Si se usaran las mismas semillas, se obtendrían exactamente los mismos resultados en ambos casos donderandomForestse llama la rutina; ambos internamente encaret::trainasí como externamente cuando se ajusta un bosque aleatorio manualmente. Adjunto un fragmento de código simple para mostrar esto. Tenga en cuenta que uso un número muy pequeño de árboles (argumento:)ntreepara mantener el entrenamiento rápido, generalmente debería ser mucho más grande.En este punto, tanto el
caret.trainobjetofitRFcaretcomo elrandomForestobjeto definido manualmentefitRFmanualhan sido entrenados usando los mismos datos pero importantemente usando las mismas semillas aleatorias al ajustar su modelo final. Por lo tanto, cuando intentaremos predecir el uso de estos objetos y porque no procesamos previamente nuestros datos , obtendremos las mismas respuestas exactas.Solo para aclarar esto más adelante, apunte un poco más:
predict(xx$finalModel, testData)ypredict(xx, testData)será diferente si se configura lapreProcessopción cuando se usatrain. Por otro lado, cuando se usafinalModeldirectamente, es equivalente usar elpredictfunción del modelo ajustado (predict.randomForestaquí) en lugar depredict.train; no tiene lugar el preprocesamiento. Obviamente, en el escenario descrito en la pregunta original donde no se realiza el procesamiento previo, los resultados serán los mismos cuando se utiliza el objetofinalModelajustado manualmenterandomForesto elcaret.trainobjeto.Te sugiero encarecidamente que siempre establezca la semilla aleatoria utilizada por R, MATLAB o cualquier otro programa utilizado. De lo contrario, no puede verificar la reproducibilidad de los resultados (lo cual está bien, puede que no sea el fin del mundo) ni excluir un error o factor externo que afecte el desempeño de un procedimiento de modelado (que sí, apesta). Muchos de los principales algoritmos de ML (p. Ej., Aumento de gradiente, bosques aleatorios, redes neuronales extremas) emplean ciertos procedimientos internos de remuestreo durante sus fases de entrenamiento, estableciendo los estados de semilla aleatorios antes (o a veces incluso dentro) de su fase de entrenamiento puede ser importante.
fuente
trainpara que sea exactamente equivalente arandomForest? Intentémethod="none"pero no estoy seguro de cómo establecer la semilla en el valor único. Gracias.preProcesso cómorandomForestestá entrenado para empezar. En general, suponiendo que no tengamos pasos de preprocesamiento, debemos asegurarnos de que tanto la semilla como los hiperparámetros (aquí solomtry) utilizados sean iguales.Las predicciones de
curClassifierno son lo mismo que las predicciones delcurClassifier$finalModelenlace . Has reproducidofinalModely lo estás comparando con elpredict.trainobjeto.fuente
predictdeberían (y lo hacen en realidad) dar las mismas predicciones en el caso de que el OP explore. Aclaro un poco más este punto en mi publicación.