7 votos

¿Tenemos que fijar las divisiones antes de la validación cruzada de 10 pliegos si queremos comparar diferentes algoritmos?

Trabajo con R y digamos que tengo un juego de trenes y un juego de pruebas. Quiero probar diferentes algoritmos (por ejemplo, redes neuronales y svm).

Voy a realizar una primera validación cruzada de 10 veces en mi conjunto de entrenamiento para afinar la red neuronal.

Luego realizaré una validación cruzada de 10 veces en mi conjunto de trenes para afinar el svm.

Y compararé el rendimiento de cada uno de los mejores modelos en mi conjunto de pruebas.

Me preguntaba si era teóricamente un problema que los 10 pliegues (construidos aleatoriamente) no fueran los mismos en la sintonía de ambos algoritmos.

Creo que esto no debería ser un problema porque el resultado del ajuste debería ser robusto a la elección de los pliegues. Pero aparentemente no es el caso (he leído que sobre knn, con tune.knn del paquete e1071 en R).

Si tenemos que arreglar las divisiones antes de la sintonización, ¿sabes cómo hacerlo en R? No he encontrado la opción adecuada para la función de sintonización del paquete e1071.

¿Es caret un paquete mejor relativamente a este punto? Dado que parece posible repetir la validación cruzada de 10 pliegues al realizar el ajuste, creo que eso podría hacer que los resultados del ajuste sean más robustos y que la comparación de los diferentes modelos sea más legítima.

Gracias por su visión

5voto

Rob Allen Puntos 486

Ciertamente ayuda, pero no es absolutamente esencial.

La elección de las divisiones de validación cruzada introduce una fuente de variabilidad (poco interesante). El uso del mismo conjunto de divisiones elimina esta fuente de variabilidad, lo que podría aumentar su capacidad para detectar la variabilidad en el rendimiento de diferentes clasificadores (si existe), que suele ser mucho más interesante.

Si puedes controlar las divisiones, deberías hacerlo: es una forma fácil de aumentar la potencia de tu experimento sin hacer mucho trabajo adicional. Por otro lado, si ya tiene algunos resultados difíciles de replicar en los que se olvidó de almacenar las divisiones, ciertamente puede utilizar esos datos; sólo tenga en cuenta que las comparaciones basadas en esos resultados no serán tan potentes como podrían ser. La gente suele suponer que la varianza relacionada con la partición es mucho menor que la varianza entre los clasificadores, aunque eso puede no ser cierto, especialmente si sus clases están muy desequilibradas.

En cuanto a e1071 específicamente, los documentos de tune diga

La validación cruzada aleatoriza el conjunto de datos antes de construir las divisiones que, una vez creadas, permanecen constantes durante el proceso de entrenamiento. Las divisiones de pueden recuperarse a través del componente train.ind del objeto devuelto.

Podrías dejar que tune generar los pliegues por sí mismo para el primer algoritmo, y luego utilizarlos, a través de tune.control (con muestreo=fijo), para evaluar las siguientes. Alternativamente, parece que tune genera su partición usando prng global (a través de una llamada a sample ), al principio de la función ( Línea 71 de Tune.R en la fuente ), por lo que puede ser capaz de generar los mismos pliegues restableciendo la semilla del generador de números aleatorios antes de cada llamada a tune . Sin embargo, esto parece un poco frágil. Por último, esto es bastante fácil de programar usted mismo.

2voto

user777 Puntos 10934

Los resultados serán sensibles a las divisiones, por lo que debe comparar los modelos en la misma partición de los datos. Compare estos dos enfoques:

  1. El enfoque 1 comparará dos modelos, pero utilizará la misma partición de CV.
  2. El enfoque 2 comparará dos modelos, pero el primer modelo tendrá una partición de CV diferente a la del segundo.

Nos gustaría seleccionar el mejor modelo. El problema con el enfoque 2 es que la diferencia de rendimiento entre los dos modelos provendrá de dos fuentes diferentes (a) las diferencias entre los dos pliegues y (b) las diferencias entre los propios algoritmos (por ejemplo, bosque aleatorio y regresión logística). Si un modelo supera al otro, no sabremos si esa diferencia de rendimiento se debe en su totalidad, en parte o en absoluto a las diferencias entre las dos particiones de CV. Por otro lado, cualquier diferencia en el rendimiento utilizando el enfoque 1 no puede ser debido a las diferencias en la forma de dividir los datos, porque las particiones son idénticas.

Para arreglar el parcionamiento, utilice cvTools para crear sus particiones CV (repetidas) y almacenar los resultados.

2voto

cbeleites Puntos 12461

Además de la respuesta de @Matt Krause:

Yo enfocaría la cuestión desde dos puntos diferentes:

  • Uno de los supuestos básicos en los que se basa la validación cruzada es que los modelos construidos en las diferentes divisiones son iguales (o al menos equivalentes). Esto permite agrupar los resultados de todas esas divisiones. Si se cumple este supuesto, la división no importa.
    Sin embargo, en la práctica ocurre que la división introduce una varianza no despreciable, es decir, que los modelos son inestables frente a pequeños cambios en los datos de entrenamiento, por lo que esta variación debería comprobarse de todos modos (aunque no se optimice nada).

  • Evaluar diferentes clasificadores en las mismas divisiones significa que se puede evaluar la comparación en una prueba emparejada, que es más potente que las correspondientes pruebas no emparejadas: por eso se pueden detectar cambios menores en el rendimiento manteniendo las divisiones constantes.

0voto

PauloHDSousa Puntos 101

Aunque esto ya ha sido respondido, si quieres un código que te permita usar las mismas divisiones de CV en caret para múltiples entrenamientos de modelos, puedes usar lo siguiente:

tune_control <- trainControl(
  method = "repeatedcv", 
  repeats = 2,
  number = 5,
  index = createMultiFolds(df$y, k=5, times=2) # assuming your object is df and you are modeling y
)

Puedes comprobar manualmente este trabajo entrenando dos modelos y comparando la salida de:

model$control$index # replace model w/ name of your model

que debería imprimir algo como:

List of 10
Fold1.Rep1: int [1:2400] 1 2 3 4 5 7 9 10 11 12 ...
Fold2.Rep1: int [1:2400] 1 2 3 4 5 6 7 8 9 10 ...
Fold3.Rep1: int [1:2400] 2 3 4 6 8 9 10 11 13 14 ...
Fold4.Rep1: int [1:2400] 1 2 5 6 7 8 11 12 16 18 ...
Fold5.Rep1: int [1:2400] 1 3 4 5 6 7 8 9 10 11 ...
Fold1.Rep2: int [1:2400] 1 3 4 5 6 8 10 11 12 14 ...
Fold2.Rep2: int [1:2400] 1 2 3 4 5 6 7 8 9 10 ...
Fold3.Rep2: int [1:2400] 2 3 4 5 7 8 9 10 11 12 ...
Fold4.Rep2: int [1:2400] 1 2 3 5 6 7 8 9 11 12 ...
Fold5.Rep2: int [1:2400] 1 2 4 6 7 9 10 13 16 17 ...

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X