LOOCV vs.K-veces CV lleva a los mismos resultados

Aug 18 2020

Construyo un modelo de regresión lineal y lo uso para predecir fuera de muestra. En este contexto, utilizo LOOCV y k-fold CV (5). Sin embargo, ambos métodos parecen conducir a los mismos resultados. La única diferencia menor entre estos dos métodos son los valores ligeramente diferentes para las medidas de precisión para las estimaciones en la muestra (consulte los resultados a continuación).

Que esta pasando aqui; me estoy perdiendo un punto?

library(mlbench)
library(caret)
data(BostonHousing)
df <- BostonHousing

######
set.seed(12345)
train.index <- createDataPartition(df$medv, p = 0.75, list = FALSE)
train <- df[train.index, ]
test <- df[-train.index, ]

#####
fitControl <- trainControl(method = "LOOCV")

mod1 <- train(medv ~ crim + zn + rm,
              data = train,
              method = "lm",
              trControl = fitControl)

preds1 <- predict(mod1, newdata = test)

#####
fitControl2 <- trainControl(method = "repeatedcv", number = 5, repeats = 10)

mod2 <- train(medv ~ crim + zn + rm,
              data = train,
              method = "lm",
              trControl = fitControl2)

preds2 <- predict(mod2, newdata = test)

Los resultados son los siguientes:

Coeficientes:

coef(summary(mod1)) 
coef(summary(mod2))

             LOOCV         k-fold
(Intercept) -28.74077696  -28.74077696
crim         -0.23736504   -0.23736504
zn            0.04259996    0.04259996
rm            8.21720224    8.21720224

Ajuste dentro de la muestra:

mod1$results mod2$results

              LOOCV         k-fold
RMSE          6.16378       6.083234
Rsquared      0.5437839     0.5727744
MAE           4.176978      4.174368

Ajuste fuera de muestra:

postResample(preds1, obs = test$medv) postResample(preds2, obs = test$medv)

              LOOCV         k-fold
RMSE          4.1298679     4.1298679
Rsquared      0.5489697     0.5489697
MAE           4.1298679     4.1298679

Respuestas

1 cbeleitesunhappywithSX Aug 19 2020 at 16:56

En primer lugar, los modelos finales ( mod1$finalModely mod1$finalModel) son los mismos, en su caso particular por dos razones:

  1. En realidad, no sintoniza, entrena un solo modelo que es el modelo lineal con intercept = TRUE).

    La línea indicadora es el resultado de print(mod2):

    El parámetro de ajuste 'intercepción' se mantuvo constante en un valor de VERDADERO

    También puede mirar mod2$results:

      intercept     RMSE  Rsquared      MAE    RMSESD RsquaredSD     MAESD  
    1      TRUE 6.121066 0.5568386 4.187102 0.9087823  0.1089092 0.4691107
    

    Compare esto con:

    mod3 <- train(medv ~ crim + zn + rm,
               data = train,
               method = "lm",
               tuneGrid = data.frame (intercept = c(FALSE, TRUE)),
               trControl = fitControl)
    mod3
    # [...snip...]
    # Resampling results across tuning parameters:
    # 
    #   intercept  RMSE      Rsquared   MAE     
    #   FALSE      6.818821  0.4592127  4.844369
    #    TRUE      6.163780  0.5437839  4.176978
    # 
    # RMSE was used to select the optimal model using the smallest value.
    # The final value used for the model was intercept = TRUE.
    
    mod3$results
    #   intercept     RMSE  Rsquared      MAE
    # 1     FALSE 6.818821 0.4592127 4.844369
    # 2      TRUE 6.163780 0.5437839 4.176978
    
  2. La validación cruzada interna durante el ajuste da como resultado un conjunto de hiperparámetros, pero aún no en el modelo final. El modelo final se obtiene entrenando con este conjunto de hiperparámetros y todos los datos que se le entregaron train().

    Independientemente de la rutina de validación cruzada / bootstrap que elija, siempre que el conjunto de hiperparámetros sintonizados sea el mismo, el modelo final también será el mismo (al menos para rutinas de entrenamiento deterministas como lm()).

    Entonces, incluso si lo hubiera sintonizado, todavía resultaría el mismo modelo: el que tiene intercept = TRUE.