Validación cruzada de PCA y k-fold en el paquete caret en R

16

Acabo de volver a ver una conferencia del curso de Machine Learning en Coursera. En la sección donde el profesor discute PCA para el procesamiento previo de datos en aplicaciones de aprendizaje supervisado, dice que PCA solo debe realizarse en los datos de entrenamiento y luego el mapeo se utiliza para transformar la validación cruzada y los conjuntos de pruebas. Ver también PCA y la división de tren / prueba .

Sin embargo, en el caretpaquete R, train()PCA ya procesa los datos de entrenamiento que pasa a la función. Entonces, cuando el algoritmo realiza la validación cruzada k-fold, el conjunto de validación cruzada ya se ha procesado con PCA a través de preProcess()y, predict()de hecho, se utiliza en el "ajuste" de PCA.

¿Es correcto mi comprensión de la situación? Es decir, el procedimiento de caret para la validación cruzada con PCA (o, de hecho, con cualquier método de reescalado / centrado) es "incorrecto" porque el procesamiento previo de los datos se realiza en el conjunto de validación cruzada y en el conjunto de entrenamiento. Y si es así, ¿qué impacto tendría esto en los resultados?

mchangun
fuente
1
Interesante pregunta. ¿El profesor Ng da razones por las cuales "PCA solo debe realizarse en los datos de entrenamiento y luego el mapeo se utiliza para transformar la validación cruzada y los conjuntos de prueba"? Mi intuición es que el impacto debería ser mínimo, ya que se supone que los datos de tren / cv / prueba provienen de la misma distribución, y PCA no involucra la salida / variable (s) dependiente (s).
miura
1
@miura Sí, lo hace. Al realizar PCA, necesitamos resolver el número mínimo de k dimensiones en los vectores de salida necesarios para lograr la "varianza retenida" deseada. Este parámetro k ahora está en vigencia (en mi entendimiento) un parámetro adicional de nuestro algoritmo que necesitamos ajustar. Si también realizamos PCA en el conjunto de validación cruzada, en efecto estamos entrenando una parte de nuestro algoritmo en el conjunto de CV, lo que disminuye el valor de la validación cruzada.
mchangun
Creo que está confundiendo PCA y MDS, pero en ambos métodos no establece una variación retenida deseada. Pero puede calcularlo a partir del ajuste que aportan para reducir a k dimensiones. No necesita ajustarlo porque la primera dimensión siempre reducirá más la varianza que la segunda, y la segunda más que la tercera ...
llrs

Respuestas:

18

No vi la conferencia, así que no puedo comentar sobre lo que se dijo.

Mis $ 0.02: si desea obtener buenas estimaciones de rendimiento utilizando el remuestreo, realmente debe realizar todas las operaciones durante el remuestreo en lugar de antes. Esto es realmente cierto para la selección de características [1], así como para operaciones no triviales como PCA. Si agrega incertidumbre a los resultados, inclúyalo en el remuestreo.

Piense en la regresión de componentes principales: PCA seguida de regresión lineal en algunos de los componentes. PCA estima los parámetros (con ruido) y también se debe elegir el número de componentes (valores diferentes darán como resultado resultados diferentes => más ruido).

Digamos que usamos 10 veces CV con el esquema 1:

conduct PCA
pick the number of components
for each fold:
   split data
   fit linear regression on the 90% used for training
   predict the 10% held out
end:

o esquema 2:

for each fold:
   split data
   conduct PCA on the 90% used for training
   pick the number of components
   fit linear regression
   predict the 10% held out
end:

Debe quedar claro que el segundo enfoque debe producir estimaciones de error que reflejen la incertidumbre causada por PCA, la selección del número de componentes y la regresión lineal. En efecto, el CV en el primer esquema no tiene idea de lo que lo precedió.

Soy culpable de no siempre hacer todas las operaciones con el remuestreo, sino solo cuando realmente no me importan las estimaciones de rendimiento (lo cual es inusual).

¿Hay mucha diferencia entre los dos esquemas? Depende de los datos y el preprocesamiento. Si solo está centrando y escalando, probablemente no. Si tiene un montón de datos, probablemente no. A medida que disminuye el tamaño del conjunto de entrenamiento, aumenta el riesgo de obtener estimaciones pobres, especialmente si n está cerca de p.

Puedo decir con certeza por experiencia que no incluir la selección de funciones supervisadas dentro del remuestreo es una muy mala idea (sin grandes conjuntos de entrenamiento). No veo por qué el preprocesamiento sería inmune a esto (hasta cierto punto).

@mchangun: Creo que el número de componentes es un parámetro de ajuste y probablemente desee elegirlo utilizando estimaciones de rendimiento que sean generalizables. Puede elegir automáticamente K de manera que se explique al menos el X% de la varianza e incluir ese proceso dentro del remuestreo para que tengamos en cuenta el ruido en ese proceso.

Max

[1] Ambroise, C. y McLachlan, G. (2002). Sesgo de selección en la extracción de genes sobre la base de datos de expresión de genes de microarrays. Actas de la Academia Nacional de Ciencias, 99 (10), 6562-6566.

topepo
fuente
21

¡No procese previamente los datos antes de ejecutar la trainfunción! Usa el preProcess argumento para la función de tren, y el preprocesamiento se aplicará a cada iteración de remuestreo.

por ejemplo , no hagas esto:

library(caret)
dat <- iris
pp <- preProcess(dat[,-5], method="pca")
dat[,-5] <- predict(pp, dat[,-5])
knnFit1 <- train(Species~., dat, method = "knn", preProcess=c("pca"), 
    trControl = trainControl(method = "cv"))

¡hacer esto!

dat <- iris
knnFit2 <- train(Species~., dat, method = "knn", preProcess=c("pca"), 
    trControl = trainControl(method = "cv"))
Zach
fuente
1
Si realizo el prProcess como usted sugiere, ¿necesito preprocesar nuevos datos cuando quiero usar el modelo para las predicciones? Por el momento, solo lo hago: pred <- predict(knnFit2, newdata) donde newdatano está escalado. ¿Caret es lo suficientemente inteligente como para saber que necesita preprocesar newdataantes de usarlo para las predicciones?
mchangun
77
@mchangun no. caret guarda los parámetros de preprocesamiento y procesará previamente los nuevos datos en la llamada predict.caret. ¡Es muy hábil!
Zach