FastAI Machine Learning (Lección 5-Primera parte)

Christian Tutivén Gálvez
Saturdays.AI
Published in
12 min readMar 2, 2019

Ahora ya entendemos que es un bosque aleatorio (Random Forest) y sabemos como usarlo para analizar nuestros datos. En la lección # 5, nos centraremos en cómo identificar si el modelo se está generalizando bien o no. Jeremy Howard también habla acerca de los intérpretes de árboles, la contribución y la comprensión de los mismos usando un cuadro de cascada (que ya hemos cubierto en la lección anterior, por lo que no explicaremos más sobre esto). El enfoque principal del vídeo es sobre la extrapolación y la comprensión de cómo podemos construir un algoritmo de bosque aleatorio desde cero.

El objetivo de Machine Learning es generalizar

Tenemos un conjunto de datos con un montón de filas y tenemos algunas variables dependientes. ¿Cuál es la diferencia entre el aprendizaje automático y cualquier otro tipo de trabajo? La diferencia es que, en el aprendizaje automático, lo que nos importa es la precisión de la generalización o el error de la generalización. Además, en casi todo lo demás, lo único que nos importa es qué tan bien podemos mapear las observaciones. Así que esta cosa sobre la generalización es la pieza clave única de aprendizaje automático. Y si queremos saber si estamos haciendo un buen trabajo de aprendizaje automático, necesitamos saber si estamos haciendo un buen trabajo de generalización. Si no lo sabemos, no sabemos nada.

Escalabilidad vs Generalizar

Escalar es una cosa importante en muchas áreas. Es como si tenemos algo que funciona en mi computadora con 10,000 artículos, ahora necesito hacer que funcione con 10,000 artículos por segundo. Por lo tanto, la escalabilidad es importante, pero no solo para el aprendizaje automático, sino para casi todo lo que ponemos en producción.

Para entender la generalización veamos el siguiente ejemplo. He visto cinco fotos de gatos y cinco fotos de perros, y he construido un modelo que es perfecto. Luego miro a un grupo diferente de cinco gatos y perros, y los clasifico a todos mal. Entonces, en ese caso, lo que aprendió no fue la diferencia entre un gato y un perro, sino que aprendió cómo se veían esos cinco gatos exactos y cómo se veían esos cinco perros exactos. O construí un modelo para predecir las ventas de comestibles para un producto en particular, por ejemplo para los rollos de papel higiénico en Nueva Jersey el mes pasado, luego voy y lo pongo en producción y la escalabilidad es excelente (en otras palabras, una gran latencia, sin una gran carga de CPU) pero no predice nada más que rollos de papel higiénico en Nueva Jersey. También resulta que solo lo hizo bien el mes pasado, no el mes siguiente. Así que ambas son fallas de generalización.

La forma más común en que las personas verifican la capacidad de generalizar es crear una muestra aleatoria. Así que se tomarán unas cuantas filas al azar y lo pondrán en un conjunto de prueba. Luego, construirán todos sus modelos en el resto de las filas y cuando terminen, comprobarán la precisión que obtuvieron en el conjunto de pruebas (el resto de filas se denomina conjunto de entrenamiento). En otras palabras, al final de su proceso de modelado en el conjunto de entrenamiento, obtuvieron una precisión del 99% al identificar gatos en un conjunto que tiene también perros y lo comparan con un conjunto de prueba para asegurarse de que el modelo realmente se generalice.

Ahora el problema es, ¿y si no lo hace? Bueno, podría volver atrás y cambiar algunos hyper-parámetros, hacer un aumento de datos, cualquier otra cosa que intente crear un modelo más generalizable. Y luego volveré otra vez después de hacer todo eso, y comprobaré que todavía no es bueno. Seguiré haciendo esto una y otra vez hasta que finalmente, después de cincuenta intentos, se generalice. ¿Pero realmente se generaliza? Porque tal vez todo lo que he hecho es encontrar accidentalmente este que funciona solo para ese conjunto de pruebas porque he probado cincuenta cosas diferentes. Entonces, lo que generalmente hacemos es dejar de lado un segundo conjunto de datos (conjunto de validación). Entonces todo lo que no está en la validación o prueba ahora se está entrenando. Lo que hacemos es entrenar un modelo, verificarlo con la validación para ver si se generaliza, hacer eso unas cuantas veces. Luego, cuando finalmente obtengamos algo que creemos que se generalizará correctamente en función del conjunto de validación (al final del proyecto), lo comparamos con el conjunto de prueba.

