He estado tratando de evaluar si es más apropiado dividir mi conjunto de datos en conjuntos de prueba y de entrenamiento para estimar la exactitud del modelo o utilizar el CV con exclusión.
Al comparar la variación en las precisiones reportadas por los dos enfoques, noté que tienden a estar correlacionadas negativamente, lo cual no tiene ningún sentido para mí.
Para ilustrar este problema he utilizado un conjunto de datos diferente que he visto mencionado en este Correo electrónico: y también usé los mismos comandos de preprocesamiento que se usaron en ese post. Como se mencionó anteriormente, he visto la misma correlación negativa extraña en las precisiones en un conjunto de datos diferente, así que no creo que los pasos de preprocesamiento y / o las peculiaridades de este conjunto de datos específicos son responsables.
Creo que es más probable que me esté perdiendo algo trivial - ¿alguien tiene una idea de lo que está pasando aquí? Ver mi Rscript y gráfico de dispersión de las precisiones a continuación.
library(caret)
### import doMC library and allow up to 30 cores to be used for multi-threading:
library(doMC)
registerDoMC(cores = 30)
### GermanCredit dataset, which is packaged with caret:
data(GermanCredit)
### prep df for all results:
out <- data.frame( matrix( NA , nrow=0 , ncol=5 ))
colnames(out) <- c("Rep" , "mtry" , "train_accuracy" , "test_accuracy" , "Kappa")
GermanCredit <- GermanCredit[, -nearZeroVar(GermanCredit)]
GermanCredit$CheckingAccountStatus.lt.0 <- NULL
GermanCredit$SavingsAccountBonds.lt.100 <- NULL
GermanCredit$EmploymentDuration.lt.1 <- NULL
GermanCredit$EmploymentDuration.Unemployed <- NULL
GermanCredit$Personal.Male.Married.Widowed <- NULL
GermanCredit$Property.Unknown <- NULL
GermanCredit$Housing.ForFree <- NULL
### use leave-one-out CV and a grid search for the mtry parameter:
fit_control <- trainControl( method = "LOOCV" , search="grid" )
for ( i in 1:100) {
### change random seed for every replicate (for both dividing data into test/training sets and for the RF itself)
set.seed(1991 + i)
### divide data into test/training sets:
inTrain <- createDataPartition(GermanCredit$Class, p = .8)[[1]]
GermanCreditTrain <- GermanCredit[ inTrain, ]
GermanCreditTest <- GermanCredit[-inTrain, ]
set.seed(10847 + i)
### run RF model with tuneLength and ntree set to small values so this script can be re-run relatively quickly
### I observed the same overall trend of negative correlation when tuneLength=30 and ntree = 1001, so this isn't the problem.
credit.rf <- train( Class ~ . , data = GermanCreditTrain, trControl=fit_control , model="rf", tuneLength=3, ntree = 11)
### get accuracy on test set:
test.rf <- predict( credit.rf, GermanCreditTest)
test_confusionMatrix <- confusionMatrix( test.rf , GermanCreditTest$Class )
result <- data.frame( matrix(c( i , credit.rf$bestTune[[1]] , credit.rf$results$Accuracy[which(credit.rf$results$mtry==credit.rf$bestTune[[1]])] , test_confusionMatrix$overall[[1]] , test_confusionMatrix$overall[[2]] ), nrow=1, ncol=5) )
colnames(result) <- c("Rep" , "mtry" , "train_accuracy" , "test_accuracy" , "Kappa")
out <- rbind( out, result)
}
plot( out$train_accuracy , out$test_accuracy , pch = 16 , xlab="Training set leave-one-out CV accuracy" , ylab="Test set accuracy")
cor.test( out$train_accuracy , out$test_accuracy )
# Pearson's product-moment correlation
#
# data: out$train_accuracy and out$test_accuracy
# t = -5.128, df = 98, p-value = 1.476e-06
# alternative hypothesis: true correlation is not equal to 0
# 95 percent confidence interval:
# -0.601990 -0.289714
# sample estimates:
# cor
# -0.4599582
EDITAR: Creo que ahora entiendo el problema, véase mi respuesta más abajo.