(Estoy seguro de que ya escribí la mayor parte de esto en alguna respuesta, pero no puedo encontrarlo en este momento. Si alguien se topa con esa respuesta, por favor enlácela). Veo 2 enfoques ligeramente diferentes aquí, que creo que son sensatos.
Pero primero algo de terminología:
- Viniendo de un campo aplicado, un modelo (ajustado / entrenado) para mí es un modelo listo para usar. Es decir, el modelo contiene toda la información necesaria para generar predicciones para nuevos datos. Por lo tanto, el modelo contiene también los hiperparámetros . Como verá, este punto de vista está estrechamente relacionado con el enfoque 2 a continuación.
- OTOH, el algoritmo de entrenamiento en mi experiencia no está bien definido en el siguiente sentido: para obtener el modelo (ajustado), no solo se debe hacer, digamos "ajuste primario", de los parámetros del modelo "normal", pero también los hiperparámetros necesitan ser reparados. Desde la perspectiva de mi aplicación, no hay mucha diferencia entre los parámetros y los hiperparámeros: ambos son parte del modelo y deben estimarse / decidirse durante el entrenamiento.
Supongo que la diferencia entre ellos está relacionada con la diferencia entre alguien que desarrolla nuevos algoritmos de entrenamiento que generalmente describen una clase de algoritmos de entrenamiento junto con algunos parámetros de dirección (los hiperparámetros) que son difíciles / imposibles de corregir (o al menos corregir cómo deberían decidirse / estimarse) sin el conocimiento de la aplicación / dominio.
Enfoque 1: requieren resultados de optimización estables
Con este enfoque, el "entrenamiento del modelo" es la adaptación de los parámetros del modelo "normal", y se proporcionan hiperparámetros . Una validación cruzada interna, por ejemplo, se encarga de la optimización del hiperparámetro.
El paso / supuesto crucial aquí para resolver el dilema de qué conjunto de hiperparámetros debe elegirse es requerir que la optimización sea estable . La validación cruzada para fines de validación supone que todos los modelos sustitutos son lo suficientemente similares al modelo final (obtenido por el mismo algoritmo de entrenamiento aplicado a todo el conjunto de datos) para permitir tratarlos como iguales (entre ellos, así como al modelo final). Si esta suposición se rompe y
los modelos sustitutos siguen siendo iguales (o equivalentes) entre sí, pero no con el modelo final, estamos hablando del conocido sesgo pesimista de la validación cruzada.
Si también el modelo sustituto no es igual / equivalente entre sí, tenemos problemas de inestabilidad .
Para los resultados de optimización del bucle interno, esto significa que si la optimización es estable, no hay conflicto al elegir hiperparámetros . Y si se observa una variación considerable en los resultados de validación cruzada interna, la optimización no es estable . Las situaciones de entrenamiento inestables tienen problemas mucho peores que la decisión de cuál de los parámetros de hiperparámetros elegir, y realmente recomendaría retroceder en ese caso y comenzar el proceso de modelado nuevamente.
Sin embargo, aquí hay una excepción: puede haber varios mínimos locales en la optimización que produzcan el mismo rendimiento para fines prácticos. Exigir también la opción entre ellos de ser estable puede ser un requisito innecesario, pero no sé cómo salir de este dilema.
Tenga en cuenta que si no todos los modelos producen el mismo conjunto de parámetros ganadores, no debe usar estimaciones de bucle externo como error de generalización aquí:
- pag
- Pero a menos que no haya una decisión involucrada ya que todas las divisiones produjeron los mismos parámetros, esto romperá la independencia en el bucle externo: los datos de prueba de cada división ya ingresaron la decisión de qué conjunto de parámetros gana, ya que fueron datos de entrenamiento en todas las otras divisiones y, por lo tanto, se usaron para optimizar los parámetros.
Enfoque 2: tratar el ajuste de hiperparámetros como parte del entrenamiento modelo
Este enfoque une las perspectivas del "desarrollador del algoritmo de entrenamiento" y el usuario aplicado del algoritmo de entrenamiento.
El desarrollador del algoritmo de entrenamiento proporciona un algoritmo de entrenamiento "desnudo" model = train_naked (trainingdata, hyperparameters)
. Como el usuario aplicado necesita tunedmodel = train_tuned (trainingdata)
que también se encarga de arreglar los hiperparámetros.
train_tuned
se puede implementar, por ejemplo, envolviendo un optimizador basado en validación cruzada alrededor del algoritmo de entrenamiento simple train_naked
.
train_tuned
entonces puede usarse como cualquier otro algoritmo de entrenamiento que no requiera la entrada de hiperparámetros, por ejemplo, su salida tunedmodel
puede estar sujeta a validación cruzada. Ahora se verifica la estabilidad de los hiperparámetros al igual que se debe verificar la estabilidad de los parámetros "normales" como parte de la evaluación de la validación cruzada.
Esto es realmente lo que hace y evalúa en la validación cruzada anidada si promedia el rendimiento de todos los modelos ganadores, independientemente de sus conjuntos de parámetros individuales.
¿Cual es la diferencia?
Posiblemente terminemos con diferentes modelos finales que adopten esos 2 enfoques:
- el modelo final en el enfoque 1 será
train_naked (all data, hyperparameters from optimization)
- mientras que el enfoque 2 usará
train_tuned (all data)
y, ya que eso ejecuta la optimización de hiperparámetros nuevamente en el conjunto de datos más grande, esto puede terminar con un conjunto diferente de hiperparámetros.
Pero de nuevo se aplica la misma lógica: si encontramos que el modelo final tiene parámetros sustancialmente diferentes de los modelos sustitutos de validación cruzada, ese es un síntoma de la suposición 1 violada. Entonces, en mi humilde opinión, nuevamente no tenemos un conflicto, sino más bien una verificación de si nuestras suposiciones (implícitas) están justificadas. Y si no lo son, de todos modos no deberíamos apostar demasiado por tener una buena estimación del rendimiento de ese modelo final.
Tengo la impresión (también de ver la cantidad de preguntas / confusiones similares aquí en CV) que muchas personas piensan en la validación cruzada anidada haciendo el enfoque 1. Pero el error de generalización generalmente se estima de acuerdo con el enfoque 2, por lo que ese es el camino a seguir para el modelo final también.
Ejemplo de Iris
Resumen: La optimización es básicamente inútil. El tamaño de muestra disponible no permite distinciones entre el rendimiento de ninguno de los conjuntos de parámetros aquí.
Sin embargo, desde el punto de vista de la aplicación, la conclusión es que no importa cuál de los 4 conjuntos de parámetros elija, lo cual no es una mala noticia: encontró una meseta de parámetros relativamente estable. Aquí viene la ventaja de la validación anidada adecuada del modelo ajustado: si bien no puede afirmar que es el modelo óptimo, todavía puede afirmar que el modelo construido sobre todos los datos utilizando el enfoque 2 tendrá aproximadamente 97% de precisión (intervalo de confianza del 95% para 145 correctos de 150 casos de prueba: 92 - 99%)
Tenga en cuenta que también el enfoque 1 no está tan lejos como parece: vea a continuación: su optimización accidentalmente perdió un "ganador" comparativamente claro debido a los lazos (ese es otro síntoma muy revelador del problema del tamaño de la muestra).
Si bien no soy lo suficientemente profundo en SVM como para "ver" que C = 1 debería ser una buena opción aquí, optaría por el núcleo lineal más restrictivo. Además, como hizo la optimización, no hay nada de malo en elegir el conjunto de parámetros ganador, incluso si es consciente de que todos los conjuntos de parámetros conducen a un rendimiento prácticamente igual.
Sin embargo, en el futuro, considere si su experiencia arroja estimaciones aproximadas de qué rendimiento puede esperar y aproximadamente qué modelo sería una buena opción. Luego, cree ese modelo (con hiperparámetros fijados manualmente) y calcule un intervalo de confianza para su rendimiento. Use esto para decidir si intentar optimizar es razonable. (Debo agregar que estoy trabajando principalmente con datos en los que obtener 10 casos independientes más no es fácil; si está en un campo con grandes tamaños de muestra independientes, las cosas se ven mucho mejor para usted)
Versión larga:
En cuanto a los resultados del ejemplo en el iris
conjunto de datos. iris
tiene 150 casos, se considera SVM con una cuadrícula de 2 x 2 parámetros (2 núcleos, 2 órdenes de magnitud para la penalización C
).
El bucle interno tiene divisiones de 129 (2x) y 132 (6x) casos. El "mejor" conjunto de parámetros está indeciso entre el núcleo lineal o rbf, ambos con C = 1. Sin embargo, las precisiones internas de la prueba son todas (incluida la pérdida constante de C = 10) dentro del 94 - 98.5% de precisión observada. La mayor diferencia que tenemos en una de las divisiones es 3 vs. 8 errores para rbf con C = 1 vs. 10.
No hay forma de que esto sea una diferencia significativa. No sé cómo extraer las predicciones para los casos individuales en el CV, pero incluso suponiendo que se compartieron los 3 errores, y el modelo C = 10 cometió 5 errores adicionales:
> table (rbf1, rbf10)
rbf10
rbf1 correct wrong
correct 124 5
wrong 0 3
> mcnemar.exact(rbf1, rbf10)
Exact McNemar test (with central confidence intervals)
data: rbf1 and rbf10
b = 5, c = 0, p-value = 0.0625
alternative hypothesis: true odds ratio is not equal to 1
Recuerde que hay 6 comparaciones por pares en la cuadrícula de 2 x 2, por lo que también tendremos que corregir las comparaciones múltiples.
Enfoque 1
En 3 de las 4 divisiones externas donde rbf "ganó" sobre el núcleo lineal, en realidad tenían la misma precisión estimada (supongo que min en caso de empate devuelve el primer índice adecuado).
Cambiar la grilla a
params = {'kernel':['linear', 'rbf'],'C':[1,10]}
rendimientos
({'kernel': 'linear', 'C': 1}, 0.95238095238095233, 0.97674418604651159)
({'kernel': 'rbf', 'C': 1}, 0.95238095238095233, 0.98449612403100772)
({'kernel': 'linear', 'C': 1}, 1.0, 0.97727272727272729)
({'kernel': 'linear', 'C': 1}, 0.94444444444444442, 0.98484848484848486)
({'kernel': 'linear', 'C': 1}, 0.94444444444444442, 0.98484848484848486)
({'kernel': 'linear', 'C': 1}, 1.0, 0.98484848484848486)
({'kernel': 'linear', 'C': 1}, 1.0, 0.96212121212121215)
Enfoque 2:
Aquí clf
está tu modelo final. Con random_state = 2
, rbf con C = 1 gana:
In [310]: clf.grid_scores_
[...snip warning...]
Out[310]:
[mean: 0.97333, std: 0.00897, params: {'kernel': 'linear', 'C': 1},
mean: 0.98000, std: 0.02773, params: {'kernel': 'rbf', 'C': 1},
mean: 0.96000, std: 0.03202, params: {'kernel': 'linear', 'C': 10},
mean: 0.95333, std: 0.01791, params: {'kernel': 'rbf', 'C': 10}]
(sucede aproximadamente 1 de cada 5 veces, 1 de cada 6 veces linear
y rbf
con C = 1
empate en el rango 1)