OOB

Otro truco que hemos aprendido para el bosque aleatorio es una forma de no necesitar un conjunto de validación. Y la forma en que aprendimos fue utilizar, la puntuación OOB. Esta idea se basa en que para tener aleatoriedad cada árbol fue entrenado con filas de manera aleatoria, por lo que quedan filas que no fueron usadas en todos los árboles (solo en algunos) y, por lo tanto, al promediar los árboles que no usaron esa fila para su entrenamiento obtenemos el OOB. Entonces, el puntaje OOB nos da algo que es bastante similar al puntaje de validación, pero en promedio es un poco menos bueno. ¿Por qué? Debido a que cada fila usará un subconjunto de los árboles para hacer su predicción, y con menos árboles, sabemos que obtenemos una predicción menos precisa. De todos modos, generalmente están lo suficientemente cerca. Entonces, ¿por qué tener un conjunto de validación cuando está utilizando bosques aleatorios? Si se trata de un conjunto de validación elegido al azar, no es estrictamente necesario, pero puedes realizar pruebas en el OOB. Cuando funciona bien, puede realizar pruebas en el conjunto de validación, y con suerte en el momento en que compruebes el conjunto de pruebas, no habrá sorpresas, por lo que será una buena razón.

Lo que hace Kaggle es algo inteligente. Lo que Kaggle hace es dividir el conjunto de pruebas en dos partes: una pública y otra privada. Y no te dicen cuál es cuál. Entonces, envías tus predicciones a Kaggle y luego un 30% aleatorio de ellas se usa para decirte el puntaje de la tabla de clasificación. Pero al final de la competencia, eso se desecha y usan el otro 70% para calcular tu puntaje real. Entonces, lo que está haciendo es asegurarse de que no estás utilizando continuamente los comentarios de la tabla de clasificación para descubrir un conjunto de hyper-parámetros que funcionan bien y que en realidad no se generalizan. Así que es una gran prueba. Esta es una de las razones por las que es una buena práctica usar Kaggle, porque al final de una competencia, en algún momento esto te sucederá, y bajaras cien lugares en la tabla de clasificación el último día de la competencia. Ahí es cuando veras lo que es estar sobre-entrenado y es mucho mejor practicar y tener ese sentido allí que hacerlo en una compañía donde hay cientos de millones de dólares en juego.

Por qué hay casos en que usar muestra aleatorios para validar va mal?

Si predecimos quién va a comprar papel higiénico en Nueva Jersey y tardamos dos semanas en ponerlo en producción y lo hicimos utilizando datos de los últimos dos años y para ese entonces, las cosas pueden parecer muy diferentes. Y, en particular, nuestro conjunto de validación, si lo probamos al azar, y fue de un período de cuatro años, la gran mayoría de los datos tendrá más de un año de diferencia. Y puede ser que los hábitos de compra de papel higiénico de la gente en Nueva Jersey hayan cambiado drásticamente. Tal vez ahora existe una recesión terrible y ya no pueden pagar un papel higiénico de alta calidad. O tal vez saben que su industria de fabricación de papel se ha disparado y de repente están comprando mucho más papel higiénico porque es muy barato. Entonces, el mundo cambia y, por lo tanto, si usas una muestra aleatoria para tu conjunto de validación, ¿realmente estás comprobando qué tan bueno es tu modelo para predecir cosas que están totalmente obsoletas ahora? ¿Qué tan bueno eres para predecir cosas que sucedieron hace cuatro años? Eso no es interesante. Entonces, lo que queremos hacer en la práctica, cada vez que hay una parte temporal es decir, suponiendo que lo hayamos ordenado por tiempo, usaremos la última parte como nuestro conjunto de validación. Supongo, en realidad hacerlo correctamente:

Podemos ver nuestro conjunto de validación, y nuestro conjunto de prueba. Así que el resto es nuestro conjunto de entrenamiento y lo usamos, tratando de modelar que aún funcione en cosas que son más tarde que cualquier otra cosa en la que se construyó el modelo. Por lo tanto, no solo estamos probando la generalización en algún tipo de sentido abstracto, sino en un sentido del tiempo muy específico que generaliza el futuro.

¿Cómo se hace el compromiso entre la cantidad de datos frente a la actualidad de los datos?

Lo que Jeremy tiende a hacer es, cuando existe este tipo de problema temporal, que es probablemente la mayoría del tiempo, una vez que se tiene algo que funciona bien en el conjunto de validación, no iría y solo usaría ese modelo en el conjunto de prueba, porque el conjunto de pruebas está mucho más lejos en el futuro en comparación con el conjunto de entrenamiento. Entonces volvería a replicar la construcción de ese modelo, pero esta vez combinaría los conjuntos de entrenamiento y validación y volvería a entrenar el modelo. En ese momento, no hay forma de probar un conjunto de validación, por lo que se debe asegurar tener un script o cuaderno reproducible que realice exactamente los mismos pasos de la misma manera porque si se equivoca en algo, entonces, vamos a encontrar en el conjunto de prueba, que tienes un problema.

Cómo saber si mi conjunto de validación realmente representa mi conjunto de prueba?

En la práctica se necesita saber si mi conjunto de validación es realmente representativo del conjunto de pruebas. Entonces, lo que se hace es construir cinco modelos en el conjunto de entrenamiento, y tratar de que varíen en lo buenos que creo que son. Luego calificamos los cinco modelos en el conjunto de validación y también los calificamos en el conjunto de prueba. Por lo tanto, no estamos haciendo trampa, ya que no utilizamos ninguna observación del conjunto de pruebas para cambiar los hyper-parámetros, solo lo usamos para esta única cosa que es verificar el conjunto de validación. Así que obtenemos cinco puntajes del conjunto de validación y del conjunto de pruebas y luego verificamos que crean una línea.

Si no lo hacen, entonces no obtendremos suficiente información del conjunto de validación. Así que hay que seguir haciendo ese proceso hasta que obtengamos una línea y eso puede ser bastante complicado.

Tratar de crear algo que sea lo más parecido posible al resultado del mundo real es difícil. Y en el mundo real, lo mismo ocurre con la creación del conjunto de prueba: el conjunto de prueba debe ser lo más cercano posible a la producción. Entonces, ¿cuál es la mezcla real de clientes que van a usar esto, cuánto tiempo realmente habrá entre cuando construyes el modelo y cuando lo pones en producción? ¿Con qué frecuencia vas a poder actualizar el modelo? Estas son todas las cosas en que pensar cuando construyes ese conjunto de pruebas.

Entonces, si comienzas con un conjunto de validación de muestras aleatorias de todo tu set y no obtienes una línea, te das cuenta de que deberías haber elegido los últimos dos meses. Luego escoges los últimos dos meses y todavía los puntos están en todas partes y te das cuenta de que deberías haberlo elegido para que también sea desde el primero del mes hasta el quince del mes, y sigues cambiando el conjunto de validación hasta que encuentres un conjunto que es indicativo de los resultados de tu conjunto de prueba. Lo que se desea es tener una idea de qué pasa si mi conjunto de validación no se generaliza temporalmente, y si no se generaliza estadísticamente.

Ejemplos de sets de validación que se pueden usar (si deseamos predecir del 15 de agosto al 30 de agosto):

  • Muestra aleatoria (4 años)
  • Último mes de datos (15 de julio al 15 de agosto)
  • Últimas 2 semanas (1 al 15 de agosto)
  • Rango el mismo día un mes antes (15–30 de julio)

En cada uno de los cinco modelos, calculo la puntuación de validación. Luego vuelvo a entrenar el modelo en todo el conjunto (entrenamiento y validación) y calculo lo mismo en el conjunto de prueba. Entonces, cada uno de estos puntos ahora me dice qué tan bien fue en el conjunto de validación y qué tan bien fue en el conjunto de prueba. Si el conjunto de validación es útil, diríamos que cada vez que el conjunto de puntuación de validación mejore, el puntaje de prueba también debería mejorar.

Reconocer que el set de prueba refleja el mundo real es el paso más importante de un proyecto de Machine Learning. ¿Por qué es el paso más importante? Porque si arruinas todo lo demás, sabrás que fue lo que lo causo. Si tienes un buen conjunto de pruebas, entonces sabrás que todo salio mal porque cambiaste algo, lo probaste y no funcionó. Está bien, no vas a destruir la empresa. Si arruinaste la creación del conjunto de prueba, sería horrible. Porque entonces no sabes si has cometido un error. Intentas construir un modelo, lo pruebas en el conjunto de pruebas y se ve bien. Pero el conjunto de pruebas no era indicativo del entorno del mundo real. Así que no sabes realmente si vas a destruir la compañía.

El conjunto de pruebas, es algo de lo que todo el mundo habla un poco en las clases de aprendizaje automático, pero a menudo se detiene en el punto en el que aprendiste que hay una cosa en sklearn (librería de machine learning) llamada train_test_split y devuelve estas cosas y listo, o la función de validación cruzada. El hecho de que estas cosas siempre te den muestras aleatorias te dice que, la mayoría de las veces no deberías usarlas. El hecho de que un bosque aleatorio te dé un OOB gratis, es útil pero solo te dice que esto se generaliza en un sentido estadístico, no en un sentido práctico.

Cross validation (validación cruzada)

La validación cruzada dice que no solo extraigamos un conjunto de validación, sino que extraigamos cinco, por ejemplo. Así que supongamos que primero vamos a barajar aleatoriamente los datos. Esto es crítico.

  • Mezclar aleatoriamente los datos.
  • Dividirlo en cinco grupos
  • Para el modelo №1, llamaremos al primer conjunto para la validación y los cuatro últimos al para el entrenamiento.
  • Entrenaremos y verificaremos la validación y obtendremos RMSE, R², etc.
  • Lo repetiremos cinco veces, y tomamos el promedio de RMSE, R², etc., y eso es una precisión promedio de validación cruzada.

¿Cuál es el beneficio de usar la validación cruzada? Puedes utilizar todos los datos. No tienes que poner nada a un lado. Y también obtienes un pequeño beneficio, ya que ahora tienes cinco modelos que puedes armar juntos, cada uno utiliza el 80% de los datos. Así que a veces ese conjunto puede ser útil.

¿Cuáles podrían ser algunas razones por las que no debes utilizar la validación cruzada? Para grandes conjuntos de datos, tomará mucho tiempo. Tenemos que ajustar cinco modelos en lugar de uno, por lo que el tiempo es un inconveniente clave. Si estamos haciendo un aprendizaje profundo y demora un día en ejecutarse, de repente demoran cinco días o necesitamos 5 GPU.

¿Qué pasa con mis problemas anteriores sobre conjuntos de validación? Nuestras preocupaciones anteriores acerca de por qué los conjuntos aleatorios de validación son un problema son totalmente relevantes aquí. Estos conjuntos de validación son aleatorios, por lo que si un conjunto de validación aleatorio no es adecuado para tu problema, probablemente porque tu problema es temporal, ninguno de estos cinco conjuntos de validación es bueno. Todos son aleatorios. Entonces, si tienes datos temporales como lo hicimos antes, no hay manera de hacer validación cruzada o no hay una buena manera de hacerlo. Deseas que tu conjunto de validación sea lo más cercano posible al conjunto de prueba, y no puedes hacer eso mediante el muestreo aleatorio de diferentes cosas. Es posible que no necesites realizar una validación cruzada os de validación al azar no son adecuados para nuestro problema.

Conclusión

Espero que esta guía te haya ayudado a entender la importancia de crear un buen conjunto de validación y de pruebas. Continuaremos con la parte práctica de esta lección en la siguiente guía.

--

--